C++反汇编学习笔记(五)各种算数运算的工作形式(4)
1、 条件表达式(?:)
表达式1?表达式2:表达式3
条件表达式的构成应该是先判断再选择。但编译器优化后未必是这样。当表达式1为一个常量时,编译器会在编译期间得到答案,将不会有条件表达式存在。
转换方案:
① :表达式2和表达式3都是常量且两者的差值为1;
② :其他
先说3个指令:cmove和cmovle,cmovne,条件传送指令,应该还有类似的指令,暂时没找到这些指令的资料,下面是根据汇编代码逆推的,不知道对不对,望高手指导!
Cmp ........
Cmove/cmovle/cmovne reg1,reg2;
根据前面指令对标志位的影响:
Cmove:如果zf=0,将reg2的值传送到reg1中
Cmovle:如果zf!=of或zf=1,则将reg2的值传送到reg1中
Cmovne:如果zf=0,则将reg2的值传送到reg1中。
Debug版和release版差别很大,debug为调试方便,使用的依然是条件判断的分支结构。
C++源码 |
Debug版 |
Release版 |
#include <iostream> using namespace std; int main() { int a, b; cin >> a >> b; //① cout << (a == 5 ? 5 : 6); //② cout << (a == 6 ? 3 : 10); cout << (a <= 7 ? 2 : 11); cout << (a ? 8: b);
system("pause"); return 0; } |
#include <iostream> using namespace std; int main() { .............略 int a, b; cin >> a >> b; ...............略 //① cout << (a == 5 ? 5 : 6); 003D5EB6 cmp dword ptr [a],5 003D5EBA jne main+68h (03D5EC8h) 003D5EBC mov dword ptr [ebp-0E0h],5 003D5EC6 jmp main+72h (03D5ED2h) 003D5EC8 mov dword ptr [ebp-0E0h],6 003D5ED2 mov esi,esp 003D5ED4 mov eax,dword ptr [ebp-0E0h] 003D5EDA push eax 003D5EDB mov ecx,dword ptr ds:[3E10A8h] cout << (a == 5 ? 5 : 6); 003D5EE1 call dword ptr ds:[3E1094h] 003D5EE7 cmp esi,esp 003D5EE9 call __RTC_CheckEsp (03D1339h) //② cout << (a == 6 ? 3 : 10); 003D5EEE cmp dword ptr [a],6 003D5EF2 jne main+0A0h (03D5F00h) 003D5EF4 mov dword ptr [ebp-0E0h],3 003D5EFE jmp main+0AAh (03D5F0Ah) 003D5F00 mov dword ptr [ebp-0E0h],0Ah 003D5F0A mov esi,esp 003D5F0C mov eax,dword ptr [ebp-0E0h] 003D5F12 push eax 003D5F13 mov ecx,dword ptr ds:[3E10A8h] 003D5F19 call dword ptr ds:[3E1094h] 003D5F1F cmp esi,esp 003D5F21 call __RTC_CheckEsp (03D1339h) cout << (a <= 7 ? 2 : 11); 003D5F26 cmp dword ptr [a],7 003D5F2A jg main+0D8h (03D5F38h) 003D5F2C mov dword ptr [ebp-0E0h],2 003D5F36 jmp main+0E2h (03D5F42h) 003D5F38 mov dword ptr [ebp-0E0h],0Bh 003D5F42 mov esi,esp 003D5F44 mov eax,dword ptr [ebp-0E0h] 003D5F4A push eax 003D5F4B mov ecx,dword ptr ds:[3E10A8h] 003D5F51 call dword ptr ds:[3E1094h] 003D5F57 cmp esi,esp 003D5F59 call __RTC_CheckEsp (03D1339h) cout << (a ? 8: b); 003D5F5E cmp dword ptr [a],0 cout << (a ? 8: b); 003D5F62 je main+110h (03D5F70h) 003D5F64 mov dword ptr [ebp-0E0h],8 003D5F6E jmp main+119h (03D5F79h) 003D5F70 mov eax,dword ptr [b] 003D5F73 mov dword ptr [ebp-0E0h],eax 003D5F79 mov esi,esp 003D5F7B mov ecx,dword ptr [ebp-0E0h] 003D5F81 push ecx 003D5F82 mov ecx,dword ptr ds:[3E10A8h] 003D5F88 call dword ptr ds:[3E1094h] 003D5F8E cmp esi,esp 003D5F90 call __RTC_CheckEsp (03D1339h)
system("pause"); ............略 return 0; 003D5FAC xor eax,eax } ..........略 |
#include <iostream> using namespace std; int main() { 012612A0 push ebp 012612A1 mov ebp,esp 012612A3 sub esp,0Ch 012612A6 mov eax,dword ptr ds:[01264000h] 012612AB xor eax,ebp 012612AD mov dword ptr [ebp-4],eax int a, b; cin >> a >> b; 012612B0 mov ecx,dword ptr ds:[1263038h] int a, b; cin >> a >> b; 012612B6 lea eax,[b] 012612B9 push eax 012612BA lea eax,[a] 012612BD push eax 012612BE call dword ptr ds:[1263028h] 012612C4 mov ecx,eax 012612C6 call dword ptr ds:[1263028h] //① cout << (a == 5 ? 5 : 6); 012612CC mov ecx,dword ptr ds:[126303Ch] 012612D2 xor eax,eax 012612D4 cmp dword ptr [a],5 //如果a==5,则将eax置0,否则将eax置1,然后eax+5, //最后输出eax+5的结果 012612D8 setne al 012612DB add eax,5 012612DE push eax 012612DF call dword ptr ds:[1263024h] //② cout << (a == 6 ? 3 : 10); 012612E5 cmp dword ptr [a],6 012612E9 mov ecx,3 012612EE mov eax,0Ah //根据cmp最ZF位的影响,如果ZF=1,则表示a==6,将ecx(3)传送到eax中进行输出,否则保留eax的值(10)进行输出 012612F3 cmove eax,ecx 012612F6 mov ecx,dword ptr ds:[126303Ch] 012612FC push eax 012612FD call dword ptr ds:[1263024h] cout << (a <= 7 ? 2 : 11); 01261303 cmp dword ptr [a],7 01261307 mov ecx,2 0126130C mov eax,0Bh //这里判断的是ZF和OF,如果ZF=1(相等)或ZF!=OF(溢出,即a<7),则将ecx(2)的值传送到eax中进行输出,否则保留eax的值(11)进行输出 01261311 cmovle eax,ecx 01261314 mov ecx,dword ptr ds:[126303Ch] 0126131A push eax 0126131B call dword ptr ds:[1263024h] cout << (a ? 8: b); 01261321 cmp dword ptr [a],0 cout << (a ? 8: b); 01261325 mov ecx,8 0126132A mov eax,dword ptr [b] //整理是判断a的真假,看得是ZF标志位 0126132D cmovne eax,ecx 01261330 mov ecx,dword ptr ds:[126303Ch] 01261336 push eax 01261337 call dword ptr ds:[1263024h]
system("pause"); 0126133D push 126319Ch 01261342 call dword ptr ds:[12630C4h] return 0; } ........略 |
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。