空弹出怎么办?

问题描述

我具有以下函数,该函数一个数字存储在堆栈上(并修改该数字),最后将其清理干净:

.rodata
number: .long   127     # need to keep original value

_start:

    # set up stack,align on 16 for syscalls
    push %rbp
    mov %rsp,%rbp
    push number

    ...

  exit:
    pop ???
    mov %rbp,%rsp
    pop %rbp
    mov $SYS_EXIT,%eax
    syscall

我应该怎么用pop删除数字(即退出前重新对齐堆栈)?

解决方法

您可以使用add $8,%rsp,也可以直接跳到不需要关心的寄存器中,例如pop %rcx

由于较短的代码大小和“ stack engine”的怪异(在RSP中的明确使用可以使Intel CPU作为堆栈同步uop插入),后者在较新的系统上略为可取。太糟糕了。

某些编译器(特别是clang)在需要将RSP精确移动8时会默认使用虚拟push / pop:Why does this function push RAX to the stack as the first operation?


还要注意,popmov %rbp,%rsp来说是多余的,因为无论如何您都将RBP用作帧指针。而且_exit系统调用与RSP指向的位置无关。