C语言之 Switch和?:运算符的反汇编
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和?:运算符的反汇编的更多相关文章
- 李洪强漫谈iOS开发[C语言-040]-switch case
李洪强漫谈iOS开发[C语言-039]-switch case 补充:
- PROCESS_YIELD()宏和C语言的switch语句< contiki学习笔记之七>
写在前面: 按照main()函数的代码一行一行的分析,该是看到了 etimer_process 这个位置.但是etimer_process实现里的一个宏 PROCESS_YIELD()引出了很多故事 ...
- Swift语言指南(九)--基本运算符
原文:Swift语言指南(九)--基本运算符 运算符(operator)是用来检查,改变或合并值的一种特殊符号或短语.例如,加号运算符让两个数字相加(如:let i = 1 + 2),还有些更复杂的运 ...
- c语言的类型、运算符与表达式
title: 2017-10-17c语言的类型.运算符与表达式 tags: c程序设计语言 grammar_cjkRuby: true --- 1.1 数据类型 char 字符型,一个字节 int 整 ...
- 选择语言之switch case
程序语言-选择语言之switch case 多选一,类似if else if else if else 模版: Switch(选择条件) { Case(条件一)//相当于if Conso ...
- c语言基础表达式, 关系运算符, 逻辑运算符, 位运算符, 数据的取值范围, 分支结构(if...else, switch...case)
1.表达式: 表达式的判断是有无结果(值), 最简单的表达式是一个常量或变量, 如:12, a, 3 + 1, a + b, a + 5 都是表达式 2.BOOL(布尔)数据类型: c语言中除了基本数 ...
- C语言的关键字,运算符,标识符
关键字 数据类型修饰相关 auto按照自动的方式进行变量的存储 const定义常量或常参数 extern声明外部变量或函数 register指定变量的存储类型是寄存器变量 static指定变量的存储类 ...
- 2.2JAVA基础复习——JAVA语言的基础组成运算符和语句
JAVA语言的基础组成有: 1.关键字:被赋予特殊含义的单词. 2.标识符:用来标识的符号. 3.注释:用来注释说明程序的文字. 4.常量和变量:内存存储区域的表示. 5.运算符:程序中用来运算的符号 ...
- JavaScript 基础 if switch 弹窗 运算符
脚本语言最重要的几个部分: 数据类型 运算符 控制语句 数组 方法(函数) 一.基础知识 关键字:系统定义 有意义的名字如 background link 等 标识符:自己定 比如class的名字a ...
随机推荐
- JVM学习(八)指令重排序
一.数据依赖性 在学习JVM的指令重排序之前,我们先了解一下什么是数据依赖性: 编译器和处理器在处理具体的指令时,可能会对操作进行重排序来提高执行性能[多条指令并行执行,所以提升性能的同时也可能会导致 ...
- Spring学习(七)bean装配详解之 【通过注解装配 Bean】【自动装配的歧义解决】
自动装配 1.歧义性 我们知道用@Autowired可以对bean进行注入(按照type注入),但如果有两个相同类型的bean在IOC容器中注册了,要怎么去区分对哪一个Bean进行注入呢? 如下情况, ...
- (转载)什么是B+树?
本文转载自网络. 如有侵权,请联系处理!
- Hibernate4.3基础知识2
一.数据库的隔离级别 脏读 不可重复读 幻读 Read uncommited Y Y Y Read commited N Y Y Repeatable read N N Y Serializabl ...
- chrome浏览器的两个坑,以及其他
chrome打开本地网页时,不能保存cookiechrome拒绝使用ajax访问本地文件(火狐可以) ipinfo.io/ip 获得公网iphttps://v1.hitokoto.cn/ 获得一句动漫 ...
- Spring循环依赖的问题
什么是循环依赖?就是两个Bean相互引用,比如用@Autowire 相互注入. 那么Spring是如何解决这个问题的呢?在Bean还未完全实例化前(类只实例化了一部分),将bean提前暴露出来 ...
- 日志分析平台ELK之日志收集器filebeat
前面我们了解了elk集群中的logstash的用法,使用logstash处理日志挺好的,但是有一个缺陷,就是太慢了:当然logstash慢的原因是它依赖jruby虚拟机,jruby虚拟机就是用java ...
- CentOS7设置内网时间同步
1.yum 安装 NTP服务器 [root@master ~]# yum -y install ntp 2.启动ntpd服务 [root@master ~]# systemctl start ntpd ...
- 057 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 04 案例:求整型数组的数组元素的元素值累加和
057 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 04 案例:求整型数组的数组元素的元素值累加和 本文知识点:求整型数组的数组元素的元素值累加和 案例:求整型数 ...
- 050 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 12 continue语句
050 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 12 continue语句 本文知识点:continue语句 continue语句 continue ...