为什么常量存储在C存储器映射中的文本段中?

Laa*_*vaa 3 c linux memory memory-management

您好请考虑下面的代码片段在Linux机器(64位)上用gcc编译,并带有相应的内存映射

#include <stdio.h>

int global = 2;

int main(void)
{
    int local = 0;

    return 0;
}

text       data     bss     dec     hex filename

1092        500      16    1608     648 mem
Run Code Online (Sandbox Code Playgroud)

这里因为有一个全局变量初始化为2.它存储在数据段中考虑使其成为const的情况,如下所示

#include <stdio.h>

int const global = 2;

int main(void)
{
    int local = 0;

    return 0;
}

text       data     bss     dec     hex filename
1096        496      16    1608     648 mem
Run Code Online (Sandbox Code Playgroud)

这里全局变量从数据段移动到文本段.

为什么它从数据移到文本段?

由于数据段分为读写区域,它应该存储在数据的读取区域中吗?

在代码中间初始化的未初始化的全局变量会发生什么?

zwo*_*wol 12

在一个现代化的体系,不断为只读数据保留的对象文件的一部分.该部分size在默认模式下与"文本"(程序代码)部分混为一谈,但您可以使它为您提供更多详细信息:

$ size test.o  # compiled from the code in the question
   text    data     bss     dec     hex filename
     58       0       0      58      3a test.o

$ size -A test.o
test.o  :
section           size   addr
.text                6      0
.data                0      0
.bss                 0      0
.rodata              4      0
.comment            29      0
.note.GNU-stack      0      0
.eh_frame           48      0
Total               87
Run Code Online (Sandbox Code Playgroud)

看到第一个命令生成的"文本"号又是怎样的总和.text,.rodata以及.eh_frame通过第二个问题产生的数字?

你可以告诉大家不断在.rodata.text使用objdump命令:

$ objdump -t test.o | grep -w global
0000000000000000 g     O .rodata    0000000000000004 global
Run Code Online (Sandbox Code Playgroud)

('g'表示全局,'O'表示'Object'而不是'F'表示Function.)

  • 有些常量甚至只在机器指令中.当你在C中编码`i = j + 3;`时,`3`常量很可能只在机器代码内部(不在`.rodata`段中). (2认同)