首页 文章

C代码到MIPS汇编

提问于
浏览
3

我试图将C代码转换为MIPS程序集 . 有以下两个C代码片段 . 问题是我的解决方案与标准解决方案不同 . 另外,我不明白标准解决方案 . 我希望,有人可以向我解释以下两个mips汇编代码片段 .

首先是该任务的一些附加信息 . 仅允许以下MIPS指令: lw, add, beq, bne and j .
登记册:
$s3 包含 i
$s4 包含 j
$s5 包含 k
A32-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 回答

  • 2

    我有一个答案 . 循环,一个元素数组有基本地址: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
    
  • 2

    lw 正在加载 . 这里的模式是间接寻址,最常见的是:

    lw $t2, ($t0)
    

    但是你也可以包含一个字节偏移,

    lw $t2, 4($t0)   # load word at RAM address ($t0 + 4) into register $t2
    

    编译器只是将0占位符放在非偏移版本中 .

    所以,要加载 A[i] ,你需要做两件事 . 取 A[] 的基址,然后添加_51277的 i 倍 . 我猜 A 中的值是32位 .

    add $t1, $s3, $s3
    

    $t1 = j + j2 * j

    add $t1, $t1, $t1
    

    $t1 = $t1 + $t1j +j +j +j4 * j

    那么为什么这样做呢?那么,就时钟周期而言,进行直线乘法是很慢的 . 下一个选择是移位操作,但在这种情况下,编译器设计者决定两个增加击败移位 .

    add $t1, $t1, $s6
    

    我猜 $s6A[] 的基地址 . 所以最终'$ t1 = A [] 4 * j`

  • 0

    好 . 最有趣且不易理解的代码如下:添加$ 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 .

相关问题