我们在C语言中获得了以下代码,并要求将其转换为MIPS。我们不需要处理lo和hi;它们为我们存储在$ a0和$ a1中:
void decode_request(unsigned long int request, int* array) {
// lo and hi are already stored for us in $a0 and $a1
unsigned lo = (unsigned)((request << 32) >> 32);
unsigned hi = (unsigned)(request >> 32);
for (int i = 0; i < 6; ++i) {
array[i] = lo & 0x0000001f;
lo = lo >> 5;
}
unsigned upper_three_bits = (hi << 2) & 0x0000001f;
array[6] = upper_three_bits | lo;
hi = hi >> 3;
for (int i = 7; i < 11; ++i) {
array[i] = hi & 0x0000001f;
hi = hi >> 5;
}
这是我的尝试:
.globl decode_request
decode_request:
li $t0, 0 # int i = 0;
first_loop:
bge $t0, 6, after_first_loop # branch if greater than or equal to 6
mul $t0, $t0, 4 # account for ints; storage size = word
and $t1, $a0, 0x0000001f # lo & 0x0000001f;
sw $t1, 4($t1) # array[i] = lo & 0x0000001f;
srl $t2, $a0, 5 # lo >> 5;
sw $t2, 0($t2) # lo = lo >> 5;
add $t0, $t0, 1 # ++i
j first_loop # jump back to top of loop
after_first_loop:
sll $t3, $a1, 2 # (hi << 2)
and $t3, $t3, 0x0000001f # & 0x0000001f
mul $t3, $t3, 4 # account for ints; storage size = word
sw $t3, 0($t3) # store back into memory
or $t4, $t3, $a0 # array[6] = upper_three_bits | lo;
sw $t4, 24($t4) # store back into memory; use 24 since int = 4 bytes and we have offset of 6
srl $a1, $a1, 3 # hi >> 3;
sw $a1, 0($a1) # hi = hi >> 3;
second_loop:
li $t5, 7 # int i = 7;
bge $t0, 11, end # branch if greater than or equal to 11
mul $t5, $t5, 4 # account for ints; storage size = word
and $t6, $a1, 0x0000001f # hi & 0x0000001f
sw $t6, 4($t6) # array[i] = hi & 0x0000001f;
srl $t7, $a0, 5 # hi >> 5;
sw $t7, 0($t7) # lo = lo >> 5;
add $t5, $t5, 1 # ++i
j second_loop # jump back to top of second_loop
end:
jr $ra
关于我可能会出错的地方或其他方法的任何想法吗?
谢谢!
答案 0 :(得分:1)
我已更正了您代码的第一部分。并且80%的指令在语法上不正确。这是汇编应该告诉您的。还有很多很多逻辑错误。 主要之一是您需要管理数组元素的地址。
decode_request:
li $t0, 0 # int i = 0;
### we assume $t4=@array and $t5=array[i]
add $t5, $t4, zero ## t5=&array[0]
first_loop:
### bge is bge reg1, reg2, offset. Cant use an immediate
### slti does a compare and then a branch is possible
sltiu $t1, $t0, 6 # i<6 ?
beq $t0, zero, after_first_loop # false ? goto end first loop
### i=i*4??? what is it supposed to do?
####mul $t0, $t0, 4 # account for ints; storage size = word
### and $t1, $a0, 0x0000001f ... should be andi
andi $t1, $a0, 0x0000001f # lo & 0x0000001f;
### not sw $t1, 4($t1) which does not make sense
### array[i] is $t5 and data to store is $t1
sw $t1, 0($t5) # array[i] = lo & 0x0000001f;
srl $t2, $a0, 5 # lo >> 5;
### why do you want to store lo? Just keep it is register $t2.
### And your store is anyway incorrect. Should be sw $t2,0($t6)
#### where $t6 is the address of lo
## sw $t2, 0($t2) # lo = lo >> 5;
### add add $t0 ... should be addi
addi $t0, $t0, 1 # ++i
#### and you must increment array address
addi $t5, $t5, 4 # $t5++ -> $t5==array[i+1]
j first_loop # jump back to top of loop
现在尝试更正程序的其余部分。 asm中的错误应该是明确的。
答案 1 :(得分:0)
我已经使用Alain的更正来尝试进行第二次循环
loop_two:
# these loops go from 0-5 and then from 7-10
# since t5 has been incremented each time, $t5 = array[5]
# have to add 8 to get $t5 = array[7]
# do this in between_loops
slti $t7, $t6, 11 # i < 11 ?
beq $t6, zero, end # if false, done with loop, go to end
# loop body goes here
andi $t6, $a1, 0x0000001f # hi & 0x0000001f
# array[i] is $t5 and data to store is $t6
sw $t6, 0($t5) # array[i] = hi & 0x0000001f;
srl $t7, $a0, 5 # hi >> 5;
add $t6, $t6, 1 # ++i
addi $t5, $t5, 4 # increment array address, $t5++ -> $t5==array[i+1]
j loop_two
这假定下面的代码在decode_request中声明了
li $t6, 7 # t3 is our second counter (int i = 7)