代码到MIPS汇编
我试图将C代码转换为MIPS汇编。 有以下两个C代码片段。 问题是我的解决方案与标准解决方案不同。 另外,我不了解标准解决方案。 我希望有人能向我解释下面两个mips汇编代码片断。
首先为该任务提供一些附加信息。 只允许使用以下MIPS指令: lw,add,beq,bne和j 。
寄存器:
$ s3包含我
$ 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
任何人都可以解释我究竟发生了什么? 这将是非常有益的
好吧,最有趣和不可理解的代码如下:add $ 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。
lw
是负载。 这里的模式是间接寻址,最常见的是:
lw $t2, ($t0)
但是你也可以包含一个字节偏移量,
lw $t2, 4($t0) # load word at RAM address ($t0 + 4) into register $t2
编译器只是将0占位符置于非偏移版本中。
所以,加载A[i]
你需要做两件事。 取A[]
的基地址,然后加i
倍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`
我有一个答案。循环,一个是元素数组有基本地址: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
链接地址: http://www.djcxy.com/p/60379.html