我是 MIPS 语言的新手,我不明白 MIPS 汇编语言中的函数(过程)是如何工作的。这是但我会指定我的问题:
有什么作用:
jal
jr
$ra
在 mips 语言中的意思和重要的事情
- 当我们想创建一个函数或(过程)时,我们如何使用它们?
首先,您可能想查看此快速 MIPS 参考。它真的帮助了我。
jal
其次,解释jr
和$ra
。什么jal <label>
是跳转到label
标签并将程序计数器(将其视为当前指令的地址)存储在$ra
寄存器中。现在,当您想从label
最初的位置返回时,只需使用jr $ra
.
这是一个例子:
.text
main:
li $t0, 1
jal procedure # call procedure
li $v0, 10
syscall
procedure:
li $t0, 3
jr $ra # return
在 SPIM 仿真器中运行此程序时,您会注意到留下的$t0
值为 3,即在所谓的procedure中加载的值。
希望这可以帮助。
1.前两个是指令,第三个是特殊寄存器
我们经常使用这样的指令......
这意味着返回(跳转)到 $ra 中保存的地址。
2.
这是 C 中的示例函数(过程)
int main(){
x=addthem(a,b);
}
int addthem(int a, int b){
return a+b;
}
MIPS 中的函数
.text
main: #assume value a is already in $t0, b in $t1
add $a0,$0,$t0 # it's the same function as move the value
add $a1,$0,$t1
jal addthem # call procedure
add $t3,$0,$v0 # move the return value from $v0 to where we want
syscall
addthem:
addi $sp,$sp,-4 # Moving Stack pointer
sw $t0, 0($sp) # Store previous value
add $t0,$a0,$a1 # Procedure Body
add $v0,$0,$t0 # Result
lw $t0, 0($sp) # Load previous value
addi $sp,$sp,4 # Moving Stack pointer
jr $ra # return (Copy $ra to PC)
您将需要阅读System V 应用程序二进制接口,MIPS RISC 处理器补充。这描述了用于调用函数的约定,特别是如何管理堆栈和交换参数(MIPS 中没有硬件堆栈,一切都是软件约定的问题,而 ABI 定义了这些约定)。
上面的文档假设了 MIPS 指令的一些基本知识,因此您还需要MIPS32 Architecture for Programmers,特别是第二卷(指令集),它描述了每条指令的详细效果。但是,帮自己一个忙,先下载并阅读第一卷(介绍)。
该jal
指令是“跳转和链接”操作码。它跳转到目标地址(即被调用过程的第一个操作码的地址),同时将当前指令指针保存到链接寄存器中,即寄存器 31(准确地说,它将值x +8保存在寄存器 31 中) ,其中x是jal
操作码本身的地址)。
主功能:
.data
x: .word 3 # initializing x to be 3
y: .word 5 # initializing y to be 5
answer: .word 0 # intialzing answer to be 0
prompt: .asciiz "Add X to Y: " # console prompt for final answer
.text
.globl main
.ent main
main:
lw $a0, x # pass arguments to function $a0 - x, $a1 - y
lw $a1, y
jal adds # adds function is called
sw $v0, answer # answer from the returned value
la $a0, prompt # displaying prompt on the console
li $v0, 4
syscall
lw $a0, answer # displaying final answer on the console
li $v0, 1
syscall
li $v0, 10 # end program
syscall
.end main
增加功能:
.globl adds
.ent adds
adds: # adds function
li $v0, 0
add $v0, $a0, $a1 # adding arguments to the callee
jr $ra # return
.end adds