assembly 什么是推入顺序参数

hsgswve4  于 2022-11-13  发布在  其他
关注(0)|答案(2)|浏览(125)

我在学习汇编语言。参数的推入顺序到底是什么?我知道这是参数被推入堆栈的方式,但是左 * 和 * 右 * 部分是什么意思?什么的左还是右?
或者,这仅仅是与命令的语义编写方式有关,即:

mov ebp, esp             ;esp is moved into ebp, right to left.

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

slmsl1lt

slmsl1lt1#

处理器不知道'function arguments',因此当你想写f(a,b,c)时,你真的需要把参数推到某个地方。
我知道在大多数x86机器上,函数参数是从右向左推到堆栈上的,即首先是c,然后是B,然后是a。

push c
push b
push a
call f

在x86上,推入堆栈会将堆栈的“顶端”减少一个字。已经推入三个字,以及传回位址,所以被呼叫的函式可以使用top + 1*W代表atop + 2*W代表btop + 3*W代表c
你也可以建立一个惯例,说:前两个参数在寄存器ebxecx中,其余的在堆栈中。只要调用方和被调用方同意,就可以了。

rqcrx0a6

rqcrx0a62#

除了xtofl的解释,你可能还想看看x86调用约定的表格。你会注意到,关于参数顺序,几乎所有的参数都是从右向左推送的(最右边的参数是最先推送的),除了Pascal。
xtofl没有涉及的另一个场景是寄存器参数--一些ABI要求一些参数在寄存器 * 中,而不是在堆栈 * 中。

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-您的体系结构肯定会有一个标准的调用约定,因为没有它很难工作。

相关问题