我正在尝试学习C++和x86之间的关系,并一直在寻找一些C++代码的相应汇编指令。但是引起我注意的是,下一条指令似乎有多个JMP。这不就是浪费空间和时钟周期吗?
源代码非常简单,只是教科书中的一个简单游戏。
// Lost Fortune
// A personalized adventure!
#include <iostream>
#include <string>
using std::cout;
using std::cin;
using std::endl;
using std::string;
int main()
{
const int GOLD_PIECES = 900;
int adventurers, killed, survivors;
string leader;
// Get info.
cout << "Welcome fo Lost Fortune\n\n";
cout << "Please enter the following for your personalized adventure\n";
cout << "Enter a number: ";
cin >> adventurers;
cout << "Enter a number, smaller than the first: ";
cin >> killed;
survivors = adventurers - killed;
cout << "Enter your last name: ";
cin >> leader;
// Tell story.
cout << "\nA brave group of " << adventurers << " set out on a quest ";
cout << "-- in search of the lost treasure of the Ancient Dwarves. ";
cout << "The group was led by that legendary rogue, " << leader << ".\n";
cout << "\n Along the way, a bang of marauding ogres ambushed the party. ";
cout << "All fought bravely under the command of " << leader;
cout << ", and the ogres were defeated, but at a cost. ";
cout << "Of the adventurers, " << killed << " were vanquished, ";
cout << "leaving just " << survivors << " in the group.\n";
cout << "\nThe party was about to give up all hope. ";
cout << "But while laying the deceased to rest, ";
cout << "they stumbled upon the buried fortune. ";
cout << "So the adventurers split " << GOLD_PIECES << " gold pieces. ";
cout << leader << " held on to the extra " << (GOLD_PIECES % survivors);
cout << " pieces to keep things fair of course.\n";
return 0;
}
该组件的摘录如下。请注意,有几个JMP转到下一条指令,地址为00002053、00002076等。如果有帮助,这些JMP的操作码为E9 00 00 00 00。
00002035 mov eax, dword [ebp+var_64] ; CODE XREF=_main+148
00002038 lea ecx, dword [eax-0x1f91+0x3c60] ; "Welcome fo Lost Fortune\\n\\n"
0000203e mov edx, esp
00002040 mov dword [edx+4], ecx
00002043 mov ecx, dword [eax-0x1f91+__ZNSt3__14coutE_400c] ; __ZNSt3__14coutE_400c
00002049 mov dword [edx], ecx
0000204b call imp___symbol_stub___ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc ; std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<< <std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*)
00002050 mov dword [ebp+var_74], eax
00002053 jmp loc_2058
loc_2058:
00002058 mov eax, dword [ebp+var_64] ; CODE XREF=_main+211
0000205b lea ecx, dword [eax-0x1f91+0x3c7a] ; "Please enter the following for your personalized adventure\\n"
00002061 mov edx, esp
00002063 mov dword [edx+4], ecx
00002066 mov ecx, dword [eax-0x1f91+__ZNSt3__14coutE_400c] ; __ZNSt3__14coutE_400c
0000206c mov dword [edx], ecx
0000206e call imp___symbol_stub___ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc ; std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<< <std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*)
00002073 mov dword [ebp+var_78], eax
00002076 jmp loc_207b
loc_207b:
0000207b mov eax, dword [ebp+var_64] ; CODE XREF=_main+246
0000207e lea ecx, dword [eax-0x1f91+0x3cb6] ; "Enter a number: "
00002084 mov edx, esp
00002086 mov dword [edx+4], ecx
00002089 mov ecx, dword [eax-0x1f91+__ZNSt3__14coutE_400c] ; __ZNSt3__14coutE_400c
0000208f mov dword [edx], ecx
00002091 call imp___symbol_stub___ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc ; std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<< <std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*)
00002096 mov dword [ebp+var_7C], eax
00002099 jmp loc_209e
loc_209e:
0000209e mov eax, esp ; CODE XREF=_main+281
000020a0 lea ecx, dword [ebp+var_44]
000020a3 mov dword [eax+4], ecx
000020a6 mov ecx, dword [ebp+var_64]
000020a9 mov edx, dword [ecx-0x1f91+__ZNSt3__13cinE_4008] ; __ZNSt3__13cinE_4008
000020af mov dword [eax], edx
000020b1 call imp___symbol_stub___ZNSt3__113basic_istreamIcNS_11char_traitsIcEEErsERi ; std::__1::basic_istream<char, std::__1::char_traits<char> >::operator>>(int&)
000020b6 mov dword [ebp+var_80], eax
000020b9 jmp loc_20be
为什么编译器会这样做?任何帮助是极大的赞赏 :)
最佳答案
在不进行优化的情况下进行编译时,编译器的工作重点是生成易于调试且与原始源代码尽可能接近的代码,而不是运行速度很快的代码。
优化时(例如,使用-O3
),编译器的工作是使代码快速运行,并且不会像您观察到的那样对JMP
进行愚蠢的操作。
优化的代码运行速度可能更快,但是调试起来却极为困难。因此,如果您打算调试代码以查找错误,则几乎总是首选未优化的版本。
关于c++ - x86-为什么编译器在下一条指令中插入看似毫无意义的JMP?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45428952/