gpt4 book ai didi

c - 程序集中局部变量的大小

转载 作者:太空宇宙 更新时间:2023-11-04 06:12:14 27 4
gpt4 key购买 nike

我有以下 C 函数:

void function(int a) {
char buffer[1];
}

它产生以下汇编代码(gcc 0 优化,64 位机器):

function:
pushq %rbp
movq %rsp, %rbp
movl %edi, -20(%rbp)
nop
popq %rbp
ret

问题:

  • 为什么缓冲区占用20个字节?
  • 如果我声明 char buffer 而不是 char buffer[1] 偏移量是 4 个字节,但我希望看到 8 个字节,因为机器是 64 位的,我认为它将使用 qword(64 位)。

提前致谢,如果问题重复,我很抱歉,我找不到答案。

最佳答案

movl %edi, -20(%rbp) 将函数 arg 从寄存器溢出到堆栈指针下方的红色区域。它有 4 个字节长,在其上方的 RSP 下方留有 16 个字节的空间。

gcc 的 -O0(朴素的反优化)代码生成函数实际上并没有触及它为 buffer[] 保留的内存,所以你不需要不知道它在哪里。

你不能推断 buffer[] 正在用完红色区域中 a 上面的所有 16 个字节,只是 gcc 在有效打包本地人方面做得不好(因为你用 -O0 编译所以它甚至没有尝试)。但它绝对不是 20,因为没有那么多空间了。除非它把 buffer[] 放在 a 中,在 128 字节红色区域的其余部分的其他地方。 (提示:它没有。)


如果我们为数组添加一个初始值设定项,我们可以看到它实际存储字节的位置。

void function(int a) {
volatile char buffer[1] = {'x'};
}

由 gcc8.2 编译 -xc -O0 -fverbose-asm -Wall on the Godbolt compiler explorer :

function:
pushq %rbp
movq %rsp, %rbp # function prologue, creating a traditional stack frame

movl %edi, -20(%rbp) # a, a

movb $120, -1(%rbp) #, buffer

nop # totally useless, IDK what this is for
popq %rbp # tear down the stack frame
ret

所以 buffer[] 实际上是一个字节长,正好在保存的 RBP 值之下。

x86-64 System V ABI 要求对至少 16 字节长的自动存储阵列进行 16 字节对齐,但此处情况并非如此,因此该规则不适用。

我不知道为什么 gcc 在溢出的寄存器 arg 之前留下额外的填充; gcc 经常有这种错过的优化。它没有给 a 任何特殊对齐方式。

如果您添加额外的本地数组,它们将填满溢出 arg 上方的 16 个字节,并将其溢出到 -20(%rbp)。 (请参阅 Godbolt 链接中的 function2)

我还在 Godbolt 链接中包含了 clang -O0icc -O3 和 MSVC 优化输出。有趣的事实:ICC 选择优化掉 volatile char buffer[1] = {'x'}; 而不是实际存储到内存中,但 MSVC 将其分配在影子空间中。 (Windows x64 使用不同的调用约定,返回地址上方有 32B 的阴影空间,而不是堆栈指针下方的 128B 红色区域。)

clang/LLVM -O0 选择将 a 溢出到 RSP 正下方,并将数组放在其下方 1 个字节处。


使用 just char buffer 而不是 char buffer[1]

我们从 gcc -O0 得到 movl %edi, -4(%rbp) # a, a。它显然完全优化了未使用和未初始化的局部变量,并在保存的 RBP 正下方溢出 a。 (我没有在 GDB 下运行它,也没有查看调试信息以查看 &buffer 是否会给我们。)

所以,您再次混淆了 abuffer

如果我们用 char buffer = 'x' 初始化它,我们会回到旧的堆栈布局,buffer-1 (%rbp)

或者即使我们只是让它成为 volatile char buffer; 而没有初始化器,那么它的空间存在于堆栈上并且 a 被溢出到 -20 (%rbp) 即使没有对 buffer 进行存储。

关于c - 程序集中局部变量的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53907745/

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