样本垃圾代码

时间:2011-04-12 16:52:06

标签: assembly mips 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

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

感谢您的时间

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

这是由于使用了约定,特别是调用约定。在MIPS中,如果需要使用它们,calleé会在堆栈上保存一些寄存器,这些寄存器需要保存,并且在某些约定中指定它们保存在堆栈中的位置。关于SPIM的IDK,但是SGI IRIX有两个不同的约定,分别是o32n32(对于“旧”和“新”),你可能会有一些运气用谷歌搜索它们。