C语言反汇编选择语句(一)

1、选择语句

(1)、if语句

示例代码:

#include "stdafx.h"

int main(int argc, char* argv[])
{
	printf("Hello World!\n");

	int a,b,temp;
	a = 4;
	b = 3;
	if( a < b )
	{
		//将a和b的值互换
		temp = a;
		a = b;
		b = temp;
	}
	
	printf("%d=%d",a,b);

	printf("end\n");
	return 0;
}

总体反汇编代码:

10:       int a,b,temp;
11:       a = 4;
0040F9C5 C7 45 FC 04 00 00 00 mov         dword ptr [ebp-4],4
12:       b = 3;
0040F9CC C7 45 F8 03 00 00 00 mov         dword ptr [ebp-8],3
13:       if( a > b )
0040F9D3 8B 45 FC             mov         eax,dword ptr [ebp-4]
0040F9D6 3B 45 F8             cmp         eax,dword ptr [ebp-8]
0040F9D9 7E 12                jle         main+4Dh (0040f9ed)
14:       {
15:           //将a和b的值互换
16:           temp = a;
0040F9DB 8B 4D FC             mov         ecx,dword ptr [ebp-4]
0040F9DE 89 4D F4             mov         dword ptr [ebp-0Ch],ecx
17:           a = b;
0040F9E1 8B 55 F8             mov         edx,dword ptr [ebp-8]
0040F9E4 89 55 FC             mov         dword ptr [ebp-4],edx
18:           b = temp;
0040F9E7 8B 45 F4             mov         eax,dword ptr [ebp-0Ch]
0040F9EA 89 45 F8             mov         dword ptr [ebp-8],eax
19:       }
20:
21:       printf("%d=%d",a,b);
0040F9ED 8B 4D F8             mov         ecx,dword ptr [ebp-8]
0040F9F0 51                   push        ecx
0040F9F1 8B 55 FC             mov         edx,dword ptr [ebp-4]
0040F9F4 52                   push        edx
0040F9F5 68 18 60 42 00       push        offset string "%d<%d" (00426018)
0040F9FA E8 11 17 FF FF       call        printf (00401110)
0040F9FF 83 C4 0C             add         esp,0Ch

分步解析:

 10:       int a,b,temp;
11:       a = 4;
0040F9C5 C7 45 FC 04 00 00 00 mov         dword ptr [ebp-4],4
12:       b = 3;
0040F9CC C7 45 F8 03 00 00 00 mov         dword ptr [ebp-8],3

如上代码可见,在定义变量时并没有为变量分配空间,而是赋值的时候分配。例如

11:       a = 4;
0040F9C5 C7 45 FC 04 00 00 00 mov         dword ptr [ebp-4],4

将a的值mov如一个内存单元中。

13:       if( a > b )
0040F9D3 8B 45 FC             mov         eax,dword ptr [ebp-4]
0040F9D6 3B 45 F8             cmp         eax,dword ptr [ebp-8]
0040F9D9 7E 12                jle         main+4Dh (0040f9ed)

首先是将存储a值的内存单元赋值给寄存器eax,然后将eax与存储b值的内存单元进行cmp比较。(为什么不直接cmp 两个内存单元呢?因为cmp指令不同同时比较两个内存单元)
当jle(小于或等于)时(即a<=b),跳转到 “main+4Dh”内存单元,从main开始向后偏移4Dh个地址(即内存单元(0040f9ed) ),刚好是 if {} 代码块的下一条指令。
因此,当 a<=b 时,程序跳过 if代码块执行下一条语句。

15:           //将a和b的值互换
16:           temp = a;
0040F9DB 8B 4D FC             mov         ecx,dword ptr [ebp-4]
0040F9DE 89 4D F4             mov         dword ptr [ebp-0Ch],ecx
17:           a = b;
0040F9E1 8B 55 F8             mov         edx,dword ptr [ebp-8]
0040F9E4 89 55 FC             mov         dword ptr [ebp-4],edx
18:           b = temp;
0040F9E7 8B 45 F4             mov         eax,dword ptr [ebp-0Ch]
0040F9EA 89 45 F8             mov         dword ptr [ebp-8],eax

上面为交换两个数的代码,可知,之前没有被赋值即没有分配内存空间的temp顺位分配到【ebp-0Ch】的内存单元中了。并且每次变量赋值时,都是先将一个变量赋值给寄存器,然后再将寄存器的值赋给另外一个变量。

if综述:

例如:if(a>b)语句,先将a赋值给寄存器,然后将寄存器与存储b相关的值进行cmp比较,jle(小于等于)的的话,就直接跳到 if代码块的下一个执行语句。(如果为if( a<b ),那么跳转语句为 jge(大于等于) ,如果是if(a=b),那么跳转语句为je(等于))

跳转指令机器码:
直接跳 JMP EB 八位
直接跳 JMP E9 十六位
直接标志转移(8位寻址)
指令格式 机器码 测试条件 如…则转移  
指令格式 机器码 测试条件 如…则转移
JC 72 C=1 有进位 JNS 79 S=0 正号
JNC 73 C=0 无进位 JO 70 O=1 有溢出
JZ/JE 74 Z=1 零/等于 JNO 71 O=0 无溢出
JNZ/JNE 75 Z=0 不为零/不等于 JP/JPE 7A P=1 奇偶位为偶

汇编代码实现:

#include "stdafx.h"

int main(int argc, char* argv[])
{
	printf("Hello World!\n");
	char* str = "a=%d,b=%d\n";
	
	_asm{
		push 4
		push 3
		mov eax, [esp+4]
		mov ebx, [esp+0]
		cmp eax, ebx
		jge swap		
		xchg eax, ebx
		
swap:	push ebx
		push eax
		push str
		call printf
		add esp, 12
		jmp end
		
end:	nop

	}

	/*
	int a,b,temp;
	a = 4;
	b = 3;
	if( a < b )
	{
		//将a和b的值互换
		temp = a;
		a = b;
		b = temp;
	}
	*/
//	printf("%d=%d",a,b);

	printf("end\n");
	return 0;
}
(2)、if–else语句

示例代码:


```cpp
int main(int argc, char* argv[])
{
	printf("Hello World!\n");

	int a;
	a = 4;
	if( a < 5 )
	{
		a = 5;
	}
	else
		a = 10;
	
	printf("%d\n",a);
	printf("end\n");
	return 0;
}

总体反汇编:

10:       int a;
11:       a = 4;
0040F9C5 C7 45 FC 04 00 00 00 mov         dword ptr [ebp-4],4
12:       if( a < 5 )
0040F9CC 83 7D FC 05          cmp         dword ptr [ebp-4],5
0040F9D0 7D 09                jge         main+3Bh (0040f9db)
13:       {
14:           a = 5;
0040F9D2 C7 45 FC 05 00 00 00 mov         dword ptr [ebp-4],5
15:       }
16:       else
0040F9D9 EB 07                jmp         main+42h (0040f9e2)
17:           a = 10;
0040F9DB C7 45 FC 0A 00 00 00 mov         dword ptr [ebp-4],0Ah
18:
19:       printf("%d\n",a);
0040F9E2 8B 45 FC             mov         eax,dword ptr [ebp-4]
0040F9E5 50                   push        eax
0040F9E6 68 24 50 42 00       push        offset string "a=%d,b=%d\n" (00425024)
0040F9EB E8 20 17 FF FF       call        printf (00401110)
0040F9F0 83 C4 08             add         esp,8
20:
12:       if( a < 5 )
0040F9CC 83 7D FC 05          cmp         dword ptr [ebp-4],5
0040F9D0 7D 09                jge         main+3Bh (0040f9db)

由上面汇编可知,在 if(a<5) 时,类似于一个单独的 if 语句,cmp进行条件比较,jge进行对应条件的转移地址。

16:       else
0040F9D9 EB 07                jmp         main+42h (0040f9e2)

如上为else反汇编语句,简答的一个jmp跳址,刚好 跳出else代码块。
综述:if - else语句其实就是先cmp条件比较,然后 jge决定是否符合条件(类似于 if条件语句);而else语句就是一个简单的 jmp 语句,用来跳出 else 代码块。

(3)、if-else if -else语句

示例代码:

int main(int argc, char* argv[])
{
	printf("Hello World!\n");

	int a;
	a = 4;
	if( a < 5 )
	{
		a = 5;
	}
	else if(a = 5)
		a = 5;
	else
		a = 10;
	
	printf("%d\n",a);

	printf("end\n");
	return 0;
}

总体反汇编:
在这里插入图片描述
由上可知:if - else if - else语句:
第一个 if(a<5) 语句:首先先cmp进行条件比较,然后 jge 判断是否符合条件。
而第二个else if( a=5 )语句:可以分解成else + if( a=5 ),所以反汇编代码第一句类似于else 为 jmp+地址,当满足if条件时,则执行if代码块,只有当执行完if代码块后,才会开始执行else语句,而else汇编代码为jmp+地址,所以便直接跳出了else if和后面的else代码块,然后执行最后的printf语句。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值