什么是参数推送顺序

时间:2012-02-04 14:31:40

标签: assembly push arguments

我正在学习汇编语言。什么是参数推送顺序?我理解它如何被推入堆栈但左右部分是什么意思?什么左?或右? 或者这只是与语义编写命令的方式有关,即:

mov ebp,esp; esp从右到左移动到ebp。

这是正确的还是有人可以启发我?

非常感谢!

2 个答案:

答案 0 :(得分:14)

处理器不知道'函数参数'。因此,当你想写f(a,b,c)时,你真的需要在某个地方推送参数。

这是惯例。我知道在大多数x86机器上,函数参数从右到左被推入堆栈,即第一个c,然后是b,然后是a。

push c
push b
push a
call f

现在被叫函数可以使用ebx -1代表a,ebx - 2代表b,ebx - 3代表c。

您还可以建立一个约定:前两个参数位于寄存器ebxecx中,其余位于堆栈中。只要来电者和被叫者同意,你就没事了。

答案 1 :(得分:10)

xtofl的解释外,您可能希望查看此x86 calling conventions表。关于参数顺序,你会注意到的是几乎所有参数都是从右到左推送的(最右边的参数是先推的),Pascal除外。

另一个场景xtofl没有涉及寄存器参数 - 一些ABI要求某些参数位于寄存器中而不是堆栈上的。例如,在x86_64系统上,函数:

int add3(int a, int b, int c)

将提出参数:

a -> rdi
b -> rsi
c -> rdx

具体来说,这看起来像(英特尔语法):

mov     rdi, [source-of-a]
mov     rsi, [source-of-b]
mov     rdx, [source-of-c]
call    add3

因此寄存器从寄存器列表从左到右填充然后堆栈使用从右到左

正如xtofl所说,如果调用者和被调用者同意你做什么并不重要 - 但是,如果调用者和被调用者不同意这会导致不兼容问题,这显然是实际上,不仅对于汇编程序而且对于更高级别的语言也是一个问题 - 幸运的是,编译器主要从右到左运行。为了进一步阅读,您可能会发现堆栈的被调用者/调用者清理很有趣 - 并注意它是如何标准化为x86_64的一种方法。

你没有说你正在使用x86 - 你的架构肯定会有一个标准的调用约定,因为没有它就很困难。