什么是参数推送顺序

Axo*_*otl 9 assembly arguments push

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

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

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

非常感谢!

xto*_*ofl 14

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

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

push c
push b
push a
call f
Run Code Online (Sandbox Code Playgroud)

现在被调用的函数可以ebx -1用于a,ebx - 2for b和ebx - 3c.

你还可建立一个约定,说:前两个参数是在寄存器ebxecx,其余的都是在栈上.只要来电者和被叫者同意,你就没事了.

  • “ebx-1”从哪里来?如果这些应该是地址,则“push”会将堆栈指针递减 4(或 64 位模式下的 8),因此每个堆栈槽相隔 4 或 8 个字节,如“ebx - 4”(c)、“ebx” - 8` (b) 等。只有在这些推送之前 EBX = ESP 时才是如此。这很不寻常;如果你要使用任何寄存器来做到这一点,那就是 EBP。但是 *callee* `f` 无法假设调用者相对于其传入堆栈参数离开 EBP 的位置。它需要查看其返回地址以及 `[esp+4]` (a)、`[esp+8]` (b) 等。或者在推送任何内容后查看更高的偏移量。 (2认同)

小智 10

除了xtofl的解释之外,你可能想看看这个x86调用约定表.关于参数顺序,你会注意到几乎所有的参数都是从右到左推送的(最右边的参数是先推的),Pascal除外.

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

int add3(int a, int b, int c)
Run Code Online (Sandbox Code Playgroud)

将提出论点:

a -> rdi
b -> rsi
c -> rdx
Run Code Online (Sandbox Code Playgroud)

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

mov     rdi, [source-of-a]
mov     rsi, [source-of-b]
mov     rdx, [source-of-c]
call    add3
Run Code Online (Sandbox Code Playgroud)

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

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

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