函数地址与其他变量地址几乎相同

  • 本文关键字:地址 变量 其他 函数 c
  • 更新时间 :
  • 英文 :


为什么函数地址与静态全局变量或动态分配变量的地址几乎相同?下面是演示代码:

#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规范没有真正的最小或最大要求。如果您确实需要,可以编写自己的链接器脚本,将它们放在更远的地方。

最新更新