根据 mips abi 的说法,调用者将前几个参数放在 GPR 中以提高性能,并且不要将这些参数推送到堆栈框架中。但是当我使用 varargs api(stdarg.h) 定义具有可变参数列表的函数时,例如 void func(int type, ...);,api 工作。
我发现 stdarg.h apis 只搜索堆栈中的参数,如果编译器只将前几个参数推入 GPR,为什么 stdarg.h 工作?我错过了关于 ABI 的一些东西吗?
可变参数函数的约定在MIPS ELF ABI中描述,第 3-46 页。基本上,当被调用函数是可变参数时(其声明的参数列表以 ' ...
' 结尾),编译器会添加一些代码,将第一个参数(在寄存器中传递)写入堆栈。$4
堆栈帧总是为前四个参数包含一些空间(准确地说,对于在寄存器中传递给的四个字$7
)。因此,调用者不需要知道函数是否是可变参数(可能浮点参数除外;无论如何,最好是调用者和被调用者都看到并使用相同的原型)。
如果您编译一个 C 可变参数函数并查看生成的程序集,您会在函数开头附近看到如下行:
sw $5,52($sp)
sw $6,56($sp)
sw $7,60($sp)
这对应于那个参数到堆栈的过程。