在cdecl
调用约定中,它声明:
Arguments are pushed in the reverse order (right to left)
我的问题是:相反于非反向顺序的相反顺序?它与功能文档有关吗?例如,如果我有以下功能文档:
void __cdecl foo (int arg1, int arg2, int arg3)
那么我应该只看一下函数文档中参数的顺序,并反转推入堆栈的增量?
答案 0 :(得分:3)
根据asm指令顺序和执行顺序,第一个函数参数被推送到最后。但是,由于堆栈向下增长,第一个参数的地址最低。
这个方案意味着第一个参数(和第二个等)总是可以作为当前堆栈指针的常量偏移量来访问 - 它就在返回地址之后找到。
是的,你应该完全按照你在问题结尾处建议的那样做,尽管一种常见的技术是在函数头部保留堆栈空间,该空间足够大以支持所有堆栈变量加上任何所需的函数调用参数(但不是返回地址),只需堆叠相对存储来设置参数。
请注意,在许多ISA ABI中,前几个参数在寄存器中传递,而不是在堆栈中传递,但无论如何都保留堆栈空间,以便跨嵌套函数调用进行存储。
答案 1 :(得分:3)
如果您的函数调用是:
foo( arg1, arg2, ... argN )
然后"参数顺序"将从左到右(arg1到argN)。函数调用代码为:
push arg1
push arg2
...
push argN
call foo
"逆序(从右到左)"将argN转到arg1:
push argN
...
push arg1
call foo
当然,args可能不是单个DWORDS,因此推送操作可能不是单个指令。编译器也可能非常聪明,并为args预先分配堆栈空间,然后通过各种MOV指令将参数填充到分配的堆栈空间中的偏移量,可能不是以任何特定顺序。因此,解释"推动论证"根据这个想法"好像"推动已经完成。