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)
которые соответствуют этому процессу аргумента в стек.