假设我有两个参数,arg1和arg2,以及我想调用的函数。如果我将arg1加载到$ esp + 4并将arg2加载到$ esp中,我将执行以下哪项操作:
func(arg1, arg2)
或
func(arg2, arg1)
我正在使用IA32。
答案 0 :(得分:4)
This是一篇非常有用的文章,可以很好地解释应用程序堆栈。
答案 1 :(得分:4)
哦,我会以我最喜欢的方式回答!
它取决于!
这取决于您正在使用的呼叫机制。看看x86 calling conventions并感到惊讶。
但是,请注意,在最常见的默认情况下,cdecl函数参数以从右到左的顺序被压入堆栈。实际上,它们也在Windows使用的stdcall中从右向左推送。
现在找出esp+x
在函数排序中的方式。堆栈从地址空间的高端向下增长,从右到左排序意味着最右边的对象首先进入堆栈,因此最右边的参数具有更高的内存地址。因此,当您添加到esp
或任何寄存器跟踪堆栈中最低(就内存地址而言)参数时,您将从右到左移动参数。
我想补充一点,ebp
往往是基指针,esp
被移动以允许根据function prologue的描述进行局部变量存储。
答案 2 :(得分:1)
堆栈增长,参数布局有点像数组,特别是第一个参数(你的例子调用 arg2 )在同一个地方,无论有多少参数在电话中。
否则,当函数采用可变数量的参数时,很难使函数工作。
理论上,平台可以采用不同的方式,但任何主要实例都不是这样。
答案 3 :(得分:1)
This article是必读。