代码之家  ›  专栏  ›  技术社区  ›  unwind

无法理解x86-64函数前导码

  •  8
  • unwind  · 技术社区  · 14 年前

    我遇到了车祸,在调查过程中,我发现自己完全被以下代码阻止:

    0000000000000a00 <_IO_vfprintf>:
    a00:       55                      push   %rbp
    a01:       48 89 e5                mov    %rsp,%rbp
    a04:       41 57                   push   %r15
    a06:       41 56                   push   %r14
    a08:       41 55                   push   %r13
    a0a:       41 54                   push   %r12
    a0c:       53                      push   %rbx
    a0d:       48 81 ec 48 06 00 00    sub    $0x648,%rsp
    a14:       48 89 95 98 f9 ff ff    mov    %rdx,0xfffffffffffff998(%rbp)
    

    这是通过运行 objdump --disassemble /usr/lib64/libc.a 在64位Linux x86系统上,然后搜索输出。这是 AT&T syntax ,所以目的地在右边。

    具体地说,我不明白最后的指示。它似乎在写 rdx 在函数接触到该寄存器之前,在堆栈的某个位置(远、远)注册到内存中。对我来说,这没有任何意义。

    我试着读一下通话约定,现在我最好的理论是 RDX 用于参数,因此代码基本上是直接“返回”参数值。这不是函数的结尾,所以它不会真正返回。

    1 回复  |  直到 10 年前
        1
  •  12
  •   Matthew Slattery    14 年前

    是的,这是一个参数。这个 ABI used by Linux 以明显且易于记忆的顺序为寄存器分配最多6个“integer”(<=64位integer或指针)类型参数 %rdi , %rsi , %rdx , %rcx , %r8 , %r9 .

    堆栈帧为1648字节( sub $0x648,%rsp 声明1608字节,加上5个64位寄存器已经被推到前面),以及 0xfffffffffffff998 IS - 1640。

    所以代码将第三个参数存储在堆栈框架的底部附近。

    (注意:Windows 64位ABI与Linux不同。)