传统上,一个程序一般会有这几个段: .test, .data, .bss段。下面就来说一说各段的作用是什么,以此了解c语言中的各元素(函数和变量)是被放在哪一个段中的。
指令段:
地改写。
处理器所需加工的数据是放在.data,.bss,.rdata段的。当然,除了这几个段外,数据也可以来自堆和栈(这个之后再做讨论)。下面通过例子例子来了解各段中存放的是C语言中什么类型的数据。
eg:
#include<stdio.h> int main() { return(0); }
现在我们定义两个全局变量:
#include<stdio.h> int g_non=0x1234; int g_zero=0; int main() { return(0); }
此时发现,data和bss段大小发生了改变。对于初始化不为0的全局变量,编译器会把它放入data段,而对于初始化为0的全局变量,会被放入bss段。实际上,没有初始化的全局变量也像初始化为0的全局变量一样,放在bss段。
小端模式,低位在前,高位在后。
由于bss段中存放的数据是初始化为0或者没有初始化好的,所以不需要像data段那样存放在程序文件中。
至于data段数据的初始化,是引导加载器加载程序时,通过程序文件中data段的数据复制到所对应的内存地址空间,从而一次性完成所有变量的初始化。通过nm工具(使用nm之前不能使用trip命令哦),我们可以验证两个变量的所分配的段信息。
#include<stdio.h> int main() { static int g_non=0x123456; static int g_zero=0; return(0); }
对于静态局部变量,编译器为之分配的内存空间与全局变量是一样的。
data段大小为d,刚好13字节,正是字符串的所有字符的个数,包含结尾 。
现在增加const关键字:
#include<stdio.h> const char g_char[]="hello world!"; int main() { return(0); }