【问题标题】:What is argument push order什么是参数推送顺序
【发布时间】:2012-02-26 20:00:35
【问题描述】:

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

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

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

非常感谢!

【问题讨论】:

    标签: assembly push arguments


    【解决方案1】:

    处理器不知道“函数参数”。因此,当您想写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 中,其余参数在堆栈中。只要调用者和被调用者同意,就可以了。

    【讨论】:

      【解决方案2】:

      除了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 - 你的架构肯定会有一个标准的调用约定,因为没有它很难工作。

      【讨论】:

      • 非常感谢你们两位。这很有帮助,我现在理解得更好了!谢谢一百万!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-27
      • 2016-08-27
      • 1970-01-01
      • 2019-01-28
      • 2023-04-05
      相关资源
      最近更新 更多