【问题标题】:Convert C++ function to MIPS将 C++ 函数转换为 MIPS
【发布时间】:2017-09-30 06:16:15
【问题描述】:

如果给你:

calc (int b) {
return b - 2;
}

它将如何转换为 MIPS?

我考虑过以下几点:

addi $v0, $a0, -2
jr $ra
***********************
jr $ra
addi $v0, $a0, -2
***********************
addi $v0, $a0, 2
jr $ra 
***********************
lw $v0, 0($a0)
addi $v0, $v0, -2
jr $ra

我只是在 MIPS 中学习函数,希望得到建议。在这种情况下使用“lw”指令有什么意义吗?

【问题讨论】:

标签: c++ function mips code-conversion


【解决方案1】:

你的结果是正确的,至少第一个是正确的。根据here你的第一个回答:

addi $v0, $a0, -2
jr $ra

是正确的。它使用最少的指令,这将提高执行速度,更不用说使用立即指令减少了从内存中提取的次数。查看链接中的表格会告诉你:

  • $v0 是函数的第一个返回值应该去哪里的寄存器。
  • $a0 是调用函数时要使用的第一个输入参数的寄存器。
  • $ra 是保存上一条跳转指令的返回地址的寄存器。

所以有人想调用你的汇编函数,它看起来像:

int x = calc(5); // This line is the `C` equivalent and not part of assembly code.

组装将是:

li $a0, 5  # Load immediate the value 5 into register $a0.
jal __calc # Jump to the sub routine '__calc' and store return address in $ra.
           # Result will now be in $v0.
...

__calc:
  addi $v0, $a0, -2
  jr $ra 

如果可以,请尽量远离lw 之类的指令。与将值保存在 CPU 的寄存器中相比,它们会进入 RAM 并获取内存非常慢。

【讨论】:

  • 我注意到我尝试在 MIPS 中编写的一些函数,包括这个函数,当我使用像“lw”或“sw”这样的指令时,我收到一个错误。通常错误消息显示为:“获取地址未在字边界上对齐”。这是否意味着您提到从 RAM 中获取值?请记住,我正在使用: ori $a0, $0, 5 将 $a0 初始化为 5 以进行测试。如果我不限制 $a0 的值,您认为我可以使用“lw”指令避免错误吗?这只是出于好奇,我已经对您的回答感到满意。
  • 如果你想要一个寄存器中的值,例如5 in register $a0,你可以使用'load immediate'指令lili $a0, 5 与 $a0 = 5 相同。使用 lwsw 等指令时,需要寄存器和 RAM 地址。如果您使用lw $a0, 5,这与将地址5 的RAM 内容加载到$a0 相同,那么RAM 中的内容可以是任何内容。 RAM 地址5 可能会被限制供内核使用,用户空间内存在 RAM 地址中开始较高,这将导致获取错误。
  • “获取地址未在 WORD 边界上对齐”的问题是另一个问题。 WORD 是 CPU 的寄存器大小,在您的情况下假设为 32 位。这意味着在读取和写入 RAM 时,您提供的地址必须是 32 位对齐的。在不知道您设置的确切细节的情况下,这是我能给出的最佳答案。通常任何 RAM 地址都是有效的。
猜你喜欢
  • 1970-01-01
  • 2012-06-16
  • 2011-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-28
  • 2020-07-28
  • 2021-09-13
相关资源
最近更新 更多