【发布时间】:2015-09-16 06:21:01
【问题描述】:
我正在用 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 $16, %esp
leave
ret
.size function, .-function
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
pushl $3
pushl $2
pushl $1
call function
addl $12, %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 个字节。
但是根据不同的教程,我可以看到堆栈空间通常以 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) 可以组合成一个栈内存字的局部变量的类型有限制吗?
【问题讨论】:
-
不确定你的问题是什么,你声明了 16 个字节的局部变量并分配了 16 个字节,这是 4 的倍数。是的,编译器可能会按照它认为合适的方式排列局部变量和对齐方式
char是1,因此它们可以连续打包。 -
@Jester 我已经编辑了这个问题。可以请您现在检查吗
-
调用约定可能需要或需要,但我认为指令集不需要对齐。这些对齐有助于提高性能,arm 的 eabi 也需要它,但归根结底,它是特定的编译器、版本、命令行选项,无论什么决定了生成的代码。而且没有任何两个编译器必须做同样的事情的理由。
-
堆栈保持对齐的原因如下:1) 对齐的内存访问速度更快 2) 某些指令需要对齐内存操作数。 Vars(甚至 1 字节 var)通常分配为 4/8/16 字节的倍数,原因如下:1)使用本机字长(4 或 8 字节)更快(因为它有助于避免错误的依赖关系),甚至对于较小的数据类型 2) 从对齐的堆栈指针开始并仅减去对齐的数量来保持堆栈对齐。架构本身并不关心堆栈对齐
-
该语言几乎没有说明如何分配局部变量。你问的是编译器特定的。
标签: c linux memory assembly virtual-memory