C 堆栈上的本地var和EBP之间是什么?

C 堆栈上的本地var和EBP之间是什么?,c,linux,assembly,stack,C,Linux,Assembly,Stack,对于此简单代码: void main(){ char buf[12]; buf[11]='\xff'; puts(buf); } 我使用gdb调试此代码,并获得如下堆栈信息: 0xbffff480: 0x40158ff4 0x40158ff4 0xff0494dc 0x40158ff4 0xbffff490: 0x00000000 0x40016ca0 0xbffff4f8 0x40045de3 0xbf

对于此简单代码:

void main(){
  char buf[12];
  buf[11]='\xff';
  puts(buf);
}
我使用gdb调试此代码,并获得如下堆栈信息:

0xbffff480:     0x40158ff4      0x40158ff4      0xff0494dc      0x40158ff4
0xbffff490:     0x00000000      0x40016ca0      0xbffff4f8      0x40045de3
0xbffff480是buf开始的地方,最后两个词是EBP和RET,但buf和EBP之间到底是什么?很明显,我没有任何其他的本地VAR。我也尝试过,若我在堆栈上为buf分配8个字节,它只是从EBP继续,但若我分配9个或更多字节,它总是在两者之间。谁能给我解释一下吗?谢谢!我使用的是linux 2.6.9

主泵的拆卸:

0x080483c4 <main+0>:    push   %ebp
0x080483c5 <main+1>:    mov    %esp,%ebp
0x080483c7 <main+3>:    sub    $0x28,%esp
0x080483ca <main+6>:    and    $0xfffffff0,%esp
0x080483cd <main+9>:    mov    $0x0,%eax
0x080483d2 <main+14>:   add    $0xf,%eax
0x080483d5 <main+17>:   add    $0xf,%eax
0x080483d8 <main+20>:   shr    $0x4,%eax
0x080483db <main+23>:   shl    $0x4,%eax
0x080483de <main+26>:   sub    %eax,%esp
0x080483e0 <main+28>:   movb   $0xff,0xfffffff3(%ebp)
0x080483e4 <main+32>:   lea    0xffffffe8(%ebp),%eax
0x080483e7 <main+35>:   mov    %eax,(%esp)
0x080483ea <main+38>:   call   0x80482e4
0x080483ef <main+43>:   leave
0x080483f0 <main+44>:   ret

通常,为了能够使用SSE指令,gcc将堆栈对齐到16的倍数。阅读main的反汇编会很有帮助。

通常,为了能够使用SSE指令,gcc会将堆栈对齐到16的倍数。阅读主要部件的拆卸会很有帮助。

那会很有帮助。您的编译器可能是8字节边界上的EBP,因为从处理器的角度来看,对齐内存几乎总是可以使用的。有些数据类型甚至需要正确对齐才能工作

当在缓冲区中只分配8个字节时,您看不到任何填充,因为在这种情况下,EBP已经正确对齐。

。您的编译器可能是8字节边界上的EBP,因为从处理器的角度来看,对齐内存几乎总是可以使用的。有些数据类型甚至需要正确对齐才能工作


当在缓冲区中只分配8个字节时,您不会看到任何填充,因为在这种情况下,EBP已经正确对齐。

您应该真正包括一个ASEMBLY转储,而不是纯十六进制转储。但这很可能是两件事中的一件:

正在恢复的堆栈帧 进行堆叠检查,以确保没有过量
开始还可能包含堆栈对齐,强制执行上面的一个或两个

您应该真正包括一个适当的转储,而不是纯十六进制转储。但这很可能是两件事中的一件:

正在恢复的堆栈帧 进行堆叠检查,以确保没有过量
start还可能包含堆栈对齐,强制执行上面的一个或两个

GCC对堆栈的使用有点满意。它通常会保留比严格需要的更多的堆栈空间。此外,它将尝试实现16字节堆栈对齐,即使这不是必需的。第一条指令保留40个字节,然后%esp对齐到16的倍数,这似乎就是发生的情况

然而,您展示的代码包含一些奇怪的东西,特别是偏移量9到27的序列:这是一种从%esp中减去16的长、慢、复杂的方法,可以在单个操作码中完成。此时从%esp中减去一些字节是为调用外部函数puts做准备的合乎逻辑的,计数16尊重对齐,但为什么这样做如此奇怪


该序列可能以某种方式修补,例如在链接时,以支持堆栈破坏检测代码或某种分析代码。我无法在自己的系统上复制这一点。您应该指定您正在使用的gcc和libc的版本、确切的编译标志以及Linux发行版,因为默认情况下分发服务器可能会激活一些选项。图2.6.9是内核版本,它与当前的问题没有任何关系,它只是告诉我们系统已经很旧了。

GCC对堆栈的使用有点满意。它通常会保留比严格需要的更多的堆栈空间。此外,它将尝试实现16字节堆栈对齐,即使这不是必需的。第一条指令保留40个字节,然后%esp对齐到16的倍数,这似乎就是发生的情况

然而,您展示的代码包含一些奇怪的东西,特别是偏移量9到27的序列:这是一种从%esp中减去16的长、慢、复杂的方法,可以在单个操作码中完成。此时从%esp中减去一些字节是为调用外部函数puts做准备的合乎逻辑的,计数16尊重对齐,但为什么这样做如此奇怪


该序列可能以某种方式修补,例如在链接时,以支持堆栈破坏检测代码或某种分析代码。我无法在自己的系统上复制这一点。您应该指定您正在使用的gcc和libc的版本、确切的编译标志以及Linux发行版,因为默认情况下分发服务器可能会激活一些选项。图2.6.9是内核版本,与当前的问题没有任何关系,它只是告诉我们系统非常旧。

看看我的gcc是否使堆栈16字节对齐,我认为如果我在堆栈上分配16字节,它应该从EBP继续,但事实并非如此。中间还有填充物。看看我的gcc是否
堆栈16字节对齐,我认为如果我在堆栈上分配16字节,它应该从EBP继续,但事实并非如此。中间还有衬垫。谢谢你们的帮助。我已经为main添加了disas。请进一步帮助。谢谢大家的帮助。我已经为main添加了disas。请进一步帮助。谢谢