用汇编中查看常见的控制流
来源:互联网 发布:ubuntu 开机自启动 编辑:程序博客网 时间:2024/06/18 04:51
这篇文章用汇编查看c/c++中常见的控制流。
1. if else
在汇编中主要用cmp指令比较两个数,然后利用jz/jnz实现逻辑的跳转。
首先我们看下cmp指令的功能
CMP结果ZFCF目的<源01目的>源00目的=源10对于有符号数,我们常用jnz表示不相等则跳,jle表示小于则跳,我们可以看下如下列子:
1
2
3
4
5
6
7
8
9
10
int
a = 4, b =5;
if
(a == 0)
a = 8;
else
if
(a > b)
a = 9;
else
a = 10;
return
0;
1
看看其对应的汇编源码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
bool
fun1()
{
return
true
;
}
int
_tmain(
int
argc, _TCHAR* argv[])
{
int
a =0;
if
(fun1())
a++;
return
0;
}
下面来看下其汇编源码有什么不同:
1
2
3
4
5
6
7
8
9
10
11
12
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 的应用。我们可以看下如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int
a = 4;
switch
(a)
{
case
0:
a++;
break
;
case
1:
a--;
break
;
case
3:
break
;
default
:
a =10;
}
return
0;
可以看下对应的汇编源码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//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
}
- 用汇编中查看常见的控制流
- 汇编中常见的错误
- 汇编中常见的一些错误信息
- 汇编中常见的错误2
- 汇编中常见的段代号
- X86汇编中常见的寄存器汇总
- 汇编中常见的一些错误信息
- 汇编中常见的一些错误信息
- 汇编中精妙的流程控制
- vs2008中查看汇编代码
- 如何在Source Insight中查看ARM的汇编代码
- 如何在Source Insight中查看ARM的汇编代码
- 常见的基本汇编书籍
- 常见的几个汇编指令
- neon的常见汇编命令
- 查看uboot的汇编代码
- ARM 反汇编的查看
- VS2013 查看汇编的方法
- 利用汇编查看C++函数调用
- interviewstreet - even tree
- Factorial hoj poj
- 产品需求背后的用户动机
- c/c++转java的一个注意点:对象和对象引用
- 用汇编中查看常见的控制流
- lesson1_05_Graphics
- 排序1---几种排序以及其时间复杂度
- 内存数据的分析
- Ubuntu一些有用的linux命令
- 关于23种设计模式的有趣见解
- 内存配置器alloc
- 神奇的__type_traits
- stl_config.h中和编译器相关的一些宏定义