【问题标题】:What to do with an empty pop?空的流行音乐怎么办?
【发布时间】:2021-01-05 20:04:35
【问题描述】:

我有以下函数,它在堆栈上存储一个数字(并修改该数字),然后在最后清理它:

.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 以摆脱数字(即,在退出之前重新对齐堆栈)?

【问题讨论】:

  • 可以在不清理堆栈的情况下调用“SYS_EXIT”,也就是说可以删除“pop???”以及它之后的 2 条指令,这无关紧要。
  • push number 从绝对地址 number 加载 8 个字节,但您只分配了 4 个字节的静态数据与 .long。您的意思可能是push $number 将地址作为立即推送,而不是从中加载?因为如果您确实想加载,push number(%rip) 是解决静态存储的更有效方式。

标签: assembly x86 x86-64 callstack


【解决方案1】:

您可以使用add $8, %rsp 或直接弹出一个您不关心的值的寄存器,例如pop %rcx

由于“stack engine”的代码较短和怪癖(显式使用 RSP 可以使 Intel CPU 作为堆栈同步 uop 插入),后者在最近的系统上稍微可取,但前者还不错要么。

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


还请注意,您的popmov %rbp, %rsp 是多余的,因为无论如何您都在使用 RBP 作为帧指针。并且_exit 系统调用并不关心 RSP 指向的位置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-07
    • 1970-01-01
    • 1970-01-01
    • 2021-03-17
    • 2013-02-01
    • 1970-01-01
    相关资源
    最近更新 更多