函数的地址不是实际的代码地址

时间:2010-03-21 00:35:05

标签: c++ assembly x86

在Visual Studio 2008(C ++)中调试一些代码,我注意到我的函数指针变量中的地址不是函数本身的实际地址。这是一个外部“C”函数。

int main() {
   void (*printaddr)(const char *) = &print; // debug shows printaddr == 0x013C1429

}

Address: 0x013C4F10
void print() {
  ...
}

获取函数地址的反汇编是:

   void (*printaddr)(const char *) = &print;
013C7465 C7 45 BC 29 14 3C 01 mov         dword ptr [printaddr],offset print (13C1429h) 

编辑:我在地址013C4F10查看了代码,编译器显然在该地址插入了“jmp”指令。

013C4F10 E9 C7 3F 00 00   jmp         print (013C1429h) 

实际上,.exe中的每个方法都有一个完整的跳转表。

有人可以解释为什么会这样做吗?它是一个调试“功能”吗?

3 个答案:

答案 0 :(得分:19)

这是由“增量链接”引起的。如果在编译器/链接器设置中禁用它,则跳转将消失。

http://msdn.microsoft.com/en-us/library/4khtbfyf(VS.80).aspx

答案 1 :(得分:6)

我会冒这个猜测,但可能会启用Edit-and-Continue

假设您需要重新编译该函数,您只需要更改间接表,而不是所有调用者。这将大大减少在执行“编辑并继续”功能时要执行的工作量。

答案 2 :(得分:2)

编译器在该地址处向实际方法插入“jmp”指令。

013C4F10 E9 C7 3F 00 00   jmp         print (013C1429h)

实际上,.exe中的每个方法都有一个完整的跳转表。

这是一项调试功能。当我切换到释放模式时,跳转表消失,地址确实是实际的功能地址。