为什么使用NOExcept时Xcode生成更多指令
这是一个琐碎的程序,使用C ++ 11在Intel Mac上编辑,
#include <iostream>
void show() //noexcept
{
std::cout << "Hello, World!\n";
}
int main(int argc, const char * argv[])
{
show();
return 0;
}
我一直在检查“ NOEXCEPT”在调试模式和发布(优化)模式下使用“ NOEXCEPT”时的代码生成差。
在调试模式下,如果没有NOExcept预选赛,我会获得以下显示功能的说明:
0x100003280 <+0>: pushq %rbp
0x100003281 <+1>: movq %rsp, %rbp
0x100003284 <+4>: movq 0xd75(%rip), %rdi ; (void *)0x00007fff96d36760: std::__1::cout
0x10000328b <+11>: leaq 0xcc2(%rip), %rsi ; "Hello, World!\n"
0x100003292 <+18>: callq 0x100003e2c ; symbol stub for: std::__1::basic_ostream<char.....
0x100003297 <+23>: popq %rbp
0x100003298 <+24>: retq
非常明显 - 创建堆栈帧,设置呼叫cout,用堆栈框架完成并返回。
但是,如果我删除“ noexcept”,那么我会得到以下内容:
0x100003240 <+0>: pushq %rbp
0x100003241 <+1>: movq %rsp, %rbp
0x100003244 <+4>: subq $0x10, %rsp
0x100003248 <+8>: movq 0xdb1(%rip), %rdi ; (void *)0x00007fff96d36760: std::__1::cout
0x10000324f <+15>: leaq 0xcee(%rip), %rsi ; "Hello, World!\n"
0x100003256 <+22>: callq 0x100003e0c ; symbol stub for: std::__1::basic_ostream<char....
0x10000325b <+27>: jmp 0x100003260 ; <+32> at main.cpp:14:1
0x100003260 <+32>: addq $0x10, %rsp
0x100003264 <+36>: popq %rbp
请注意额外的减法(第三行)和反向添加(第二行)。更好奇的是JMP指令,它跳到下一行。
问题
- 为什么要使用Noexcept生成额外的代码 - 我认为如果您保证堆栈不需要解开
- 该JMP指令的目的是什么?
提前致谢
Here's a trivial program, compiled on Intel Mac using C++11
#include <iostream>
void show() //noexcept
{
std::cout << "Hello, World!\n";
}
int main(int argc, const char * argv[])
{
show();
return 0;
}
I've been examining the difference in code generation when 'noexcept' is used or not used both in debug mode and release (optimized) mode.
In debug mode, without the noexcept qualifier, I get the following instructions for the show function:
0x100003280 <+0>: pushq %rbp
0x100003281 <+1>: movq %rsp, %rbp
0x100003284 <+4>: movq 0xd75(%rip), %rdi ; (void *)0x00007fff96d36760: std::__1::cout
0x10000328b <+11>: leaq 0xcc2(%rip), %rsi ; "Hello, World!\n"
0x100003292 <+18>: callq 0x100003e2c ; symbol stub for: std::__1::basic_ostream<char.....
0x100003297 <+23>: popq %rbp
0x100003298 <+24>: retq
Very obvious - create stack frame, set up the call to cout, finish with stack frame and return.
However, if I uncomment 'noexcept' then I get the following:
0x100003240 <+0>: pushq %rbp
0x100003241 <+1>: movq %rsp, %rbp
0x100003244 <+4>: subq $0x10, %rsp
0x100003248 <+8>: movq 0xdb1(%rip), %rdi ; (void *)0x00007fff96d36760: std::__1::cout
0x10000324f <+15>: leaq 0xcee(%rip), %rsi ; "Hello, World!\n"
0x100003256 <+22>: callq 0x100003e0c ; symbol stub for: std::__1::basic_ostream<char....
0x10000325b <+27>: jmp 0x100003260 ; <+32> at main.cpp:14:1
0x100003260 <+32>: addq $0x10, %rsp
0x100003264 <+36>: popq %rbp
Note the extra subtraction (third line) and the reverse addition (second last line). More curious is the jmp instruction which just jumps to the next line.
Questions
- Why is extra code being generated with noexcept - I thought there would be less if you're guaranteeing that the stack doesn't need to be unwound
- What's the purpose of that jmp instruction?
Thanks in advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论