首先我读的地址是在.data和.text保存string文字(加上机器代码,我想)之后,在别的文章有人说,它已经改变,而较长的string文字居住在.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
。 地址在哪里?
首先我读的地址是在.data和.text中保存字符串文字(加上机器代码,我想)后,在别人的文章有人说,它已经改变了,更长的字符串文字生活在文本,但.rodata而不是
编译器决定在哪里放置字符串文字( 不是机器代码)。
大多数现代编译器都会将字符串文字放入.rodata
节中,该节通常链接到第一个PT_LOAD
段中,连同.text
, .ctors
和其他只读节。
这个内容没有0x804a01c。 地址在哪里?
在.bss
。 如果你想要a
驻留在.data
,你需要初始化它。 例如
static int a = 42;
例如,可以将字符串文字放在
.rodata
并将其地址放入.data
?
当然:
cat tc const char string_literal[] = "abcdefgh"; // in .rodata const char *p_string_literal = string_literal; // in .data int main() { return 0; } gcc -m32 tc 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 。
具有静态存储分配的变量(即静态变量和全局变量)根据数据段或bss段是否初始化(bss段)或不数据段(数据段)分配在数据段或bss段中。
未初始化的静态数据默认情况下始终为0
初始化。 因此,
static int a;
默认初始化为0
,并进入bss段。 字符串文字是只读数据,通常存储在文本段中。