c语言变量的存储位置
#include <stdio.h>
/* 分配在 .rodata段,
程序加载时.rodata段和.text 段通常合并到一个Segment中,
只读,GLOBAL
*/
const int A = 10;
// 分配在 .data段,GLOBAL
int a = 20;
// 分配在 .data段,LOCAL,只能在某一个目标文件中定义和使用
static int b = 30;
/* 分配在 .bss 段(紧挨着.data段),
.data 和 .bss 段加载时合并到一个Segment中, 可读可写,
.bss 段在文件中不占存储空间,在加载时这个段用0填充,全局变量如果不初始化则初值为0,
同理可以推断,static变量(不管是函数里的还是函数外的)如果不初始化则初值也是0,也分配在.bss 段。
*/
int c;
// 都分配在 .bss 段
static int d;
const int e;
// 都分配在 .rdata 段
static const f = 20;
const static g = 30;
int main(void) {
// 静态分配在 .data, a.2050区分全局变量a
static int a = 40;
// 函数的参数和局部变量是分配在栈上的,通过三条movl指令把12个字节写到栈上
char b[] = "Hello world";
// c并没有在栈上分配存储空间,而是直接存在eax 寄存器里,这就是register 关键字的作用
register int c = 50;
// 分配在.bss段, d.2054
static int d;
printf("Hello world %d\n", c);
return 0;
}
查看方法
gcc main.c -g
readelf -a a.out
objdump -dS a.out
存储类修饰符
-
static,用它修饰的变量的存储空间是静态分配的,用它修饰的文件作用域的变量或函数 具有Internal Linkage。
-
auto,用它修饰的变量在函数调用时自动在栈上分配存储空间,可以省略不写。
-
register,用register 修饰的变量会尽可能分配一个专门的寄存器来存储。现在一般编译器的优化都做得很好了,它自己会想办法有效地利用CPU的寄存 器,所以现在register 关键字也用得比较少了。
-
extern,不是用来修 饰变量的,而是定义一个类型名。