varargs работает в мипс

Согласно Mips Abi, вызывающая сторона помещает первые несколько аргументов в GPR для производительности и не помещает эти аргументы в кадр стека. но когда я использую varargs api(stdarg.h) для определения функции с переменным списком аргументов, например void func(int type, ...);, API работает.

Я обнаружил, что stdarg.h apis ищет только аргументы в стеке. Если компилятор вставляет только первые несколько аргументов в GPR, почему работает stdarg.h? я что-то упустил из-за ABI?

1 ответ

Решение

Условные обозначения для функций variadic описаны в MIPS ELF ABI, стр. 3-46. По сути, когда вызываемая функция является переменной (ее список объявленных аргументов заканчивается на '...'), затем компилятор добавляет некоторый код, который записывает первые аргументы (переданные в регистрах) в стек. Фрейм стека всегда содержит некоторое пространство для первых четырех аргументов (точнее, для четырех слов, которые передаются в регистрах $4 в $7). Таким образом, вызывающей стороне не нужно знать, была ли функция переменной или нет (за исключением, возможно, аргументов с плавающей запятой; в любом случае, лучше, чтобы и вызывающая сторона, и вызываемая сторона видели и использовали один и тот же прототип).

Если вы скомпилируете функцию C-variadic и посмотрите на созданную сборку, то в начале функций вы увидите такие строки:

sw      $5,52($sp)
sw      $6,56($sp)
sw      $7,60($sp)

которые соответствуют этому процессу аргумента в стек.

Другие вопросы по тегам