如何在MIPS中传递10个参数?

问题描述 投票:0回答:1
.data

.text
main:  
        # 5 parameters  
        li $s0, 2  
        li $s1, 3  
        li $s2, 5  
        li $s3, 10  
        li $s4, 20 

        addi $sp, $sp, -20 # 5 Words are 5 * 4 bytes  
        sw $s0, 0($sp)  
        sw $s1, 4($sp)  
        sw $s2, 8($sp)  
        sw $s3, 16($sp)  
        sw $s4, 20($sp)  

        jal addFiveNumbers  

        # free stack  
        addi $sp, $sp, 20  

        # print the result in $v0  
        move $a0, $v0
        li $v0, 1
        syscall

    # terminate program
    li $v0, 10
        syscall

addFiveNumbers:  

    lw $t0, 0($sp)  
    lw $t1, 4($sp)  
    lw $t2, 8($sp)  
    lw $t3, 16($sp)  
    lw $t4, 20($sp)  

    add $v0, $t0, $t1  
    add $v0, $v0, $t2  
    add $v0, $v0, $t3  
    add $v0, $v0, $t4  
    jr $ra 

我接受了这个程序from here

假设,我想添加10个值。

由于只有8个$ s寄存器,如何传递10个参数?

assembly parameter-passing mips procedure subroutine
1个回答
1
投票

首先,你问题中的代码是在堆栈上传递args,而不是遵循通常的C调用约定,并且没有触及任何$s寄存器,所以我不明白为什么你认为这是相关的。你如何使用被调用者中的args显然受到机器中可用寄存器数量的限制,但这与你传递它们的方式是分开的。


正常的MIPS调用约定在$a0..$a3中传递args。 a代表争论。 $s寄存器是调用保留的,通常不用于arg传递。

与所有正常的ISA一样,MIPS上的标准C调用约定会在堆栈中传递args,这些args不适合寄存器。 (或者因为它是一个值大的结构,或者因为已经存在4个寄存器args。)

查看https://godbolt.org/上用于MIPS GCC的C编译器输出,以获取传递或接收10个参数的函数,以查看它在哪里查找它们。 (也许将每个arg存储到volatile int sink,因此您可以通过优化进行编译,但仍然可以看到它做了些什么。)


如果您在asm中写信给调用者和被调用者,您显然可以编写您想要的任何自定义调用约定。如果我想传递超过4个寄存器args,我认为自然的选择可能是在填充$t0..$t9后使用$v0..$v1和/或$a0..$a3

但是可以肯定的是,如果我想传递调用者不会破坏的一些只读参数,那么$s寄存器将适用于那些。我不知道任何具有任何调用保留的arg传递寄存器的ISA的C调用约定,但它在asm中非常有意义。

此时,您只使用一个调用者,但可能来自同一函数中的多个调用点,并且可能根据调用者的方便选择寄存器。所以它几乎不是一个独立的功能。但那没关系。

© www.soinside.com 2019 - 2024. All rights reserved.