我已经看到它用于编程(特别是在C++领域)并且不知道它是什么.据推测它是一种设计模式,但我可能是错的.谁能举出一个很好的例子?
在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中的每个方法都有一个完整的跳转表.
有人可以解释为什么会这样做吗?这是一个调试"功能"吗?
我具有用于x64构建的以下程序:
void f1()
{
printf_s("in f1()\n");
}
void main(int argc, char** argv)
{
f1();
}
Run Code Online (Sandbox Code Playgroud)
我在F5调试运行的Visual Studio 2015中运行它。并检查反汇编代码:
为什么jmp红色矩形中无条件?
可以禁用它吗?
这是一个简单的程序:
void func()
{
printf("hello");
}
int main()
{
printf("%p",func);
func();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
踩到线printf("%p",func),我00F811AE打印在控制台上.
拆卸线func(),给我call _func (0F811AEh)- 到目前为止一切顺利.
但是拆解内容func,第一条指令出现在地址上00F813C0.
所以我"去看看"地址是什么00F811AE,我找到了jmp func (0F813C0h).
总结一下,似乎函数调用被编译为两个指令:
call _func (0F811AEh)
jmp func (0F813C0h)
Run Code Online (Sandbox Code Playgroud)
为什么VS2013编译器使用两条指令而不只是一条?
似乎一个人jmp会完成这项工作.我甚至要问这个因为我有一种感觉,其他编译器也以类似的方式进行(当然,取决于底层的HW架构).
谢谢