我试图将C代码转换为MIPS程序集 . 有以下两个C代码片段 . 问题是我的解决方案与标准解决方案不同 . 另外,我不明白标准解决方案 . 我希望,有人可以向我解释以下两个mips汇编代码片段 .
首先是该任务的一些附加信息 . 仅允许以下MIPS指令: lw, add, beq, bne and j .
登记册:
$s3 包含 i
$s4 包含 j
$s5 包含 k
A 是 32-Bit-Integer 的数组, 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
谁能解释一下我到底发生了什么?这将非常有帮助
3 回答
我有一个答案 . 循环,一个元素数组有基本地址:0x0FE3B128 . 非常感谢..这是我的作业,我不确定它是否正确 .
lw
正在加载 . 这里的模式是间接寻址,最常见的是:但是你也可以包含一个字节偏移,
编译器只是将0占位符放在非偏移版本中 .
所以,要加载
A[i]
,你需要做两件事 . 取A[]
的基址,然后添加_51277的i
倍 . 我猜A
中的值是32位 .$t1 = j + j
或2 * j
$t1 = $t1 + $t1
或j +j +j +j
或4 * j
那么为什么这样做呢?那么,就时钟周期而言,进行直线乘法是很慢的 . 下一个选择是移位操作,但在这种情况下,编译器设计者决定两个增加击败移位 .
我猜
$s6
是A[]
的基地址 . 所以最终'$ t1 = A [] 4 * j`好 . 最有趣且不易理解的代码如下:添加$ t1,
此代码将$ s5乘以4,并将其存储在$ t1中,然后添加到$ t1 $ s6 . 这相当于:
在你理解了这一点后,代码看起来更加清晰 .
关于
lw $t0, 0($t1)
:你可以在地址中使用一个偏移点 . 这里的偏移量为0 .