我试图将C代码转换为MIPS程序集。有以下两个C代码片段。问题是我的解决方案与标准解决方案不同。另外,我不明白标准解决方案。我希望,有人可以向我解释以下两个mips汇编代码片段。
首先,该任务的一些其他信息。只允许以下MIPS指令: lw,add,beq,bne和j 。
登记册:
$ s3 包含 i
$ s4 包含 j
$ s5 包含 k
A 是 32位整数的数组, A 的初始地址位于 $ s6
$ t0 和 $ t1 可用于存储临时变量
第一个是简单的do-while循环:
do {
i = i + j;
} while(A[i] == k);
MIPS汇编
loop: add $s3, $s3, $s4 // this is i = i+j
add $t1, $s3, $s3 // from now on
add $t1, $t1, $t1 // I cant follow anymore
add $t1, $t1, $s6 // What happens in these three lines?
lw $t0, 0($t1) // 0($t1) is new for me. What does this zero do?
beq $t0, $s5, loop
现在是第二个C代码:
if ( i == j )
i = i + A[k];
else if( i == k )
i = i + A[j];
else
i = i + k;
这是MIPS汇编代码:
bne $s3, $s4, Else1 // this line is if(i==j)
add $t1, $s5, $s5 // from here on
add $t1, $t1, $t1 // till
add $t1, $t1, $s6 //
lw $t0, 0($t1) //
add $s3, $s3, $t0 // here I don't understand
j done
ELSE1: bne $s3, $s5, Else2 // this line is if(i==k)
add $t1, $s4, $s4 // The same game as above
add $t1, $t1, $t1
add $t1, $t1, $s6
lw $t0, 0($t1)
add $s3, $s3, $t0 // till here
j done
ELSE2: add $s3, $s4, $s5
有人能解释一下我到底发生了什么吗?这将非常有帮助
答案 0 :(得分:2)
lw
正在加载。这里的模式是间接寻址,最常见的是:
lw $t2, ($t0)
但是你也可以包含一个字节偏移量
lw $t2, 4($t0) # load word at RAM address ($t0 + 4) into register $t2
编译器只是将0占位符放在非偏移版本中。
因此,要加载A[i]
,您需要做两件事。取A[]
的基址,然后将i
的{{1}}加sizeof(A[0])
。我猜测A
中的值是32位。
add $t1, $s3, $s3
$t1 = j + j
或2 * j
add $t1, $t1, $t1
$t1 = $t1 + $t1
或j +j +j +j
或4 * j
那为什么这样做呢?好吧,就时钟周期而言,直接乘法是很慢的。下一个选择是移位操作,但在这种情况下,编译器设计者决定两个加法击败移位。
add $t1, $t1, $s6
我猜测$s6
是A[]
的基地址。所以最终'$ t1 = A [] + 4 * j`
答案 1 :(得分:2)
O.k。最有趣且不易理解的代码如下:添加$ t1,
add $t1, $s5, $s5
add $t1, $t1, $t1
add $t1, $t1, $s6
此代码将$ s5乘以4,并将其存储在$ t1中,然后添加到$ t1 $ s6。这相当于:
$t1 = A[k]
了解了这一点后,代码看起来更加清晰。
关于lw $t0, 0($t1)
:
您可以在地址中使用偏移点。偏移量为0。
答案 2 :(得分:0)
我有一个答案。循环,一个元素数组有基本地址:0x0FE3B128。 非常感谢.. 这是我的作业,我不确定它是否正确。
for(i=1; i!=20;i+=3){
a[i]= a[5]+1;
}
lui $s0, 0x0FE3
ori $s0, $0, B128
lw $t1, 20($s0)
addi $s1, $0, 1
addi $s2, $0, 20
LOOP beq $s1, $s2, DONE
add $t1, $t1, $s1
sll $t1, $t1, 2
sw $t2, 0($t1)
addi $s1, $0, 3
j LOOP
DONE