用汇编中查看常见的控制流
这篇文章用汇编查看c/c++中常见的控制流。
1. if else
在汇编中主要用cmp指令比较两个数,然后利用jz/jnz实现逻辑的跳转。
首先我们看下cmp指令的功能
| CMP结果 | ZF | CF |
| 目的<源 | 0 | 1 |
| 目的>源 | 0 | 0 |
| 目的=源 | 1 | 0 |
对于有符号数,我们常用jnz表示不相等则跳,jle表示小于则跳,我们可以看下如下列子:
int a = 4, b =5; if (a == 0) a = 8; else if (a > b) a = 9; else a = 10; return 0;
看看其对应的汇编源码:
//int a = 4, b =5; 0119181E mov dword ptr [a],4 01191825 mov dword ptr [b],5 //if (a == 0) 0119182C cmp dword ptr [a],0 01191830 jne wmain+3Bh (119183Bh) // a = 8; 01191832 mov dword ptr [a],8 01191839 jmp wmain+53h (1191853h) //else if (a > b) 0119183B mov eax,dword ptr [a] 0119183E cmp eax,dword ptr [b] 01191841 jle wmain+4Ch (119184Ch) // a = 9; 01191843 mov dword ptr [a],9 //else 0119184A jmp wmain+53h (1191853h) // a = 10; 0119184C mov dword ptr [a],0Ah
代码很简单, 看上去是不言而喻的, 就不过多解释了。
有时我们会直接判断函数的返回值是不是为true.
bool fun1()
{
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
int a =0;
if (fun1())
a++;
return 0;
}
下面来看下其汇编源码有什么不同:
int a =0; 0089184E mov dword ptr [a],0 if (fun1()) 00891855 call fun1 (8911C2h) 0089185A movzx eax,al //函数返回在al中,然后将高位扩展为0 0089185D test eax,eax //判断eax 为0还是1 0089185F je wmain+3Ah (89186Ah) a++; 00891861 mov eax,dword ptr [a] 00891864 add eax,1 00891867 mov dword ptr [a],eax
恩,还是很简单。这里在说下test的用法。
test 对每对数据执行隐含的与操作,并设置相应的标志位。但是不修改目的操作数。如:
00100101
00001001 --->test
00000001---->结果为1, ZF = 0;
2. switch case 语句
switch case 语句实际上是多个if else 的应用。我们可以看下如下代码:
int a = 4;
switch(a)
{
case 0:
a++;
break;
case 1:
a--;
break;
case 3:
break;
default:
a =10;
}
return 0;
可以看下对应的汇编源码:
//int a = 4;
0036181E mov dword ptr [a],4
//switch(a)
00361825 mov eax,dword ptr [a]
00361828 mov dword ptr [ebp-0D0h],eax
0036182E cmp dword ptr [ebp-0D0h],0
00361835 je wmain+4Bh (36184Bh) //如a==0,则跳到36184B指令
00361837 cmp dword ptr [ebp-0D0h],1
0036183E je wmain+56h (361856h) //如a==1,则跳到361856h指令
00361840 cmp dword ptr [ebp-0D0h],3
00361847 je wmain+61h (361861h) //如a==0,则跳到36186指令
00361849 jmp wmain+63h (361863h) //只要到我这里了,都跳到361863
{
//case 0:
// a++;
0036184B mov eax,dword ptr [a]
0036184E add eax,1
00361851 mov dword ptr [a],eax
// break;
00361854 jmp wmain+6Ah (36186Ah)
//case 1:
// a--;
00361856 mov eax,dword ptr [a]
00361859 sub eax,1
0036185C mov dword ptr [a],eax
// break;
0036185F jmp wmain+6Ah (36186Ah)
//case 3:
// break;
00361861 jmp wmain+6Ah (36186Ah)
//default:
// a =10;
00361863 mov dword ptr [a],0Ah
}

浙公网安备 33010602011771号