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

cod*_*eim 22 c++ x86 assembly

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

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

}

Address: 0x013C4F10
void print() {
  ...
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

013C4F10 E9 C7 3F 00 00   jmp         print (013C1429h) 
Run Code Online (Sandbox Code Playgroud)

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

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

Rap*_*tor 20

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

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


Bah*_*bar 6

我想在这里冒险,但它可能会启用编辑并继续.

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