本文共 1470 字,大约阅读时间需要 4 分钟。
3.3.2 数据段和只读数据段
.data段保存的是那些已经初始化了的全局静态变量和局部静态变量。前面的SimpleSection.c代码里面一共有两个这样的变量,分别是global_init_varabal与static_var。这两个变量每个4个字节,一共刚好8个字节,所以".data"这个段的大小为8个字节。
SimpleSection.c里面我们在调用"printf"的时候,用到了一个字符串常量"%d\n",它是一种只读数据,所以它被放到了".rodata"段,我们可以从输出结果看到".rodata"这个段的4个字节刚好是这个字符串常量的ASCII字节序,最后以\0结尾。
".rodata"段存放的是只读数据,一般是程序里面的只读变量(如const修饰的变量)和字符串常量。单独设立".rodata"段有很多好处,不光是在语义上支持了C++的const关键字,而且操作系统在加载的时候可以将".rodata"段的属性映射成只读,这样对于这个段的任何修改操作都会作为非法操作处理,保证了程序的安全性。另外在某些嵌入式平台下,有些存储区域是采用只读存储器的,如ROM,这样将".rodata"段放在该存储区域中就可以保证程序访问存储器的正确性。
另外值得一提的是,有时候编译器会把字符串常量放到".data"段,而不会单独放在".rodata"段。有兴趣的读者可以试着把SimpleSection.c的文件名改成SimpleSection.cpp,然后用各种MSVC编译器编译一下看看字符串常量的存放情况。
$ objdump -x -s -d SimpleSection.o …… Sections: Idx Name Size VMA LMA File off Algn 1 .data 00000008 00000000 00000000 00000090 2**2 CONTENTS, ALLOC, LOAD, DATA 3 .rodata 00000004 00000000 00000000 00000098 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA …… Contents of section .data: 0000 54000000 55000000 T...U... Contents of section .rodata: 0000 25640a00 %d.. …… |
我们看到".data"段里的前4个字节,从低到高分别为0x54、0x00、0x00、0x00。这个值刚好是global_init_varabal,即十进制的84。global_init_varabal是个4字节长度的int类型,为什么存放的次序为0x54、0x00、0x00、0x00而不是0x00、0x00、0x00、0x54?这涉及CPU的字节序(Byte Order)的问题,也就是所谓的大端(Big-endian)和小端(Little-endian)的问题。关于字节序的问题本书的附录有详细的介绍。而最后4个字节刚好是static_init_var的值,即85。
来源:http://book.51cto.com/art/200904/120997.htm
转载地址:http://ceaei.baihongyu.com/