反汇编--C语言(判断与分支)

if  else条件判断 C语言实现:

void Conditional(int c){
 if (c>0 && c<10)
 {
  printf("c大于0,小于10");
 }
 else if(c>10 && c<100)
 {
  printf("c大于10,小于100");
 }
 else{
  printf("其它");
 }
}
void main(){
 int num=5;
 Conditional(num);
 return 0;
}

反汇编

1: void Conditional(int c){
00401020 push ebp
00401021 mov ebp,esp
00401023 sub esp,40h
00401026 push ebx
00401027 push esi
00401028 push edi
00401029 lea edi,[ebp-40h]
0040102C mov ecx,10h
00401031 mov eax,0CCCCCCCCh
00401036 rep stos dword ptr [edi]
2: if (c>0 && c<10)
//先比较变量C和0
00401038 cmp dword ptr [ebp+8],0
//小于或者等于则跳转到00401053处执行else if 部分
0040103C jle Conditional+33h (00401053)
//然后比较变量C和10(0AH)
0040103E cmp dword ptr [ebp+8],0Ah
//大于 或者等于则跳转到00401053处执行esle if部分
00401042 jge Conditional+33h (00401053)
3: {
4: printf("c大于0,小于10");
//将字符串压入栈中   这里的汉字采用了GBK编码方式 x是十六进制数  b4\f3 =大 d3\da=于 ...
00401044 push offset string "c\xb4\xf3\xd3\xda0,\xd0\xa1\xd3\xda10" (00422038)
//调用printf子程序,打印字符串
00401049 call printf (00401100)
//调用完printf子程序后恢复esp栈顶指向。
0040104E add esp,4
5: }
6: else if(c>10 && c<100)
//else if 在开始处有一个无条件跳转指令,跳转到0040107B判断结束处,阻止前面的分支执行完后跳到这个分支执行。
00401051 jmp Conditional+5Bh (0040107b)
//这里同上面的if比较相同
00401053 cmp dword ptr [ebp+8],0Ah
00401057 jle Conditional+4Eh (0040106e)
00401059 cmp dword ptr [ebp+8],64h
0040105D jge Conditional+4Eh (0040106e)
7: {
8: printf("c大于10,小于100");
0040105F push offset string "c\xb4\xf3\xd3\xda10,\xd0\xa1\xd3\xda100" (00422024)
00401064 call printf (00401100)
00401069 add esp,4
9: }
10: else{
//最后的else 同样是有一个无条件跳转指令 跳转到判断结束处,阻止前面的分支执行完后跳到这个分支执行。
0040106C jmp Conditional+5Bh (0040107b)
11: printf("其它");
0040106E push offset string "\xc6\xe4\xcb\xfc" (0042201c)
00401073 call printf (00401100)
00401078 add esp,4
12: }
13: }
//恢复各个寄存器的值,检查esp的值后程序返回
0040107B pop edi
0040107C pop esi
0040107D pop ebx
0040107E add esp,40h
00401081 cmp ebp,esp
00401083 call __chkesp (00401180)
00401088 mov esp,ebp
0040108A pop ebp
0040108B ret

switch条件判断C语言实现:

void Conditional(int c){
 switch(c)
 {
 case 0: printf("c>0");
 case 1: {
   printf("c>10 && c<100");
   break;
   }
 default: printf("c>10 && c<100");

 }
}
void main(){
 int num=5;
 Conditional(num);
 return 0;
}

反汇编

1: void Conditional(int c){
00401020 push ebp
00401021 mov ebp,esp
00401023 sub esp,44h
00401026 push ebx
00401027 push esi
00401028 push edi
00401029 lea edi,[ebp-44h]
0040102C mov ecx,11h
00401031 mov eax,0CCCCCCCCh
00401036 rep stos dword ptr [edi]

2: switch(c)
3: {
//这里将变量c的值送入eax中
00401038 mov eax,dword ptr [ebp+8]
//将eax的值复制到  [ebp-4]处
0040103B mov dword ptr [ebp-4],eax
//把这个值和 0 进行比较
0040103E cmp dword ptr [ebp-4],0
//相等则跳转到case 0处执行
00401042 je Conditional+2Ch (0040104c)
//继续和1进行比较
00401044 cmp dword ptr [ebp-4],1
//相等则跳转到case 1处执行
00401048 je Conditional+39h (00401059)
//这里有一个无条件跳转   如果以上条件都不满足直接跳转到00401068  default处
0040104A jmp Conditional+48h (00401068)
4: case 0: printf("c>0");
0040104C push offset string "c>0" (00422024)
00401051 call printf (00401100)
00401056 add esp,4
5:
6: case 1: {
7: printf("c>10 && c<100");
00401059 push offset string "c>10 && c<100" (00422fcc)
0040105E call printf (00401100)
00401063 add esp,4
//这里break  用的 jmp 无条件指令  直接跳出
8: break;
00401066 jmp Conditional+55h (00401075)
9: }
10:
11: default: printf("c>10 && c<100");
00401068 push offset string "c>10 && c<100" (00422fcc)
0040106D call printf (00401100)
00401072 add esp,4
//后面基本相同省略

反汇编--C语言(判断与分支),布布扣,bubuko.com

时间: 2024-12-28 11:08:47

反汇编--C语言(判断与分支)的相关文章

[笔记]C#基础入门(十五)——C#中判断和分支

走到岔路口,需要选择方向.编写程序也会遇到判断和分支.请看下面的流程图,判断手机账户余额是否不足10元,如果不足给出提示: 这个程序在"balance<10"这个步骤出现了分支,"balance<10"被称为判断( bool 类型),当判断为 true 时,执行左边的分支,输出提示:当判断为 false 时,执行右边的分支,不输出任何内容. 在C#中,这个结构成为条件结构,通常用 if 关键字来实现: namespace Test { class Pro

反汇编--C语言(循环)

Debug (调试版)  汇编和 Release (发行版) 汇编的认识 调试版基本不优化,发行版则一般都优化到极致. Windows驱动开发中,一般称为Check版本和Free版本 我们暂时只研究Debug(调试版) for循环C实现: int func(int a,int b) { int c=a+b; int i; for(i=0;i<50;i++){ c=c+i; } return c; } void main(){ int sum; sum=func(2,5); return 0; }

C语言判断系统数据大/小端存储方式

小端存储:数据的低位部分,存储于存储器的低地址空间里. 大端存储:数据的低位部分,存储于存储器的高地址空间里. 首先,一般PC数据存储方式是小端存储. 基本实现思想是:将存储器中所存的数据按字节以地址顺序输出,与存入数据的高低位进行比较,即得出结论. 实现方法一: 1 #include <stdio.h> 2 int main(void) 3 { 4 short int x; 5 char *arr; 6 7 x = 0x1122; 8 arr = (char *)&x; 9 10 i

使用C语言判断栈的方向

这一问题主要是如何判读出先后入栈的变量的地址大小,比如有a, b两个变量一先一后被定义,如果a的地址大于b的地址,则说明是以低地址方向增长的,反之,往高地址方向增长. 在写C程序的时候不能简单直接的定义两个变量来比较它们的地址大小,因为这样很有可能编译器会做优化,最终导致结果不真实.为避免这种编译器优化的情况,可以采用将变量定义到函数中,然后递归调用该函数.例如下面的代码: #include <stdio.h> static int stack_direction = 0; static vo

C语言中的分支结构

<A href="http://www.goodprogrammer.org/" target="blank">ios培训</A>------我的c语言笔记,期待与您交流! 现实生活中我们经常需要根据不同的条件做出不同的选择.程序设计中也需要根据条件来选择不同的程序进行处理,这称之为分支结构. C语言中控制分支结构的主要是if语句和switch语句.首先说说if语句: if语句的单分支结构形式:if(条件 e)  { 语句 s; }.当条件e

c语言判断某一年是否为闰年的各种实现程序代码

本文导语: c语言判断某一年是否为闰年的各种实现程序代码1.公历闰年计算原则(按一回归年365天5小时48分45.5秒)1)普通年能整除4且不能整除100的为闰年.(如2004年就是闰年,1900年不是闰年)2)世纪年能整除400的是闰年.(如2000年是闰年... c语言判断某一年是否为闰年的各种实现程序代码 1.公历闰年计算原则(按一回归年365天5小时48分45.5秒) 1)普通年能整除4且不能整除100的为闰年.(如2004年就是闰年,1900年不是闰年) 2)世纪年能整除400的是闰年

Linux环境下使用gcc编译,gdb反汇编C语言程序

使用虚拟机 VMware Workstation 10 Linux环境:Ubuntu 14.04 LTS Server amd64 我把过程截图如下. 首先是hello world程序: 备注: gcc -o 参数,指定生成程序文件名. gdb下,disas命令对应英文为disassembler,反汇编. 这里没有执行程序.如果想执行,会出现: [email protected]:~$./helloworld Hello World! [email protected]:~$ 当然,前面要加 .

使用C语言判断一个IP 地址是否为私有地址

参考:https://zhidao.baidu.com/question/191740827.html 私有IP地址范围:A: 10.0.0.0 10.255.255.255 10.0.0.0/8B: 172.16.0.0 172.31.255.255 172.16.0.0/12C: 192.168.0.0 192.168.255.255 192.168.0.0/16 在C语言中的 socket 结构体如下 struct sockaddr_in { short sin_family; USHOR

C语言判断“1000年—2000年”之间的闰年

判断是否为闰年的方法: ①.普通年能被4整除且不能被100整除的为闰年. ②.世纪年能被400整除的是闰年. ③.对于数值很大的年份,这年如果能整除3200,并且能整除172800则是闰年. 这里我们只讨论"1000年-2000年"之间的闰年,所以不用考虑③. C语言代码如下: # include <stdio.h> int main() {     int year;          for(year=1000; year<=2000; year++)  //fo