c - 如何在程序集循环后转移控制权?

标签 c assembly mips

我想将下面的 C 代码翻译成汇编语言。

但是,我没有看到我需要在这个例子中使用堆栈。

此外,我想知道“beq”是否像“jal”那样将后面指令的地址保存在$ra中,因为当循环结束时,我想回到原来的函数foo , 并继续说明(这里只是返回。)

     int foo(int* a, int N) {
         if(N > 0) 
             {
             for(int i = 0; i != N; i = i + 1) 
                { 
                a[i] = bar(i << 4, a[i]);
                } 
             }
     return N & 7; 
     }
#assume *a in $a0, N $N in $a1
foo:
slt $t0, $zero, $a1 #put 1 in $t0 if 0 < N
li $t1,0 # use $t1 as loop counter
beq $t0, 1, loop  # enter loop if 0 < N
and $v0, $a1, 7 # do bitwise and on N and 7 and save in $v0 as return value

loop:
beq $t1, $a1, exit # exit loop when i = N
sll $t3, $t1, 2 # obtain 4 * i
add $t3, $a1, $t3 # obtain address of a[i] which is address of a plus 4i
lw $t3, o($t3)  # load a[i] into $t3
sll $t4, $t1, 4 #perform  i<< 4 and save in $t4
# the 2 previous load arguments for bar
jal bar # assume bar saves return value in $v2
sw $t3, 0($v1)
j loop

exit:
and $v0, $a1, 7

最佳答案

beq用于条件分支,而不是调用——它改变了 PC (有条件地)但不是 $ra .我们用它来将结构化语句(例如 if、for)翻译成汇编语言的 if-goto 风格。

However, I do not see that I need to use the stack in this example.

必须为此代码使用堆栈,因为对 bar 的调用(如 jal bar )将消灭 foo s $ra ,同时 bar将能够回到foo , foo将无法返回给它的调用者。由于这需要堆栈,因此您需要 prologue and epilogue分配和释放一些堆栈空间。

您的代码没有正确地将参数传递给 bar , i << 4 ,例如,应传入 $a0 , 而 a[i ] 应该传入 $a1 .

您在 foo 中没有返回说明— 它缺少 jr $ra .

关于c - 如何在程序集循环后转移控制权?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58290144/

相关文章:

c++ - 如何在 C++ 中为卡片制作 ASCII 边框并制作 10 不移动它们

c - 分配内存后不执行代码

c - 将数据包从一台linux服务器发送到另一台服务器(LINUX)

c++ - 这个环路优化配置文件意味着什么?

python - 如何在 MIPS 中正确使用 mod 运算符?

c - 将 x86 程序下面的端口移植到 mips32

assembly - 在MIPS中,何时使用有符号扩展,何时使用零扩展?

c++ - C 中的可变参数函数

c - 在执行procprob时,b可以是任何数据类型吗?

c - 独立于汇编操作系统的原子比较和交换