为什么函数地址与静态全局变量或动态分配变量的地址几乎相同?下面是演示代码:
#include <stdio.h>
#include <stdlib.h>
int global_var;
int global_var1;
int global_var2;
static int st_var = 3;
void func()
{
return;
}
int main(void)
{
int x;
int* x_m = malloc(sizeof(int));
printf("Malloc: %pn", x_m);
printf("Local: %pn", &x);
printf("Function: %pn", &func);
printf("Global: %pn", &global_var);
printf("Global: %pn", &global_var1);
printf("Global: %pn", &global_var2);
printf("Static: %pn", &st_var);
free(x_m);
return 0;
}
Output:
Malloc: 0x55bede9ce2a0
Local: 0x7ffdbc67b25c
Function: 0x55bede7151a9
Global: 0x55bede718024
Global: 0x55bede718030
Global: 0x55bede718020
Static: 0x55bede718010
有人可以解释一下吗?因为我认为只有全局和静态变量被存储在.bss
段中。
这是因为,通常,ELF可执行文件的.text
部分(包含函数代码)和.bss
部分彼此"相对接近"映射。
您可以使用readelf
进行检查:
$ gcc prog.c
$ readelf -S a.out
There are 29 section headers, starting at offset 0x1ac0:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
...
[14] .text PROGBITS 00000000000007e0 000007e0
0000000000000302 0000000000000000 AX 0 0 16
...
[24] .bss NOBITS 0000000000201010 00001010
0000000000000010 0000000000000000 WA 0 0 8
...
您可以从上面的"地址"字段中看到.text
和.bss
,当程序运行时,它们将被加载0x201010-0x7e0 = 0x200830
字节到虚拟内存中。
在任何情况下,这并不意味着您的代码位于.bss
部分中或变量位于.text
部分中。它们分为两个不同但"相对接近"的部分。
两者之间的距离是任意的,ELF规范没有真正的最小或最大要求。如果您确实需要,可以编写自己的链接器脚本,将它们放在更远的地方。