编译器C的全局变量,静态和字符串文字的地址在哪里?

时间:2014-04-12 15:50:56

标签: c linux 32-bit elf

首先我读了地址是.data和.text持有字符串文字(加上我想的机器代码)之后在其他一篇文章中有人说它已经改变了,并且更长的字符串文字存在于.text但是.rodata而不是(它是我的铿锵编译器输出)。但是.data内容与我在C程序中的printf地址不匹配。

假设这个C程序:

static int a;
int main()
{
    printf("my address = %p\n", &a);
    return 0;
}

此C程序的输出:

 $ ./a.out
my address = 0x804a01c

然后是.data部分的内容:

$ objdump -s -j .data a.out

a.out:     file format elf32-i386

Contents of section .data:
 804a00c 00000000 00000000 

此内容中没有0x804a01c。地址在哪里?

2 个答案:

答案 0 :(得分:5)

  

首先我读了地址是在.data和.text中保存字符串文字(加上机器代码,我猜)在其他文章之后有人说它已经改变了,并且更长的字符串文字存在于.text但是.rodata而不是

由编译器决定放置字符串文字的位置(不是机器代码)。

大多数现代编译器会将字符串文字放入.rodata部分,该部分通常链接到第一个PT_LOAD段,以及.text.ctors和其他只读部分。

  

此内容中没有0x804a01c。地址在哪里?

.bss。如果您希望a驻留在.data中,则需要对其进行初始化。 E.g。

static int a = 42;
  

例如,可以将字符串文字放入.rodata并将其地址放入.data吗?

不确定

cat t.c
const char string_literal[] = "abcdefgh";       // in .rodata
const char *p_string_literal = string_literal;  // in .data
int main() { return 0; }

gcc -m32 t.c
readelf -x.rodata a.out

Hex dump of section '.rodata':
  0x08048488 03000000 01000200 61626364 65666768 ........abcdefgh
  0x08048498 00
                                 .
readelf -x.data a.out

Hex dump of section '.data':
  0x0804a008 00000000 00000000 90840408          ............

注意:string_literal - 0x08048490的地址在.data中拼写为“向后”,因为x86为little-endian

答案 1 :(得分:1)

具有静态存储分配的变量,即静态和全局变量,在数据段或bss段中分配,具体取决于它们是0初始化(bss段)还是不是(数据段)。

默认情况下,未初始化的静态数据始终为0初始化。因此,

static int a;

默认初始化为0,它进入bss段。字符串文字是只读数据,通常存储在文本段中。