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. dubbo学习(一)认识dubbo

    一.发展背景 单一应用架构 当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本.此时,用于简化增删改查工作量的数据访问框架(ORM)是关键. 垂直应用架构 当访问量逐渐增大, ...

  2. dubbo学习(七)dubbo项目搭建--生产者(服务提供者)

    PS:  项目架子以及工程间的maven依赖配置暂时省略,后续看情况可能会单独写一篇文章捋捋框架结构,先马克~ 配置和启动 1.pom文件引入dubbo和zookeeper的操作客户端 <!-- ...

  3. 如何修改MySQL数据库名称

    比如数据库名称old_db想改名为new_db MySQL修改数据库名称比较麻烦,不支持直接修改,需要通过其它方式间接达到修改数据库名称的目的. 在 MySQL 5.1.23 之前的旧版本中,我们可以 ...

  4. jquery,Datatables插件使用,做根据【日期段】筛选数据的功能 jsp

     时间格式为yyyymmdd,通过转换为int类型进行比较大小 画面: jsp代码: 1 //日期显示控件,使用h-ui框架 2 3 <div class="text-c"& ...

  5. 理解RESTful:理论与最佳实践

    什么是 REST 什么是 RESTful Richardson 成熟度模型 RESTful API 设计最佳实践 补充:HTTP 状态码及说明 什么是 REST REST 一词,是由 HTTP 协议的 ...

  6. 在Centos6上安装RabbitMQ的过程(有点坑)

    1.安装依赖环境 yum install build-essential openssl openssl-devel unixODBC unixODBC-devel make gcc gcc-c++ ...

  7. IOS 数据储存

    IOS 数据存储 ios数据存储包括以下几种存储机制: 属性列表 对象归档 SQLite3 CoreData AppSettings 普通文件存储 1.属性列表 // //  Persistence1 ...

  8. CSG:清华大学提出通过分化类特定卷积核来训练可解释的卷积网络 | ECCV 2020 Oral

    论文提出类特定控制门CSG来引导网络学习类特定的卷积核,并且加入正则化方法来稀疏化CSG矩阵,进一步保证类特定.从实验结果来看,CSG的稀疏性能够引导卷积核与类别的强关联,在卷积核层面产生高度类相关的 ...

  9. 深入研究RocketMQ消费者是如何获取消息的

    前言 小伙伴们,国庆都过的开心吗?国庆后的第一个工作日是不是很多小伙伴还沉浸在假期的心情中,没有工作状态呢? 那王子今天和大家聊一聊RocketMQ的消费者是如何获取消息的,通过学习知识来找回状态吧. ...

  10. LiteOS-任务篇-源码分析-系统启动函数

    目录 前言 链接 参考 开启调度 LOS_Start 函数源码 osTickStart 函数源码 LOS_StartToRun 函数源码 前言 20201009 移植好内核后,开始实战内核. 源码分析 ...