5

起始地址可以从函数名中得到,如何找到函数的结束地址?我在面试中被问到这个问题:

考虑我编写的函数 f() 已经越过文本部分并开始写入相邻部分(数据部分)。我该如何处理这种情况?他还补充说我应该通过 C 代码来处理它。我不应该看到符号映射文件并获取地址。

4

4 回答 4

7

使用 GCC,您可以使用&&运算符(是 - &&,不是&)获取标签的地址。
这可以按如下方式使用:

void f(void) {
    printf("Start %p End %p\n", f, &&f_end);
    f_end: return;
}

这不会给你确切的结局,因为标签后面有一些尾声代码,但我认为它足以作为面试答案。

于 2012-06-18T18:15:15.757 回答
2

C 标准不保证存在函数的结束地址之类的东西。

在实践中,函数不一定是一块连续的内存,而是可以重叠,或者被代码优化器分割成几块。

出于这个原因,没有办法在运行时找到它。

此外,不能保证您从 GetProcAddress 或通过获取函数的地址(对于函数指针)获得的“起始地址”与代码的实际位置有任何关系。

函数指针的所有保证是,如果您通过地址调用该函数将被执行。它不保证代码实际上驻留在那里。例如,它可能只是一个 thunk 的地址。

于 2012-06-18T15:11:04.513 回答
1

您不能使用语言本身,C 没有公开函数的“大小”概念。

您可能能够做的是检查程序的二进制文件,并解析符号表等等。

于 2012-06-18T15:10:22.317 回答
0

您的编译器可能会生成一个汇编列表文件,而您的链接器可能会生成一个映射文件。这些可以让您查看手动执行特定功能的时间。不确定是否需要从 C 程序本身确定大小。

于 2012-06-18T15:14:39.523 回答