作业求助:MIPS汇编理解及CRC伪代码转MIPS翻译指导
Got it, let's break this down step by step. You're looking to convert that CRC32 lookup table generation pseudocode to MIPS assembly, and you mentioned using your name "Jane Doe" as an ASCII array—though for the CRC table itself, we don't actually need that array unless you're later using the table to compute CRC for that string. Let's focus first on building the lookup table, then we can touch on using it with your name if needed.
First, let's restate the core pseudocode clearly (filling in the missing else clause):
for (i = 0; i < 256; i++) {
temp = i;
for (j = 0; j < 8; j++) {
if (temp & 1) {
temp = (temp >> 1) ^ 0xEDB88320;
} else {
temp = temp >> 1;
}
}
T[i] = temp;
}
This generates the standard reverse CRC32 lookup table:
- We loop through every possible 8-bit value (0 to 255)
- For each value, we shift right 8 times, checking the least significant bit (LSB) each iteration
- If the LSB is 1, we XOR with the CRC polynomial after shifting; if 0, we just shift
- The final processed value becomes the table entry for that byte
Here's a complete, commented MIPS assembly version that matches the pseudocode, plus your name string for reference:
.data # Define the CRC32 reverse polynomial CRC_POLY: .word 0xEDB88320 # Reserve 256 * 4 bytes = 1024 bytes for the lookup table CRC_TABLE: .space 1024 # Your name stored as an ASCII byte array (null-terminated) NAME: .asciiz "Jane Doe" .text .globl main main: # -------------------------- # Outer Loop: i from 0 to 255 # -------------------------- li $t0, 0 # $t0 = i (loop counter) outer_loop: bge $t0, 256, end_outer # Exit loop if i >= 256 move $t1, $t0 # Initialize temp = i li $t2, 0 # $t2 = j (inner loop counter) # -------------------------- # Inner Loop: j from 0 to 7 # -------------------------- inner_loop: bge $t2, 8, end_inner # Exit inner loop if j >= 8 # Check if temp's LSB is 1 (temp & 1) andi $t3, $t1, 1 # Isolate LSB into $t3 beq $t3, 0, shift_only # Skip XOR if LSB is 0 # Case 1: LSB is 1 → temp = (temp >> 1) ^ POLY srl $t1, $t1, 1 # Logical right shift (unsigned, no sign extension) lw $t4, CRC_POLY # Load polynomial into $t4 xor $t1, $t1, $t4 # Apply XOR with polynomial j inner_inc # Jump to increment j shift_only: # Case 2: LSB is 0 → temp = temp >> 1 srl $t1, $t1, 1 inner_inc: addi $t2, $t2, 1 # j++ j inner_loop end_inner: # Store temp into CRC_TABLE[i] (each entry is 4 bytes, so offset = i*4) sll $t3, $t0, 2 # Multiply i by 4 (shift left 2 bits = same as *4) sw $t1, CRC_TABLE($t3) # Save temp to the table addi $t0, $t0, 1 # i++ j outer_loop end_outer: # Optional: Add code here to compute CRC32 of "Jane Doe" using the table # ... # Exit the program li $v0, 10 syscall
- Register Usage: We use temporary registers (
$t0-$t4) since we don't need to preserve these values across function calls (main is our entry point). - Bitwise Operations:
andiisolates the LSB (since we only care if it's 1 or 0)srl(logical right shift) is used instead of arithmetic shift (sra) because we're dealing with unsigned byte values—we don't want sign extension messing with our resultsxorhandles the polynomial XOR when needed
- Memory Access: The CRC table is stored in a 1024-byte block. To get the correct offset for each entry, we multiply the index
iby 4 usingsll $t3, $t0, 2(shifting left 2 bits is a fast way to multiply by 4 in assembly). - Loop Control:
bge(branch if greater or equal) checks when our loop counters hit their upper limits, andjjumps back to the loop start to continue iterating.
If you want to extend this code to calculate the CRC32 of your name, you'd:
- Initialize a CRC register to
0xFFFFFFFF - Iterate over each byte in the
NAMEarray - Update the CRC with:
CRC = CRC_TABLE[(CRC ^ byte) & 0xFF] ^ (CRC >> 8) - Finally, XOR the result with
0xFFFFFFFFto get the final CRC value.
Let me know if you want help writing that part!
内容的提问来源于stack exchange,提问作者sbowde4

