【问题标题】:MIPS: Translating C Code to assemblyMIPS:将 C 代码翻译成汇编
【发布时间】:2014-04-19 04:17:28
【问题描述】:

我正在尝试将下面的 C 代码翻译成 MIPS 汇编语言,但我理解其中的大部分内容,但我不知道汇编中第一行的等价物是什么...

int ary[3] = {2,3,4};

如果有人可以查看我的 C 到汇编“翻译”并验证我是否走在正确的轨道上,我将不胜感激。

C 代码

int ary[3] = {2,3,4};
int i=0;

//loop to double array values
for(i=0; i < 3; i++){
    ary[i] = ary[i]*2;
}

我尝试了什么:

add $t0, $s0, $zero #get base address of the array 'ary' (dont understand this part)
addi $t1, baseAddress, 8 #cut off point to stop the loop; array[2]
addi $t1, $zero, $zero #initialize i=0


Start:
lw $t2, base(offset)
sll $t2, $t0, 1 #mutiply $t2 by 2  
sw $t2, base(offset)
addi $t0, $t0, 4 # Increment the address to the next element
bne $t0, $t1, Start # $t0 will keep increasing until reaches stopping point $t1
Exit:

【问题讨论】:

    标签: assembly mips


    【解决方案1】:

    如果这是一个本地数组,则在堆栈上为其分配空间,然后从代码中对其进行初始化。 C 代码的一种可能的 asm 翻译可能如下所示:

        addi $sp, $sp, -12     # allocate space for 3 words, $sp is now the address of the array
        addi $t0, $zero, 2
        sw $t0, ($sp)          # ary[0]=2
        addi $t0, $zero, 3
        sw $t0, 4($sp)         # ary[1]=3
        addi $t0, $zero, 4
        sw $t0, 8($sp)         # ary[2]=4
    
        addi $t0, $zero, 0     # initialize i=0
    
    Start:
        sll $t1, $t0, 2        # i*4 for element size
        add $t1, $t1, $sp      # add base address of array, $t1 is now &ary[i]
        lw $t2, ($t1)          # load ary[i]
        sll $t2, $t2, 1        # mutiply by 2
        sw $t2, ($t1)          # store back to ary[i]
        addi $t0, $t0, 1       # i++
        addi $t1, $t0, -3      # check if i<3 by doing (i-3)<0
        bltz $t1, Start
        addi $sp, $sp, 12      # free the array
    

    您的 asm 代码采用了稍微不同的方法,C 版本应该是这样的:

    int* end = &ary[3];
    for(int* ptr = ary; ptr != end; ptr++)
    {
        *ptr = *ptr * 2;
    }
    

    而固定的 asm 版本是:

        addi $t1, $sp, 12      # end=&ary[3]
        addi $t0, $sp, 0       # ptr=ary
    
    Start:
        lw $t2, ($t0)          # load ary[i]
        sll $t2, $t2, 1        # mutiply by 2
        sw $t2, ($t0)          # store back to ary[i]
        addi $t0, $t0, 4       # ptr++ (note it is incremented by 4 due to element size)
        bne $t0, $t1, Start    # ptr!=end
    

    【讨论】:

    • 您好,谢谢您的回复,不胜感激。我想知道为什么没有结束语句。还有,为什么lw和sw指令中没​​有基地址?
    • 不确定你在说什么结束语,也许是jr $ra?由于您的 C 代码不是完整的函数或程序,我只是以类似的方式提供了 asm 代码。至于缺少的基地址:那是因为地址已经通过添加$sp(数组地址)计算出来,所以基数只是0。如果你愿意,你可以把它写出来。注意基数不能是其他寄存器,lw $t2, $sp($t1)是非法的。
    【解决方案2】:

    你的代码有很多错误

    addi $t1, baseAddress, 8 #cut off point to stop the loop; array[2]
    addi $t1, $zero, $zero #initialize i=0
    

    在第一行中,没有这样的指令,除非 baseAddress 是一个寄存器。第二行应该是add,而不是addi,因为$zero 不是立即数

    Start:
    lw $t2, base(offset)
    sll $t2, $t0, 1 #mutiply $t2 by 2  
    sw $t2, base(offset)
    

    以上几行也有问题。你刚刚加载了一个单词到 $t2,然后立即将另一个值存储到 $t2,所以之前的加载是没有意义的

    【讨论】:

      【解决方案3】:
        #include <iostream>
        using namespace std;
      
        //prototypes
      
        int maxIs (int *x, int n);
        int minIs ( int *x, int n);
        void avgIs (int *x, int n, int *theAvg, int *theRem);
      
        int main(void)
        {
        int n = 8;
        int x[] = {1,2,3,4,5,6,7,8};
        int theMax, theMin, theAvg, theRem;
      
        theMax = maxIs(x,n);
        theMin = minIs(x,n);
        avgIs(x,n,&theAvg, &theRem);
      
        cout << "max = " << theMax << "\n";
        cout << "min = " << theMin << "\n";
        cout << "avg = " << theAvg << " " << theRem << "/" << n << "\n";
        cout << "Bye!\n";
        }
      
        //functions
      
       int maxIs (int *x, int n )
       {
      int i;
      int theMax = 0;
      for (i=0; i<n; i++)
      {
          if (x[i]>theMax) theMax =x[i];
      }
      return (theMax);
      }
      
      int minIs (int *x, int n )
      {
      int i;
      int theMin = 0x7FFF;
      for (i=0; i<n; i++)
      {
          if (x[i]>theMin) theMin =x[i];
      }
      return (theMin);
      }
      
      void avgIs (int *x, int n, int *theAvg, int *theRem )
      {
      int i;
      int theSum = 0;
      for (i=0; i<n; i++)
      {
          theSum += x[i];
      }
      *theAvg = theSum /n;
      *theRem = theSum %n;
      }
      

      【讨论】:

      • 你把这个发错地方了吗?这与问题无关,也不回答问题。
      最近更新 更多