Switch条件语句

通过上面一篇了解了条件语句的使用,接下来就直接进行反汇编学习

#include <stdio.h>

void print()
{
int b = 1;
switch (b)
{
case 1:
printf("当前是1");
break;
case 2:
printf("当前是2");
break;
default:
printf("unKnow");
break;
}
} int main()
{ print();
return 0;
}

先f2在print()下个断点,然后我们进入反汇编窗口



然后我们再f11两下,跳两下,进入函数内部

00873840  push        ebp
00873841 mov ebp,esp
00873843 sub esp,0D0h
00873849 push ebx
0087384A push esi
0087384B push edi
0087384C lea edi,[ebp-0D0h]
00873852 mov ecx,34h
00873857 mov eax,0CCCCCCCCh
0087385C rep stos dword ptr es:[edi] 0087385E mov dword ptr [b],1
00873865 mov eax,dword ptr [b]
00873868 mov dword ptr [ebp-0D0h],eax
0087386E cmp dword ptr [ebp-0D0h],1
00873875 je print+42h (0873882h)
00873877 cmp dword ptr [ebp-0D0h],2
0087387E je print+51h (0873891h)
00873880 jmp print+60h (08738A0h)
00873882 push offset string "\xb5\xb1\xc7\xb0\xca\xc71" (0876B94h)
00873887 call _printf (08713B1h)
0087388C add esp,4
0087388F jmp print+6Dh (08738ADh)
00873891 push offset string "\xb5\xb1\xc7\xb0\xca\xc72" (0876BE4h)
00873896 call _printf (08713B1h)
0087389B add esp,4
0087389E jmp print+6Dh (08738ADh)
008738A0 push offset string "unKnow" (0876C0Ch)
008738A5 call _printf (08713B1h)
008738AA add esp,4 008738AD pop edi
008738AE pop esi
008738AF pop ebx
008738B0 add esp,0D0h
008738B6 cmp ebp,esp
008738B8 call __RTC_CheckEsp (087132Fh)
008738BD mov esp,ebp
008738BF pop ebp
008738C0 ret

我们的代码都是在缓冲区填充完数据之后的,才是真正的功能点

0087385E  mov         dword ptr [b],1        //把1赋值给b
00873865 mov eax,dword ptr [b] //把b给eax寄存器
00873868 mov dword ptr [ebp-0D0h],eax //把eax的值给 ebp-0D0h 这个地址上

接下来就开始进行比较了

0087386E  cmp         dword ptr [ebp-0D0h],1  //对比两个值
00873875 je print+42h (0873882h) //je是当两个数为相等的时候执行
00873877 cmp dword ptr [ebp-0D0h],2
0087387E je print+51h (0873891h)
00873880 jmp print+60h (08738A0h) //Jmp无条件跳转到 0x08738A0h 这个地址上

由上得知 eax=1 == 1,所以会跳到 0x0873882h 这个地址上面

00873882  push        offset string "\xb5\xb1\xc7\xb0\xca\xc71" (0876B94h)  //把字符串压入栈中
00873887 call _printf (08713B1h) //调用printf()函数打印出来
0087388C add esp,4 //栈顶提升4字节,也就是平栈
0087388F jmp print+6Dh (08738ADh) //直接跳到下面一段,完成功能执行
....
....
008738AD pop edi //恢复数据
008738AE pop esi //恢复数据
008738AF pop ebx //恢复数据
008738B0 add esp,0D0h
008738B6 cmp ebp,esp
008738B8 call __RTC_CheckEsp (087132Fh)
008738BD mov esp,ebp
008738BF pop ebp
008738C0 ret

?:运算符

#include <stdio.h>

void print()
{
int a = 10;
int c = a > 11 ? 10 : 11;
} int main()
{ print();
return 0;
}
00D43840  push        ebp
00D43841 mov ebp,esp
00D43843 sub esp,0DCh
00D43849 push ebx
00D4384A push esi
00D4384B push edi
00D4384C lea edi,[ebp-0DCh]
00D43852 mov ecx,37h
00D43857 mov eax,0CCCCCCCCh
00D4385C rep stos dword ptr es:[edi]
int a = 10;
00D4385E mov dword ptr [a],0Ah
int c = a > 11 ? 10 : 11;
00D43865 cmp dword ptr [a],0Bh
00D43869 jle print+37h (0D43877h)
00D4386B mov dword ptr [ebp-0DCh],0Ah
00D43875 jmp print+41h (0D43881h)
00D43877 mov dword ptr [ebp-0DCh],0Bh
00D43881 mov eax,dword ptr [ebp-0DCh]
00D43887 mov dword ptr [c],eax
}
00D4388A pop edi
00D4388B pop esi
00D4388C pop ebx
00D4388D mov esp,ebp
00D4388F pop ebp
00D43890 ret

和if语句没什么区别,就不写了,可以看看练习一下

C语言之 Switch和?:运算符的反汇编的更多相关文章

  1. 李洪强漫谈iOS开发[C语言-040]-switch case

    李洪强漫谈iOS开发[C语言-039]-switch case 补充:

  2. PROCESS_YIELD()宏和C语言的switch语句< contiki学习笔记之七>

    写在前面:  按照main()函数的代码一行一行的分析,该是看到了 etimer_process 这个位置.但是etimer_process实现里的一个宏 PROCESS_YIELD()引出了很多故事 ...

  3. Swift语言指南(九)--基本运算符

    原文:Swift语言指南(九)--基本运算符 运算符(operator)是用来检查,改变或合并值的一种特殊符号或短语.例如,加号运算符让两个数字相加(如:let i = 1 + 2),还有些更复杂的运 ...

  4. c语言的类型、运算符与表达式

    title: 2017-10-17c语言的类型.运算符与表达式 tags: c程序设计语言 grammar_cjkRuby: true --- 1.1 数据类型 char 字符型,一个字节 int 整 ...

  5. 选择语言之switch case

    程序语言-选择语言之switch   case 多选一,类似if    else if  else if  else 模版: Switch(选择条件) { Case(条件一)//相当于if Conso ...

  6. c语言基础表达式, 关系运算符, 逻辑运算符, 位运算符, 数据的取值范围, 分支结构(if...else, switch...case)

    1.表达式: 表达式的判断是有无结果(值), 最简单的表达式是一个常量或变量, 如:12, a, 3 + 1, a + b, a + 5 都是表达式 2.BOOL(布尔)数据类型: c语言中除了基本数 ...

  7. C语言的关键字,运算符,标识符

    关键字 数据类型修饰相关 auto按照自动的方式进行变量的存储 const定义常量或常参数 extern声明外部变量或函数 register指定变量的存储类型是寄存器变量 static指定变量的存储类 ...

  8. 2.2JAVA基础复习——JAVA语言的基础组成运算符和语句

    JAVA语言的基础组成有: 1.关键字:被赋予特殊含义的单词. 2.标识符:用来标识的符号. 3.注释:用来注释说明程序的文字. 4.常量和变量:内存存储区域的表示. 5.运算符:程序中用来运算的符号 ...

  9. JavaScript 基础 if switch 弹窗 运算符

    脚本语言最重要的几个部分: 数据类型 运算符 控制语句 数组  方法(函数) 一.基础知识 关键字:系统定义 有意义的名字如 background link 等 标识符:自己定 比如class的名字a ...

随机推荐

  1. SpringMVC执行流程和原理

    SpringMVC流程: 01.用户发送出请求到前端控制器DispatcherServlet. 02.DispatcherServlet收到请求调用HandlerMapping(处理器映射器). 03 ...

  2. Java源码赏析(四)Java常见注解

    元注解 @Target :标识注解的目标,默认为所有 ElementType.TYPE(用于类) ElementType.FIELD(用于域,包括enum) ElementType.METHOD(用于 ...

  3. Echarts山东省地图两级钻取、返回及济南合并莱芜地图

    Echarts3.0+jQuery3.3.1 山东省地图中济南市需要注意下,莱芜市已经和济南市合并,地图数据来源于地图选择器,获取山东省地图信息及各地市地图信息(JSON格式) //山东地图(第一级地 ...

  4. Redis小记(二)

    1.redis数据库 redis数据库属于内存数据库,若不将数据存到磁盘中,服务器进程退出,数据也会消失 redis所有数据库都保存在redisServer结构的db数组中,db数组的每一项都是一个r ...

  5. Spring AOP系列(三) — 动态代理之JDK动态代理

    JDK动态代理 JDK动态代理核心是两个类:InvocationHandler和Proxy 举个栗子 为便于理解,首先看一个例子: 希望实现这样一个功能:使用UserService时,只需关注自己的核 ...

  6. Hibernate4.3 HQL查询

    HQL:Hibernate专属语言,可以跨数据库 一.基本查询 1 public void testQuery(){ 2 Session session = HibernateUtils.getSes ...

  7. 给select赋值的一种方法

    做毕设遇到的问题,在update数据的时候,要先把原来的数据传递给前台,赋值给input等标签,但是啊,select标签没有value属性啊,所以在这里研究了一下,总结一个给select赋值的方法吧 ...

  8. matlab中colormap

    来源:https://ww2.mathworks.cn/help/matlab/ref/colormap.html?searchHighlight=colormap&s_tid=doc_src ...

  9. Linux 百度网盘卡在等待页

    解决办法1 如果无法登录百度网盘,一直在加载,运行命令:rm -rf ~/baidunetdisk 然后关闭百度客户端,重新登录百度客户端. 解决办法2 如果已经登录进百度网盘,退出百度网盘时,不要直 ...

  10. Oracle 数据库创建表空间、创建用户

    创建表空间 create temporary tablespace user_name_temp tempfile '/oradata/ORA11G/user_name_temp.dbf' size ...