什么是参数推序

发布于 2025-01-02 10:20:52 字数 230 浏览 2 评论 0原文

我正在学习汇编语言。到底什么是参数推序?我知道参数是如何推入堆栈的,但是左和部分是什么意思?左边还是右边什么?

或者这仅仅是与命令的语义编写方式有关,即:

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

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

I'm learning Assembly language. What exactly is argument push order? I understand it's how arguments are pushed to the stack but what does the left and right part mean? Left or right of what?

Or is this merely to do with the way the command is semantically written, i.e.:

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

Is this correct or could someone enlighten me?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

作死小能手 2025-01-09 10:20:52

处理器不知道“函数参数”。因此,当您想编写 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

您也可以建立一个约定:前两个参数位于寄存器 ebx 和 ecx 中,其余参数位于堆栈中。只要调用者和被调用者同意,就可以了。

The processor doesn't know 'function arguments'. Therefore when you want to write f(a,b,c), you really need to push the arguments 'somewhere'.

How and where to push them is mere convention. I know that on most x86 machines, function arguments are pushed on the stack from right to left, i.e. first c, then b, then a.

push c
push b
push a
call f

Pushing to the stack would, on x86, decrease the stack 'top' with a word. Three words have been pushed, and the return address, so the called function can use top + 1*W for a, top + 2*W for b and top + 3*W for c.

You could as well establish a convention that says: first two arguments are in registers ebx and ecx, rest are on the stack. As long as the caller and callee agree, you're fine.

江湖正好 2025-01-09 10:20:52

除了 xtofl 的解释之外,您可能还想查看一下 x86 调用约定。您会注意到,关于参数顺序,几乎所有参数都从右向左推送(最右边的参数首先推送),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

因此寄存器是从寄存器列表从左到右填充的< /em> 然后使用堆栈从右到左

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

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

In addition to xtofl's explanation you might like to have a look at this table of x86 calling conventions. What you'll note, with regards to argument order is that almost all of the arguments are pushed on right to left (rightmost argument is pushed first) with the exception of Pascal.

Another scenario xtofl doesn't cover are register arguments - some ABIs require that some arguments are in registers as opposed to on the stack. On a x86_64 system, for example, the function:

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

will put arguments:

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

Specifically, this would look like (Intel syntax):

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

So the registers are filled up from the register list left to right and then the stack is used right to left.

As xtofl says, it doesn't matter what you do provided the caller and the callee agree - clearly, however, if the caller and the callee disagree that'll cause incompatibility problems and this is actually a concern not only for assembler, but for higher level languages too - luckily, compilers largely operate right to left. For further reading, you might find the callee/caller cleanup of the stack interesting - and note how it was standardised to one method for x86_64.

You don't say you're using x86 - your architecture will most certainly have a standard calling convention as working without it is difficult.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文