как я могу передать 10 аргументов в MIPS? - PullRequest
0 голосов
/ 27 марта 2019
.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 

Я взял эту программу отсюда .

Предположим, я хочу добавить, скажем, 10 значений.

Поскольку существует только восемь $ s регистров, как я могу передать 10 аргументов?

1 Ответ

1 голос
/ 28 марта 2019

Прежде всего, код в вашем вопросе передает аргументы в стеке, не следуя обычному соглашению о вызовах C, и не касается ни одного из регистров $s, поэтому я не понимаю, почему вы думаете, что это актуально вообще. То, как вы используете аргументы внутри вызываемого, очевидно, ограничено количеством доступных регистров в машине, но это не зависит от того, как вы их передаете.


Обычное соглашение о вызовах MIPS передает аргументы в $a0..$a3. a означает аргумент. Регистры $s сохраняются при вызове и обычно не используются для передачи аргументов.

Стандартное соглашение о вызовах C для MIPS, как и для всех обычных ISA, передает в стек аргументы для аргументов, которые не помещаются в регистры. (Либо потому, что это большая структура по значению, либо потому что уже есть 4 регистрационных аргумента.)

Посмотрите на вывод компилятора C на https://godbolt.org/ для MIPS GCC для функции, которая передает или получает 10 аргументов, чтобы увидеть, где она их ищет. (Возможно, сохраните каждый аргумент в volatile int sink, чтобы вы могли скомпилировать с оптимизацией и при этом увидеть, что он что-то делает.)


Вы, очевидно, можете составить любое пользовательское соглашение о вызовах, которое хотите, если вы пишете вызывающему абоненту, и вызываете себя в asm . Если я хочу передать более 4 аргументов регистра, я думаю, что естественным выбором может быть использование $t0..$t9 и / или $v0..$v1 после заполнения $a0..$a3.

Но, конечно, если я хочу передать некоторые аргументы только для чтения, чтобы вызывающая сторона не сжималась, регистры $s были бы подходящими для них. Я не знаю каких-либо соглашений о вызовах C для ISA, у которых есть сохраняемые вызовы регистры передачи аргументов, но это имеет смысл в asm.

В этот момент вы используете его только с одним вызывающим абонентом, но, возможно, с нескольких сайтов вызовов в одной и той же функции, и, вероятно, выбираете регистры на основе того, что удобно для этого вызывающего абонента. Так что это едва ли независимая функция. Но это нормально.

...