Прежде всего, код в вашем вопросе передает аргументы в стеке, не следуя обычному соглашению о вызовах 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.
В этот момент вы используете его только с одним вызывающим абонентом, но, возможно, с нескольких сайтов вызовов в одной и той же функции, и, вероятно, выбираете регистры на основе того, что удобно для этого вызывающего абонента. Так что это едва ли независимая функция. Но это нормально.