2

为什么这行得通?我认为全局数据在编译时被“初始化”(编译器以 obj 文件格式保存到 .global 部分为空字节,因此当该部分加载到内存中时,它被初始化为空)。那么,如果编译器在运行时不知道函数在内存中的位置,那么如何初始化指向函数地址的指针呢?

#include <iostream>

void vypis();

int neco;
int * bla = &neco;
void (*vypis_ptr)() = vypis;

int main(int argc, const char * argv[])
{

}

void vypis() {

}
4

1 回答 1

4

我删除了多余的包含,iostream以便您的源代码实际上编译为 C 并在我的系统上将其编译为名为 vypis 的可执行文件。这是我发现的:

$ nm vypis | fgrep vypis
00000000004004d0 T vypis
0000000000600888 D vypis_ptr

所以,vypis一个函数,在“文本”部分是一个全局变量,而vypis_ptr一个指向函数的指针,在“数据”部分是一个全局变量。

数据部分中的对象具有存储在可执行文件中的值,我可以vypis_ptr通过使用objdump.

$ objdump -d -j .data vypis

vypis:     file format elf64-x86-64


Disassembly of section .data:

0000000000600878 <__data_start>:
        ...

0000000000600880 <__dso_handle>:
        ...

0000000000600888 <vypis_ptr>:
  600888:       d0 04 40 00 00 00 00 00                             ..@.....

0000000000600890 <bla>:
  600890:       a8 08 60 00 00 00 00 00                             ..`.....

在这里我们可以看到该值4004d0存储在其中,vypis_ptr但这正是 的vypis输出中显示的位置nm

于 2013-03-10T11:21:52.783 回答