C 缓冲区分配不是字大小的倍数
我写了一个小程序来了解堆栈的结构C 缓冲区分配不是字大小的倍数,c,memory-management,gdb,stack,buffer-overflow,C,Memory Management,Gdb,Stack,Buffer Overflow,我写了一个小程序来了解堆栈的结构 #include <stdio.h> void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; int *ret = buffer1 + 13; (*ret) += 8; } int main() { int x = 0; function(1,2,3); x = 1; printf("x = %
#include <stdio.h>
void function(int a, int b, int c) {
char buffer1[5];
char buffer2[10];
int *ret = buffer1 + 13;
(*ret) += 8;
}
int main() {
int x = 0;
function(1,2,3);
x = 1;
printf("x = %d\n",x);
return 0;
}
我还了解到,如果我们分配5个字节的数据,程序分配8个字节(因为它必须是字大小的倍数)
函数函数的汇编程序代码转储:
0x08048414 <+0>: push %ebp
0x08048415 <+1>: mov %esp,%ebp
0x08048417 <+3>: sub $0x20,%esp
0x0804841a <+6>: lea -0x9(%ebp),%eax
0x0804841d <+9>: add $0xd,%eax
0x08048420 <+12>: mov %eax,-0x4(%ebp)
0x08048423 <+15>: mov -0x4(%ebp),%eax
0x08048426 <+18>: mov (%eax),%eax
0x08048428 <+20>: lea 0x8(%eax),%edx
0x0804842b <+23>: mov -0x4(%ebp),%eax
0x0804842e <+26>: mov %edx,(%eax)
0x08048430 <+28>: leave
0x08048431 <+29>: ret
这是我的疑问,buffer1
和buffer2
之间的差异怎么可能是10
,当所有内容都以字数的倍数分配时
%ebp和buffer1
之间的9
有什么区别
这里到底发生了什么
注意:
- 考虑堆栈从高到低的增长
- 字号=4
- 我使用的是英特尔处理器、Ubuntu 12.04、32位和
gcc-o stack-g-fno stack protector-O0 main.c
建造
我怀疑,当所有内容都以字大小的倍数分配时,buffer1和buffer2之间的差异怎么可能是0x10
首先,更正:buffer1
和buffer2
之间的差异是10
,而不是0x10
(即16
)
第二,并非所有内容都以多个单词的形式分配。总帧大小至少可以被8整除,以保持堆栈正确对齐双倍
,但单个局部变量将仅按照其对齐要求进行对齐(对于字符和字符缓冲区,这是1
)。编译器可以自由安排堆栈,但它认为合适。。。。。。字符数组不需要分配到4(甚至2)的倍数的地址上。它们可以在奇数边界上对齐。在大多数机器上,大多数其他基本类型将根据类型的大小在基本大小(2、4、8、16字节)的倍数边界上分配。有时,较大的类型只需要分配4字节的倍数。如果试图覆盖对齐要求,通常会失去性能—例如,通过包装结构。对于有同样疑问的人,我建议阅读Jonathan的评论。
0x08048414 <+0>: push %ebp
0x08048415 <+1>: mov %esp,%ebp
0x08048417 <+3>: sub $0x20,%esp
0x0804841a <+6>: lea -0x9(%ebp),%eax
0x0804841d <+9>: add $0xd,%eax
0x08048420 <+12>: mov %eax,-0x4(%ebp)
0x08048423 <+15>: mov -0x4(%ebp),%eax
0x08048426 <+18>: mov (%eax),%eax
0x08048428 <+20>: lea 0x8(%eax),%edx
0x0804842b <+23>: mov -0x4(%ebp),%eax
0x0804842e <+26>: mov %edx,(%eax)
0x08048430 <+28>: leave
0x08048431 <+29>: ret
(gdb) x/x $ebp
0xbffff318: 0xbffff348
(gdb) x/x buffer1
0xbffff30f: 0xfc73e461
(gdb) x/x buffer2
0xbffff305: 0x0108049f