什么时候变量放在`.rdata`部分而不是`.text`部分?

Gan*_*esh 8 c linker gcc

我试图理解.rdatasection vs .textsection 的含义.我正在尝试一个简单的程序,如下所示

int main()
{
    const int a = 10;
    printf("%d\n", a);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我构建并转储map文件gcc -o a.out sample.c -Wl,Map,test.map并搜索时sample.o,我发现以下分配

.text          0x0040138c       0x34 sample.o
.data          0x00402000        0x0 sample.o
.rdata         0x00403064        0x8 sample.o
.eh_frame      0x00404060       0x38 sample.o
.bss           0x00405020        0x0 sample.o
Run Code Online (Sandbox Code Playgroud)

现在,如果我稍微修改我的程序以使a全局变量为

const int a = 10;
int main()
{
     printf("%d\n", a);
     return 0;
}
Run Code Online (Sandbox Code Playgroud)

通过重复上述相同的步骤,我发现分配如下

.text          0x0040138c       0x2c sample.o
.data          0x00402000        0x0 sample.o
.rdata         0x00403064        0xc sample.o
.eh_frame      0x00404060       0x38 sample.o
.bss           0x00405020        0x0 sample.o
Run Code Online (Sandbox Code Playgroud)

其中清楚地显示a被分配为.rdata部分为

.rdata         0x00403064        0xc sample.o
               0x00403064            a
Run Code Online (Sandbox Code Playgroud)

从这些实验中,我理解它们global const被分配到.rdata部分,而.text部分尺寸已经下降.因此,我认为在第一个例子中a分配了.text部分.

我的问题是:

  1. 是的范围const考虑在确定它的位置的变量.rdata.text

  2. 从我的实验中,我观察到变量在分配到.text段中时需要8个字节,而在部分中则需要4个字节.rdata.造成这种差异的原因是什么?

  3. 如果局部const变量太多,则相应.text部分的大小将显着增加.在这种情况下,推荐的编程实践是什么?

提前谢谢了.

nne*_*neo 8

在第一种情况下,变量被声明为局部变量.它具有"自动"存储持续时间,这意味着它在封闭范围的末尾消失.由于存储持续时间,它不能永久占用任何内存(无论如何都是如此const).因此,它通常存储在堆栈中或寄存器中.

在第二种情况下,变量被声明为全局变量.它具有静态存储持续时间,因此它在程序的生命周期内持续存在.这可以被存储在很多地方,如.data,.bss,.text,或.rdata(和.rodata).

.data通常用于具有一些预定义(非零)内容的可写静态数据,例如全局int foo = 42;..bss用于初始化为零(或未初始化)的可写静态数据.rdata用于常量静态数据,如字符串和const变量.当然,这些用途都是"一般"的,并且可能因编译器而异.

那么为什么.text在第一种情况下变大?这是因为编译器必须生成一些额外的指令来加载10到堆栈或寄存器中.