您的位置:首页 > 娱乐 > 明星 > 金融理财网站建设方案_做一套品牌设计多少钱_seo搜索引擎优化实战_舆情监控系统

金融理财网站建设方案_做一套品牌设计多少钱_seo搜索引擎优化实战_舆情监控系统

2025/2/25 12:42:14 来源:https://blog.csdn.net/2401_85828611/article/details/143340354  浏览:    关键词:金融理财网站建设方案_做一套品牌设计多少钱_seo搜索引擎优化实战_舆情监控系统
金融理财网站建设方案_做一套品牌设计多少钱_seo搜索引擎优化实战_舆情监控系统

1.前置知识

switch的用法参见22.【C语言】选择结构之switch

附:《C语言程序与设计》 第四版对switch的解释

8995991a9e1443859c92ed5b60f2e0e7.jpeg

注意画红线的等值比较,下面会重点讲

2.C语言代码

运行环境:VS2010+Win32

sourcecode1

int main()
{int num=2;int c1=0;int c2=0;switch (num){case 1:c1=3;case 2:c2=1;}return 0;
}

sourcecode2

int main()
{int num=2;int c1=0;int c2=0;switch (num){case 1:c1=3;break;case 2:c2=1;break;}return 0;
}

3.反汇编分析

按F11进入调试模式,右击转到反汇编

d08ed8d49cc24d2484e45728111d37eb.png

sourcecode1的反汇编代码

int main()
{push        ebp  mov         ebp,esp  sub         esp,0E8h  push        ebx  push        esi  push        edi  lea         edi,[ebp-0E8h]  mov         ecx,3Ah  mov         eax,0CCCCCCCCh  rep stos    dword ptr es:[edi]  int num=2;mov         dword ptr [num],2  int c1=0;mov         dword ptr [c1],0  int c2=0;mov         dword ptr [c2],0  switch (num)mov         eax,dword ptr [num]  mov         dword ptr [ebp-0E8h],eax  cmp         dword ptr [ebp-0E8h],1  je          main+50h (2513A0h)  cmp         dword ptr [ebp-0E8h],2  je          main+57h (2513A7h)  jmp         main+5Eh (2513AEh)  {case 1:c1=3;mov         dword ptr [c1],3  case 2:c2=1;mov         dword ptr [c2],1  }return 0;xor         eax,eax  
}pop         edi  pop         esi  pop         ebx  mov         esp,ebp  pop         ebp  ret  

逐条分析

1.栈区初始化,内存按0xCCCCCCCC(dword)循环填充

 push        ebp  mov         ebp,esp  sub         esp,0E8h  push        ebx  push        esi  push        edi  lea         edi,[ebp-0E8h]  mov         ecx,3Ah  mov         eax,0CCCCCCCCh  rep stos    dword ptr es:[edi]  

2.变量的定义,赋初值

  int num=2;mov         dword ptr [num],2  int c1=0;mov         dword ptr [c1],0  int c2=0;mov         dword ptr [c2],0  

有关为什么用mov指令为变量初始化参见动态内存管理练习题的反汇编代码分析(底层),不是本文的重点

3.将参数num的写入内存

 mov         eax,dword ptr [num]  mov         dword ptr [ebp-0E8h],eax  

这个是mov eax,dword ptr [num]未执行前,各个寄存器的值

48a381b26e6849b5a387b4d9cc0abc88.png

当mov eax,dword ptr [num]执行后,再观察变动的寄存器的值

94b94a78e7774979a853a562f69c7656.png

EIP寄存器(Extend Instruction Pointer 扩展指令指针寄存器)的值+3,表明mov eax,dword ptr [num]机器码占3个字节,此时EIP指向下一条指令mov dword ptr [ebp-0E8h],eax机器码的第一个字节

不过EIP的值不是我们所关心的,注意看EAX的值为0000 0002

将这两个指令合在一起看

 mov         dword ptr [num],2 
;......mov         eax,dword ptr [num]  

等价为C语言的

dword ptr[num] = 2;
eax = dword ptr [num];

Q:为什么编译器不直接反汇编成下面的指令,从等价为C语言的eax = 2;呢?

 mov         eax,2 

A:这个是编译器的优化过程,和x86处理器的架构有一定关系,不做深究

 mov         dword ptr [ebp-0E8h],eax  

可以通过内存窗口观察mov的过程

ebp == 00F3FA80,00F3FA80-0E8==00F3F998

打开内存窗口,输入0x00F3F998f675c9f52d794a4cbddab149d4a627aa.png

deb4f0aa3b1e481386e51fbdd2907aab.png

发现从0x00F3F998开始,是VS开辟好的栈帧空间(以0xCC填充),等待写入数据 

指令mov dword ptr [ebp-0E8h],eax执行后,再次观察

以"dword+小端序"的形式写入eax的值

7e1c4f1dffc7470fa3384c3e6d9fe0dd.png

4.重点指令(cmp+je实现等值比较)的分析

cmp指令

格式:cmp dest,src

作用:比较dest和src的值,将比较后的结果写入标志寄存器(x86下的EFL:Extend FLags),但不改变dest和src原来的值

je指令

格式:je address(32位的地址)

作用:执行时,先去读ZF(Zero Flag)的值,如果ZF==1(说明dest和src的值相等),则转到address处执行,否则继续执行je的下一条指令

 cmp         dword ptr [ebp-0E8h],1  je          main+50h (2513A0h)  cmp         dword ptr [ebp-0E8h],2  je          main+57h (2513A7h)  jmp         main+5Eh (2513AEh)  

cmp dword ptr [ebp-0E8h],1 指令执行后,观察变动的寄存器的值,

果然EFL的值改变

c5d183b70b1143908cc330163ea50a27.png

执行je main+50h (2513A0h)时,并没有跳转到main+50h处继续执行,原因是dword ptr [ebp-0E8h]和1不相等

cmp dword ptr [ebp-0E8h],2 指令执行后,观察变动的寄存器的值,

果然EFL的值改变

6d85ebc336aa44cab7acb058cdbe024d.png

执行 je main+57h (2513A7h)时,由于dword ptr [ebp-0E8h]和2相等,则跳转到main+57h(即地址0x002513A7)处继续执行

50982fee781e4a1e9bac979e32dc8c37.png

可以通过内存窗口验证上述的说法

右击选择显示代码字节,内存窗口输入0x002513A7

470886989ee24318aa017e198d9afaaf.pngd5c267f14ffa4013b3edad9676984c23.png

256518836ef04e2c86a6e35544c6a391.png

注意到两处的机器码是吻合的,说法正确

5.程序main函数的返回,空间被销毁,交还给操作系统(非本文重点)

 xor         eax,eax  pop         edi  pop         esi  pop         ebx  mov         esp,ebp  pop         ebp  ret  

如果为sourcecode1的case后都添加break;反汇编指令是什么样的?

sourcecode2的反汇编代码

截取的部分代码

int num=2;mov         dword ptr [num],2  int c1=0;mov         dword ptr [c1],0  int c2=0;mov         dword ptr [c2],0  switch (num)mov         eax,dword ptr [num]  mov         dword ptr [ebp-0E8h],eax  cmp         dword ptr [ebp-0E8h],1  je          main+50h (7513A0h)  cmp         dword ptr [ebp-0E8h],2  je          main+59h (7513A9h)  jmp         main+60h (7513B0h)  {case 1:c1=3;break;mov         dword ptr [c1],3  jmp         main+60h (7513B0h)  case 2:c2=1;break;mov         dword ptr [c2],1  

大部分的分析过程和sourcecode1一样,不再赘述

如果加break;则在非最后的case处添加一个跳转指令(上方的case 2处没有jmp指令)

那 jmp main+60h (7513B0h) 跳转到哪里执行呢?

如果按C语言的逻辑分析,是跳出switch的结构,来到return 0;处执行

验证说法:

和之前的操作一样,找0x007513B0处的机器码,右击选择显示代码字节,内存窗口输入0x007513B0

2150b96b6f1444aeb938f2d1ed87ffd6.png

1c9b1ae326e94944a64773768cafd1f5.png

return 0;对应的机器码是33 C0,说法正确

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com