为什么在x64上的函数Epilog中没有“ leave”指令?

时间:2019-02-20 08:15:06

标签: c++ c assembly x86-64 red-zone

我正在了解堆栈如何在x86和x64机器上工作。但是,我观察到的是,当我手动编写代码并将其反汇编时,它与我在人们提供的代码(例如,他们的问题和教程)中看到的有所不同。这是个小例子:

来源

int add(int a, int b) {
    int c = 16;
    return a + b + c;
}

int main () {
    add(3,4);
   return 0;
}

x86

add(int, int):
        push    ebp
        mov     ebp, esp
        sub     esp, 16
        mov     DWORD PTR [ebp-4], 16
        mov     edx, DWORD PTR [ebp+8]
        mov     eax, DWORD PTR [ebp+12]
        add     edx, eax
        mov     eax, DWORD PTR [ebp-4]
        add     eax, edx
        leave (!)
        ret

main:
        push    ebp
        mov     ebp, esp
        push    4
        push    3
        call    add(int, int)
        add     esp, 8
        mov     eax, 0
        leave (!)
        ret

现在是x64

add(int, int):
        push    rbp
        mov     rbp, rsp
        (?) where is `sub rsp, X`?
        mov     DWORD PTR [rbp-20], edi
        mov     DWORD PTR [rbp-24], esi
        mov     DWORD PTR [rbp-4], 16
        mov     edx, DWORD PTR [rbp-20]
        mov     eax, DWORD PTR [rbp-24]
        add     edx, eax
        mov     eax, DWORD PTR [rbp-4]
        add     eax, edx
        (?) where is `mov rsp, rbp` before popping rbp?
        pop     rbp
        ret

main:
        push    rbp
        mov     rbp, rsp
        mov     esi, 4
        mov     edi, 3
        call    add(int, int)
        mov     eax, 0
        (?) where is `mov rsp, rbp` before popping rbp?
        pop     rbp
        ret

如您所见,我的主要困惑是,当我针对x86进行编译时-我看到了我所期望的。当它是x64时-我错过了离开指令或确切的以下顺序:mov rsp, rbp,然后pop rbp。穿什么?

更新

似乎leave丢失了,仅仅是因为它以前没有更改过。但是,还有另一个问题-为什么框架中没有分配给本地变量?


对于这个问题,@melpomene给出了非常简单的答案-由于存在“红色区域”。从根本上讲,这意味着不调用其他函数(叶)的函数可以使用堆栈下方的前128个字节,而无需分配空间。因此,如果我在add()内插入对任何其他哑函数的调用-sub rsp, Xadd rsp, X将分别添加到序言和结语中。

0 个答案:

没有答案