当前位置: 首页 > news >正文

门户网站建设和检务公开自查百度收录的网站

门户网站建设和检务公开自查,百度收录的网站,最新网站建设,网页编辑职业规划if else嵌套 这次来研究if else嵌套在汇编中的表现形式,本次以获取三个数中最大的数这个函数为例子,分析if else的汇编形式 求三个数中的最大值 首先贴上代码: #include "stdafx.h"int result0; int getMax(int i,int j,int k)…

if else嵌套

这次来研究if else嵌套在汇编中的表现形式,本次以获取三个数中最大的数这个函数为例子,分析if else的汇编形式

求三个数中的最大值

首先贴上代码:

#include "stdafx.h"int result=0;
int getMax(int i,int j,int k){if(i>j){if(i>k){return i;}else{return k;}}else{if(j>k){return j;}else{return k;}}
}int main(int argc, char* argv[])
{result=getMax(1,2,3);printf("%d\n",result);result=getMax(1,3,2);printf("%d\n",result);result=getMax(2,1,3);printf("%d\n",result);result=getMax(2,3,1);printf("%d\n",result);result=getMax(3,1,2);printf("%d\n",result);result=getMax(3,2,1);printf("%d\n",result);return 0;
}

先验证执行的结果是正确的:

在这里插入图片描述

确认可以函数是可以取出三个数的最大值的,于是开始分析该函数

为方便观看,将多余的验证删去,直接改为

getMax(1,2,3);

在这里插入图片描述

汇编代码

然后我们观察汇编代码

函数外部

28:       getMax(1,2,3);
0040D7C8   push        3
0040D7CA   push        2
0040D7CC   push        1
0040D7CE   call        @ILT+10(func) (0040100f)
0040D7D3   add         esp,0Ch

依次压入参数,然后调用函数,最后再堆栈外平衡,重点在函数内部,进去看看

函数内部

7:    int getMax(int i,int j,int k){
0040D760   push        ebp
0040D761   mov         ebp,esp
0040D763   sub         esp,40h
0040D766   push        ebx
0040D767   push        esi
0040D768   push        edi
0040D769   lea         edi,[ebp-40h]
0040D76C   mov         ecx,10h
0040D771   mov         eax,0CCCCCCCCh
0040D776   rep stos    dword ptr [edi]
8:        if(i>j){
0040D778   mov         eax,dword ptr [ebp+8]
0040D77B   cmp         eax,dword ptr [ebp+0Ch]
0040D77E   jle         getMax+32h (0040d792)
9:            if(i>k){
0040D780   mov         ecx,dword ptr [ebp+8]
0040D783   cmp         ecx,dword ptr [ebp+10h]
0040D786   jle         getMax+2Dh (0040d78d)
10:               return i;
0040D788   mov         eax,dword ptr [ebp+8]
0040D78B   jmp         getMax+42h (0040d7a2)
11:           }else{
12:               return k;
0040D78D   mov         eax,dword ptr [ebp+10h]
0040D790   jmp         getMax+42h (0040d7a2)
13:           }
14:
15:       }else{
16:           if(j>k){
0040D792   mov         edx,dword ptr [ebp+0Ch]
0040D795   cmp         edx,dword ptr [ebp+10h]
0040D798   jle         getMax+3Fh (0040d79f)
17:               return j;
0040D79A   mov         eax,dword ptr [ebp+0Ch]
0040D79D   jmp         getMax+42h (0040d7a2)
18:           }else{
19:               return k;
0040D79F   mov         eax,dword ptr [ebp+10h]
20:           }
21:       }
22:   }
0040D7A2   pop         edi
0040D7A3   pop         esi
0040D7A4   pop         ebx
0040D7A5   mov         esp,ebp
0040D7A7   pop         ebp
0040D7A8   ret

函数内部有不少代码是用来保护现场 初始化堆栈 恢复现场的,这里将其过滤掉,看判断语句:

判断语句

8:        if(i>j){
0040D778   mov         eax,dword ptr [ebp+8]
0040D77B   cmp         eax,dword ptr [ebp+0Ch]
0040D77E   jle         getMax+32h (0040d792)
9:            if(i>k){
0040D780   mov         ecx,dword ptr [ebp+8]
0040D783   cmp         ecx,dword ptr [ebp+10h]
0040D786   jle         getMax+2Dh (0040d78d)
10:               return i;
0040D788   mov         eax,dword ptr [ebp+8]
0040D78B   jmp         getMax+42h (0040d7a2)
11:           }else{
12:               return k;
0040D78D   mov         eax,dword ptr [ebp+10h]
0040D790   jmp         getMax+42h (0040d7a2)
13:           }
14:
15:       }else{
16:           if(j>k){
0040D792   mov         edx,dword ptr [ebp+0Ch]
0040D795   cmp         edx,dword ptr [ebp+10h]
0040D798   jle         getMax+3Fh (0040d79f)
17:               return j;
0040D79A   mov         eax,dword ptr [ebp+0Ch]
0040D79D   jmp         getMax+42h (0040d7a2)
18:           }else{
19:               return k;
0040D79F   mov         eax,dword ptr [ebp+10h]
20:           }
21:       }
22:   }

参数分析

在这里插入图片描述

i>j

先来看看i>j的反汇编语句

0040D778   mov         eax,dword ptr [ebp+8]
0040D77B   cmp         eax,dword ptr [ebp+0Ch]
0040D77E   jle         getMax+32h (0040d792)

比较第一个参数和第二个参数

jle:jump less equal,小于等于则跳转(有符号数)

跳转地址:0040d792

16:           if(j>k){
0040D792   mov         edx,dword ptr [ebp+0Ch]

i>k

9:            if(i>k){
0040D780   mov         ecx,dword ptr [ebp+8]
0040D783   cmp         ecx,dword ptr [ebp+10h]
0040D786   jle         getMax+2Dh (0040d78d)

比较第一个和第三个参数

jle:jump less equal,小于等于则跳转(有符号数)

跳转地址:0040d78d

11:           }else{
12:               return k;
0040D78D   mov         eax,dword ptr [ebp+10h]
0040D790   jmp         getMax+42h (0040d7a2)

可以分析出,如果第一个参数小于等于第三个参数则跳转到0040D78D,并将第三个参数赋值给eax作为返回值,这条线路为(k>i>j)

否则执行返回指令,将第一个参数赋给eax作为返回值,这条线路为(i>j且i>k)

10:               return i;
0040D788   mov         eax,dword ptr [ebp+8]
0040D78B   jmp         getMax+42h (0040d7a2)

j>k

16:           if(j>k){
0040D792   mov         edx,dword ptr [ebp+0Ch]
0040D795   cmp         edx,dword ptr [ebp+10h]
0040D798   jle         getMax+3Fh (0040d79f)

比较第二个和第三个参数

jle:jump less equal,小于等于则跳转(有符号数)

跳转地址:0040d79f

18:           }else{
19:               return k;
0040D79F   mov         eax,dword ptr [ebp+10h]

可以分析出,如果第二个参数小于等于第三个参数则跳转到0040D79F,并将第三个参数赋值给eax作为返回值,这条线路为(i<=j<=k)

否则返回执行返回命令,将第二个参数赋值给eax作为返回值,这条线路为(i<=j且k<=j)

17:               return j;
0040D79A   mov         eax,dword ptr [ebp+0Ch]
0040D79D   jmp         getMax+42h (0040d7a2)

总结

不难发现,三个数求最大值,只需两两比较就可以得出结果

分析if else的关键在于观察涉及的参数和jcc语句

此案例中就是直接采取了cmp 外加 jle来进行分支的选择和跳转

因为不符合条件的才要跳转走,所以在条件比较中,是大于的比较如i>j,所使用的汇编为jle 小于等于的比较

不按套路比较

此次案例并不能代表所有情况,实际分析要具体看情况来采取分析,有的程序可能就是不按套路出牌,先看看按套路出牌的程序,然后我们自己来模拟个不按套路的

正常套路

拿两个数的比较为例

#include "stdafx.h"
int getMax2(int i,int j){if(i>j){return i;}else{return j;}
}
int main(int argc, char* argv[])
{getMax2(1,2);return 0;
}

先看一般的汇编代码:

9:        if(i>j){
0040D778   mov         eax,dword ptr [ebp+8]
0040D77B   cmp         eax,dword ptr [ebp+0Ch]
0040D77E   jle         getMax2+25h (0040d785)
10:           return i;
0040D780   mov         eax,dword ptr [ebp+8]
0040D783   jmp         getMax2+28h (0040d788)
11:       }else{
12:           return j;
0040D785   mov         eax,dword ptr [ebp+0Ch]
13:       }
14:   }

依旧是采用cmp 和 jle来进行判断,和套路一致

不按套路

完整代码

#include "stdafx.h"
int __declspec(naked) myGetMax(int i,int j){__asm{                                //保留调用前堆栈push ebp//提升堆栈mov ebp,espsub esp,0x40//保护现场push ebxpush esipush edi//初始化提升的堆栈,填充缓冲区mov eax,0xCCCCCCCCmov ecx,0x10lea edi,dword ptr ds:[ebp-0x40]rep stosd//函数核心功能//取出参数mov eax,dword ptr ds:[ebp+8]//比较参数cmp eax,[ebp+0xC]jge _retmov eax,[ebp+0xC]
_ret://恢复现场pop edipop esipop ebx//降低堆栈mov esp,ebppop ebp                //返回ret }
}
int main(int argc, char* argv[])
{int result=myGetMax(1,2);printf("%d\n",result);result=myGetMax(4,3);printf("%d\n",result);return 0;
}

功能代码分析

这里截取出我们自己实现比较的那段代码

                //函数核心功能//取出参数mov eax,dword ptr ds:[ebp+8]//比较参数cmp eax,[ebp+0xC]jge _retmov eax,[ebp+0xC]
_ret://恢复现场pop edipop esipop ebx//降低堆栈mov esp,ebppop ebp                //返回ret 

首先我们这里将第一个参数赋值给eax

然后比较eax和第二个参数,也就是比较第一个参数和第二个参数

这边使用的就不是jle而是jge了

jge:jump greater equal,即大于等于则跳转

前面已经将第一个参数赋值给了eax,而eax又是作为返回值来传递的

当第一个参数大于等于第二个参数时,就可以直接返回了

如果不是则不跳转,执行下面的将第二个参数赋值给eax作为返回值

这里注意到我在汇编中自己定义了一个段:_ret,来作为跳转的地址来使用

最后测试一下结果:

在这里插入图片描述

可以正确得到两个数中的最大值

http://www.ds6.com.cn/news/61005.html

相关文章:

  • 建设手机银行app下载长沙seo优化推广公司
  • 太原公司网站建设全面落实疫情防控优化措施
  • 做百度排名推广有哪些网站seo线上培训机构
  • 阿里云网站建设——部署与发布如何写软文
  • 正规网站建设报价阿里云搜索引擎
  • 乐清定制网站建设商务软文写作
  • wordpress模板适合做什么站怎样做企业推广
  • 谷歌广告代理商杭州seo渠道排名
  • 怎样做网站外部链接客户引流的最快方法是什么
  • 智能建站系统下载优化设计三年级上册语文答案
  • 网站怎么做本地测试工具郑州本地seo顾问
  • seo做的比较好的网站的几个特征简单免费制作手机网站
  • 自适应式电影网站模板学编程的正规学校
  • 有区域名和主机怎么做网站互联网营销师培训班
  • 什么网站可以做ui兼职百度网页游戏中心
  • seo推广需要网站吗长沙网络推广营销
  • 网站建设公司哪家好磐石网络真好人工智能培训机构
  • 昆明网站排名优化公司中央电视台新闻联播
  • wordpress 语言设置中文南沙seo培训
  • 一站式网站建设方案计算机培训短期速成班
  • 网站怎么做来卖东西福建seo顾问
  • 做网站公司工资淘宝网页版
  • 宜章网站建设百度浏览器下载安装
  • 那些网站反爬做的好口碑营销方案怎么写
  • 西安专业网站建设公司seo推广seo技术培训
  • 广州网站开发制作seo引擎优化是什么
  • 网站上的链接怎么做的线上推广活动有哪些
  • 平面设计师磨刀石百度快速seo优化
  • 网站被做镜像什么意思可以全部免费观看的软件
  • 免费创一个网站活动推广文案