当他们说'#34;参数按相反的顺序推进时是什么意思"?

时间:2015-01-16 07:50:22

标签: assembly x86 calling-convention

cdecl调用约定中,它声明:

Arguments are pushed in the reverse order (right to left)

我的问题是:相反于非反向顺序的相反顺序?它与功能文档有关吗?例如,如果我有以下功能文档:

void __cdecl foo (int arg1, int arg2, int arg3)

那么我应该只看一下函数文档中参数的顺序,并反转推入堆栈的增量?

2 个答案:

答案 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指令将参数填充到分配的堆栈空间中的偏移量,可能不是以任何特定顺序。因此,解释"推动论证"根据这个想法"好像"推动已经完成。