堆栈变量是否在虚拟内存中连续分配?
Are stack variables allocated contiguously in virtual memory?
我正在用 C:
编译下面的程序
void function(int a, int b, int c) {
char buffer1[11];
char buffer2[3];
char buffer3[1];
char buffer4[1];
}
void main() {
function(1,2,3);
}
使用命令:
gcc -m32 -fno-asynchronous-unwind-tables -fno-stack-protector -S -o example1.s example1.c
下面是我得到的输出:
.file "example1.c"
.text
.globl function
.type function, @function
function:
pushl %ebp
movl %esp, %ebp
subl , %esp
leave
ret
.size function, .-function
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
pushl
pushl
pushl
call function
addl , %esp
leave
ret
.size main, .-main
.ident "GCC: (Ubuntu 4.9.2-10ubuntu13) 4.9.2"
.section .note.GNU-stack,"",@progbits
行 subl $16, %esp 表示在堆栈上分配了 16 个字节。
然而,根据不同的教程,我可以看到堆栈 space 通常以 4 字节为单位分配。
为什么我看到的行为不同?
我是 运行 64 位 Ubuntu 系统:-
vendor_id : GenuineIntel
cpu family : 6
model : 58
model name : Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz
stepping : 9
microcode : 0x1b
cpu MHz : 1202.636
cache size : 3072 KB
physical id : 0
siblings : 4
core id : 0
cpu cores : 2
apicid : 0
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
bugs :
bogomips : 4988.46
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:
谁能帮我理解一下。
我提到了以下问题:How is memory allocated for stack variables?
但我找不到具体的答案。
编辑:
1) 我想了解整个堆栈是否只需要与 4/8/16 字节边界对齐,或者每个堆栈变量都必须对齐。
2) 可以组合成一个字的栈内存的局部变量的类型有没有限制?
"1) 我想了解是整个堆栈只需要与 4/8/16 位边界对齐还是每个堆栈变量都必须对齐。"
这是一个机器和编译器特定的问题。通常,变量根据其大小和 CPU 字长对齐。在 32 位 CPU 上对齐 32 位边界上的 32 位变量有很大的优势,但是在 8 位 CPU 上对齐 32 位变量没有优势,例如8051。 32位CPU只能将32位值作为32位值处理,如果它们在32位边界上对齐(0x??0, 0x??4, 0x??8, 0x??c).
2) 可以组合成一个字的栈内存的局部变量的类型有没有限制?
除对齐外没有其他限制。
答案是堆栈变量不必连续分配。在很多情况下,他们不太可能。
如果你有
{
struct
{
int a ;
char b ;
double c ;
char d ;
} x, y, z;
}
我敢打赌大多数编译器不会使 x、y 和 z 连续。
无论如何,您的要求完全取决于系统和编译器。编译器根本不需要将自动变量放在堆栈上。
我正在用 C:
编译下面的程序void function(int a, int b, int c) {
char buffer1[11];
char buffer2[3];
char buffer3[1];
char buffer4[1];
}
void main() {
function(1,2,3);
}
使用命令:
gcc -m32 -fno-asynchronous-unwind-tables -fno-stack-protector -S -o example1.s example1.c
下面是我得到的输出:
.file "example1.c"
.text
.globl function
.type function, @function
function:
pushl %ebp
movl %esp, %ebp
subl , %esp
leave
ret
.size function, .-function
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
pushl
pushl
pushl
call function
addl , %esp
leave
ret
.size main, .-main
.ident "GCC: (Ubuntu 4.9.2-10ubuntu13) 4.9.2"
.section .note.GNU-stack,"",@progbits
行 subl $16, %esp 表示在堆栈上分配了 16 个字节。
然而,根据不同的教程,我可以看到堆栈 space 通常以 4 字节为单位分配。
为什么我看到的行为不同?
我是 运行 64 位 Ubuntu 系统:-
vendor_id : GenuineIntel
cpu family : 6
model : 58
model name : Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz
stepping : 9
microcode : 0x1b
cpu MHz : 1202.636
cache size : 3072 KB
physical id : 0
siblings : 4
core id : 0
cpu cores : 2
apicid : 0
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
bugs :
bogomips : 4988.46
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:
谁能帮我理解一下。
我提到了以下问题:How is memory allocated for stack variables? 但我找不到具体的答案。
编辑: 1) 我想了解整个堆栈是否只需要与 4/8/16 字节边界对齐,或者每个堆栈变量都必须对齐。 2) 可以组合成一个字的栈内存的局部变量的类型有没有限制?
"1) 我想了解是整个堆栈只需要与 4/8/16 位边界对齐还是每个堆栈变量都必须对齐。"
这是一个机器和编译器特定的问题。通常,变量根据其大小和 CPU 字长对齐。在 32 位 CPU 上对齐 32 位边界上的 32 位变量有很大的优势,但是在 8 位 CPU 上对齐 32 位变量没有优势,例如8051。 32位CPU只能将32位值作为32位值处理,如果它们在32位边界上对齐(0x??0, 0x??4, 0x??8, 0x??c).
2) 可以组合成一个字的栈内存的局部变量的类型有没有限制?
除对齐外没有其他限制。
答案是堆栈变量不必连续分配。在很多情况下,他们不太可能。
如果你有
{
struct
{
int a ;
char b ;
double c ;
char d ;
} x, y, z;
}
我敢打赌大多数编译器不会使 x、y 和 z 连续。
无论如何,您的要求完全取决于系统和编译器。编译器根本不需要将自动变量放在堆栈上。