Почему порядок аргументов в стеке находится в таком порядке, что первый аргумент будет на самом низком адресе, второй на втором наименьшем и т. Д. - PullRequest
0 голосов
/ 08 мая 2019

Мой профессор архитектуры компьютеров попросил нас объяснить, почему аргументы помещаются в стек в обратном порядке.

Что я имею в виду под этим, скажем, когда мы хотим вызвать простую функцию, которая принимает 2 целых числа,поэтому мы расширяем наш стек по крайней мере на 24 байта, чтобы мы создали домашнюю секцию для регистров a0 - a3 и чтобы у нас было достаточно места для хранения значения регистра ra, а также выровняли стек так, чтобы sp находился по адресуэто кратно 8.

Почему этот регистр a0 находится в sp + 0, регистр a1 в sp + 4 и т. д.

Единственное, о чем я думалв том, что это просто соглашение, но нет причин спрашивать меня о причине обратного порядка аргументов, если это просто соглашение ...

1 Ответ

1 голос
/ 08 мая 2019

Если соглашение о вызовах передает аргументы в регистрах, вам не нужно сохранять их в стеке вообще .Вызывающий резервирует домашнее пространство перед вызовом, но именно вызывающий выбирает, как его использовать.

(Компилятор, выполняющий отладочную сборку, обычно сохраняет свои аргументы в памяти, но он может делать все, что захочет).

Соглашение о вызовах определяет вещи только тогда, когда у вас больше аргументов, чем умещается в регистрах: в этом случае все соглашения C помещают более ранние (слева) аргументы по более низким адресам, поэтому такие функции как printf don 'Не нужно знать, сколько всего аргументов нужно найти, например, шестое.Это делает не ошибкой printf("hello\n", 1, 2, 3, 4);.Printf просто никогда не будет смотреть на аргументы после первого, и ему все равно, что вызывающая сторона поместит 4 в стек.

Если вы хотите быть согласующимся с этим при выдаче аргументов регистра (это в основном весь смысл домашнего пространства), тогда вы сохраните их с первым аргументом по самому низкому адресу.


Я не эксперт по соглашениям о вызовах MIPS.Поскольку jal не изменяет $sp, я полагаю, что вызываемый может быть ответственным за резервирование "домашнего пространства".
Но если вызываемый пользователь резервирует домашнее пространство, тогда это просто дополнительная вещь, которую они могутделайте, если хотите, и не нуждаетесь в специальном имени!

Это отличается, например, в Windows x64, где инструкция call помещает адрес возврата в стек, поэтому важно, чтобы вызывающий резервировал теневое пространство до вызова, чтобы вызываемый мог сделать непрерывный массив аргументов.

Но так как MIPS jal передает адрес возврата в $raа не в стеке, нет причин вносить это в соглашение о вызовах.

...