【发布时间】:2011-11-05 12:24:28
【问题描述】:
我正在编写一些低级代码,我注意到函数调用的一些不必要的间接级别,我根本不明白这种间接的原因是什么。这是揭示该行为的虚拟代码:
__declspec(noinline) int get_alignment(void * ptr)
{
return 1;
}
__declspec(noinline) int test123()
{
char buf[123];
return get_alignment(buf);
}
然后,当我在调试器中以 asm 模式 (Ctrl+F11) 单步执行函数 test() 中的代码时,我看到了:
__declspec(noinline) int test123() { 0041FA70 sub esp,7Ch 字符缓冲区[123]; 返回 get_alignment(buf); 0041FA73 lea eax,[esp] 0041FA76 推eax 0041FA77 调用 get_alignment (40A38Fh) } ... 获取对齐: 0040A38F jmp get_alignment (41FA60h) ... __declspec(noinline) int get_alignment(void * ptr) { 返回 1; 0041FA60 移动 eax,1 }所以,问题在于额外的间接级别: 获取对齐: 0040A38F jmp get_alignment (41FA60h)
WTF 是这样的吗?!我只是不明白,它不是从 dll 导入的函数,它是在可执行文件中定义的本地函数。该可执行文件经过各种优化(链接时间代码生成除外)编译。
如果我将static 添加到该get_alignment 的声明中,那么该额外的间接性就会消失。但我不是在寻找“修复”,我只是想了解为什么会有额外的跳跃!
在我的真实应用程序中,我实际上使用了一个用 .asm 文件编写的函数,但我只是不明白为什么会生成额外的跳转。似乎如果我在 C 模式(而不是 C++)中编译我的代码,那么我再也看不到那个级别的间接了......
任何人都可以对这种奇怪的行为有所了解吗?
谢谢!
【问题讨论】:
标签: visual-studio-2008 visual-c++ x86