gpt4 book ai didi

linux - x86-64 Linux 堆栈未对齐时没有段错误

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:19:10 25 4
gpt4 key购买 nike

我只是通过 Nick Desaulniers 工作:Let's Write Some X86-64文件 h4.s:

.text
.globl main
main:
# subq $8, %rsp
movq $0, %rdi
call _exit

他在 Mac 上运行,并说运行上面的代码会出现段错误。我在 opensuse 13.1 上运行,只是调用

gcc h4.s

编译和链接。调整堆栈指针或注释掉该行时,我没有遇到段错误。有谁知道为什么不呢? SP 不需要对齐到 16 字节边界吗?

最佳答案

x86-64 System V ABI 要求堆栈指针在例程入口处为 8 mod 16 字节(调用前 16B 对齐,返回地址压入后 16+8栈)。

只有 SSE 指令需要这个(比如 movaps/movdqa),大多数库函数碰巧不使用它。像 _exit 这样特别简单的可以像 mov $231, %eax/syscall 一样简单。

但是,如果堆栈未对齐并且有人在某个时候想要做一些基于他们具有 16B 对齐堆栈的假设的事情。例如,发出一条对齐的 xmm 指令,如“movdqa [rsp],...”,然后你会得到一个实际的段错误。或者假设一些其他类型的堆栈对齐假设的其他错误。

总结:在调用之前简单地错位堆栈通常不会出错。

就像 C 未定义行为一样,如果您违反规则,它不一定会失败,但它可以失败。现在发生的事情可能会在未来或在其他系统上崩溃。

编译器允许在任何地方使用 SSE 一次向/从局部变量复制 16 个字节,because of the ABI guarantee ,并且因为 x86-64 至少保证 SSE2。

例如,glibc scanf Segmentation faults when called from a function that doesn't align RSP - glibc 的现代构建包括一个 movaps 以一次将 16 个字节复制到本地结构或数组。较早版本的 glibc 不需要堆栈对齐(当您正确设置 AL=0 时)。

关于linux - x86-64 Linux 堆栈未对齐时没有段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25241494/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com