4

我在互联网上找到了这个示例 spim 代码

.data

COUNT:  .word   10
TEXT:   .asciiz "The number is "
EOL:    .asciiz "\n"

        .text
    .globl  main
main:

    addiu   $sp, $sp, -32   # Adjust stack
    sw  $ra, 24($sp)
    sw  $fp, 16($sp)    # save old frame pointer
    addiu   $fp, $sp, 28    # load new frame pointer    

    la  $t0, COUNT
    lw  $t1, 0($t0)
    li  $t0, 0      # init index to 0

loop:
    sw  $t0, 12($sp)    # save caller saved registers
    sw  $t1, 8($sp) # 

    move    $a0, $t0    # setup parameter for fn call

    jal print_num   # call subroutine

    lw  $t1, 8($sp) # restore caller saved values
    lw  $t0, 12($sp)    #

    addiu   $t0, $t0, 1 # increment index;
    blt $t0, $t1, loop  #

    lw  $fp, 16($sp)    # restore frame pointer
    lw  $ra, 24($sp)    # restore return address
    addiu   $sp, $sp, 32    # restore stack pointer

    jr  $ra

更新
我无法得到的是:如果函数 main 需要将四个寄存器保存到堆栈上($ra $fp $t0 $t1),它怎么会为 8 个寄存器分配空间(32 个字节而不是 16 个字节)?

谢谢你的时间

4

2 回答 2

3

帧指针应指向堆栈的开始(底部)。由于堆栈元素是 4 个字节,因此底部元素的开头比堆栈的大小小 4。

于 2011-04-12T20:53:19.110 回答
2

这是由于使用了约定,特别是调用约定。在 MIPS 中,被调用者在需要使用时将一些寄存器保存在堆栈中,哪些寄存器需要保存,并且在某些约定中指定它们在堆栈中的保存位置。关于 SPIM 的 IDK,但 SGI IRIX 有两个不同的约定,称为o32n32(对于“旧”和“新”),您可能会幸运地在谷歌上搜索它们。

于 2011-04-12T20:32:13.247 回答