18

我是 MIPS 语言的新手,我不明白 MIPS 汇编语言中的函数(过程)是如何工作的。这是但我会指定我的问题:

  1. 有什么作用:

    • jal
    • jr
    • $ra

    在 mips 语言中的意思和重要的事情

  2. 当我们想创建一个函数或(过程)时,我们如何使用它们?
4

4 回答 4

20

首先,您可能想查看快速 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中加载的值。

希望这可以帮助。

于 2010-11-18T11:27:20.033 回答
10

1.前两个是指令,第三个是特殊寄存器

  • jal=jump and link (后面指令的地址放在$ra中,然后跳转到目标地址)
  • jr=跳转指定寄存器
  • $ra=返回地址

我们经常使用这样的指令......

  • jr $ra (复制 $ra 到程序计数器)

这意味着返回(跳转)到 $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)
于 2011-04-06T08:36:30.940 回答
2

您将需要阅读System V 应用程序二进制接口,MIPS RISC 处理器补充。这描述了用于调用函数的约定,特别是如何管理堆栈和交换参数(MIPS 中没有硬件堆栈,一切都是软件约定的问题,而 ABI 定义了这些约定)。

上面的文档假设了 MIPS 指令的一些基本知识,因此您还需要MIPS32 Architecture for Programmers,特别是第二卷(指令集),它描述了每条指令的详细效果。但是,帮自己一个忙,先下载并阅读第一卷(介绍)。

jal指令是“跳转链接”操作码。它跳转到目标地址(即被调用过程的第一个操作码的地址),同时将当前指令指针保存到链接寄存器中,即寄存器 31(准确地说,它将值x +8保存在寄存器 31 中) ,其中xjal操作码本身的地址)。

于 2010-11-18T13:20:28.143 回答
0
  • jal:又名跳转和链接到任何函数名称会将您重定向到所需的函数。
  • jr $ra:它从被调用的函数返回值。

主功能:

   .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
于 2021-03-27T11:40:27.563 回答