x86_64 调用约定

逆向工程 拆卸 x64 调用约定
2021-06-11 14:08:35

我对这里的一些 x86_64 linux 代码(由 llvm 生成)感到有些困惑:

# BB#0:                                 # %entry
    push    RBP
.Ltmp21:
    .cfi_def_cfa_offset 16
.Ltmp22:
    .cfi_offset rbp, -16
    mov RBP, RSP
.Ltmp23:
    .cfi_def_cfa_register rbp
    push    RBX
    push    RAX
.Ltmp24:
    .cfi_offset rbx, -24
    mov EDI, .L.urandom
    mov ESI, 8
    call    open
    mov EBX, EAX
    mov EDI, EBX
    mov ESI, ptrenc.keys
    mov EDX, 16
    call    read

从我在维基百科中读到的内容来看,我希望打开和读取的参数在 R 寄存器(RDI、RSI、RDX)中传递。

该代码使用 64 位寄存器来构建堆栈帧。为什么它使用 32 位寄存器进行调用?

2个回答

所以,你的问题主要是关于这部分代码(如果我不关心第二个类似的调用):

mov EDI, .L.urandom
mov ESI, 8
call    open

事实上,这完全没问题ESIEDI正如这里所做的那样,因为传输的值是 32 位值……而且,无论如何,在 amd64 中,当操作 32 位寄存器时,您将清空 32 位的高位相应的 64 位寄存器(零扩展)。所以,你最终了RSIRDI被包含正确的价值观,你只需要32位从存储器传送到寄存器...它可以被看作是一个小小的优化。

你会在这里找到答案如果您想了解更多详细信息,那么在这里您会找到所需的一切。