gpt4 book ai didi

linux - 以前错误的未对齐调用现在可以工作了吗?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:32:48 25 4
gpt4 key购买 nike

我不确定我是不是错觉了,但我接近某些调用曾经在 System V Linux x86_64 上失败,如果它们在输入时没有对齐(即你故意在 call 之前取消对齐堆栈,以便在进入时对齐)。

例如(这现在有效):

.data
str: .asciz "string literal"

.text
.globl main
main:
lea str(%rip), %rdi
call puts@plt
xor %eax, %eax
ret

我几乎可以肯定这曾经失败过,有人可以解释一下我是不是:妄想(即这一直有效),误解堆栈对齐的语义,不知道(最近?)某处某事的变化?

以前,我总是故意使用 push(按照常见的序言)或简单地 sub $8, %rsp 来不对齐,但现在我编写的代码没有这样做似乎工作正常?

这是细微差别还是现在可以接受这种行为?

最佳答案

你没有错觉。 x86-64 SysV ABI 要求堆栈在调用外部函数之前对齐到 16,这意味着堆栈指针值 mod 16 在函数入口处为 8,并且必须调整 8 的奇数倍才能重新对齐它在调用另一个函数之前。但是,这并没有严格执行。调用本身永远不会出错,用于访问堆栈的大多数类型的指令也不会出错。仅当被调用函数使用需要对齐的指令(例如某些 SSE 指令(包括 SSE 扩展和 AVX))访问堆栈上的值时才会导致错误。

一些库函数的实现总是执行这样的访问,所以它们总是会在未对齐的堆栈上出错。其他一些库函数可能会根据传递的数据对堆栈执行此类访问,而有些则永远不会使用此类访问,并且无论堆栈对齐如何都不会出错。但是,依赖其中任何一个都是不明智的,因为实现可能会发生变化。在调用之前始终对齐堆栈。

关于linux - 以前错误的未对齐调用现在可以工作了吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54620724/

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