为什么我们使用stackpointer创建一个返回地址

时间:2018-03-25 15:15:23

标签: assembly mips

最近我匆匆忙忙度过了精彩的mips装配世界:D 我实际上写了一个查找最小函数,它实际上工作。使用QtSPIM编译所有内容,我感到非常高兴。

好吧主要是我从大学讲座得到的一些代码片段。我只是编写了函数本身。所以这是我的问题。我想我弄清楚了堆栈指针如何与地址一起工作。在这个例子中,我们使用sp -4字节的地址将其保存在$ ra寄存器中。为什么我们使用堆栈本身呢?我可以使用$ ra地址本身吗? 或者这实际上是我们应该创建的习惯,我想可能以后可能有助于保护堆栈上的返回地址,但也许您可以更详细地向我解释这一点。

一如既往,我非常感谢每一位帮助。谢谢你们:)

minimum:




    lw      $v0, 0($a0)
    add     $t0, $zero, $zero                           # i = 0


for:
    bge     $t0, $a1, endfor                            # if(i>=n) goto endfor
    sll     $t1, $t0, 2                                 # $t1 = 4*i
    add     $t1, $a0, $t1                               # $t1 = a + 4*i = &a[i]
    lw      $t1, 0($t1)                                 # $t1 = a[i]

    slt     $t2, $t1, $v0                               #set t2 = 1 if (t1<v0)
    beq     $t2, 1, setnewmin                           # if t2 == 1 go to label setnewmin
    addi    $t0, $t0, 1
    j       for

setnewmin:
    move    $v0, $t1                                    #store new new minimum in v0 
    addi    $t0, $t0, 1                                 # i++
    j       for

endfor: 



    jr      $ra                                         #go back to main


# Some Parameters
#


    .data
array: .word 5, 17, 3, 22, 120, -412, 14, 254, 1000, 2, 7, 1001
n:     .word 12


#
# main
#a

    .text
    .globl main

main:
    addi    $sp, $sp, -4        # save return adress
    sw  $ra, 0($sp)

    la  $a0, array      # array adress
    lw  $a1, n        

    jal minimum

    move    $s1, $v0

    move    $a0, $s1

    li  $v0, 1
    syscall


    lw  $ra, 0($sp)
    addi    $sp, $sp, 4
    jr  $ra

#
# end main
#

1 个答案:

答案 0 :(得分:3)

The $ra register holds the return address of the current function. The return address specifies the address of the instruction at which execution should continue when the current function returns.

If the current function itself (main) needs to call another function (minimum), the jal instruction will overwrite the contents of $ra. If that happened, main wouldn't be able to return to the correct address. Therefore, it's necessary for main to save a temporary copy of $ra so that it can be restored when required. The following instructions save a copy of the return address on the stack:

addi    $sp, $sp, -4        # save return adress
sw  $ra, 0($sp)

The following instructions restore that copy just before returning from main:

lw  $ra, 0($sp)
addi    $sp, $sp, 4

The jr $ra instruction returns to the function that called main (also used at the end of minimum for the same purpose).

Note that minimum doesn't need to save a copy of $ra because it doesn't contain any instruction that destroys its value.