我试图了解.rdata部分与.text部分的含义。我正在尝试一个简单的程序,如下所示

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

当我通过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

现在,如果我稍稍修改程序以使a成为全局变量,则为
const int a = 10;
int main()
{
     printf("%d\n", a);
     return 0;
}

通过重复上述相同的步骤,我发现分配如下
.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

其中清楚地显示了a被分配为.rdata部分,如下所示:
.rdata         0x00403064        0xc sample.o
               0x00403064            a

从这些实验中,我了解到global const已分配到.rdata节中,而.text节的大小已减小。因此,我假设第一个示例中的a被分配到.text部分中。

我的问题是:
  • 在确定它在const.rdata中的位置时,是否考虑了.text变量的范围?
  • 从我的实验中,我发现将变量分配到.text部分时需要8个字节,而.rdata部分中则需要4个字节。产生这种差异的原因是什么?
  • 如果本地const变量太多,则相应.text节的大小将显着增加。在这种情况下,推荐的编程实践是什么?

  • 提前谢谢了。

    最佳答案

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

    在第二种情况下,该变量被声明为全局变量。它具有静态的存储期限,因此在程序的整个生命周期中都将持续存在。它可以存储在许多地方,例如.data.bss.text.rdata(或.rodata)。
    .data通常用于具有一些预定义(非零)内容的可写静态数据,例如全局int foo = 42;.bss用于初始化为零(或未初始化)的可写静态数据。 rdata用于常量静态数据,例如字符串和const变量。当然,这些用法都是“一般”的,并且随编译器的不同而不同。

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

    关于c - 什么时候将变量放在 `.rdata`部分而不是 `.text`部分中?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16025929/

    10-11 22:49
    查看更多