首页 > 作文

C++ 反汇编之关于Switch语句的优化措施

更新时间:2023-04-04 19:43:10 阅读: 评论:0

流程控制语句是c语言中最基本的判断语句,通常我们可以使用if来构建多分支结构,但同样可以使用switch语句构建,switch语句针对多分支的优化措施有4种形式,分别是,if-el优化,有序线性优化,非线性索引优化,平衡判定树优化。

与if语句结构不同,if语句会在条件跳转后紧跟语句块,而switch结构则将所有条件跳转都放置在一起,判断时需要重点观察每个条件跳转指令后面是否跟有语句块,以辨别switch分支结构。

在switch分支数小于4的情况下,编译器将采用模拟if-el分支的方式构建switch结构,这样则无法发挥出switch语句的优势,当分支数大于3并且ca的判断值存在明显线性关系时,switch语句的优化特性才可以凸显出来。

有序线性优化: 该优化方式将每个ca语句块的地址预先保存在数组中,并依据此数组查询ca语句块对应的首地址。

首先代码生成时会为ca语句制作一个ca地址表数组,数组中保存每个ea语句块的首地址,并且下标以0开头,在进入switch后先进行一次比较,检查输入的数值是否大于ca值的最大值,

为了达到线性有序,对于没有ca对应的数值,编译器以switch的结束地址或者default语句块的首地址填充对应的表格项。

ca线性地址表是一个有序表。

当switch为一个有序线性组合时,会对其ca语句块制作地址表,以减少比较跳转次数。

在编写代码时,我们无需自己排列ca序列,编译器编译时会自动进行排序优化,先来编写一个简单的代码:

int main(int argc, char *argv[]){int index = 0;scanf("%d", &index);switch (index){ca 1:printf("index 1"); break;ca 2:printf("index 2"); break;ca 3:printf("index 3"); break;ca 6:printf("index 6"); break;ca 7:printf("index 7"); break;default:printf("default"); break;}return 0;}

代码经过反汇编后,我们可以注意到,首先用户通过scanf输入所需要执行的分支,因为分支语句下标从0开始,所以需要dec eax减去1,在进入switch语句之前,判断输入的下标是否高于6,如果高于则直接跳出switch,否则执行ds:[eax*4+0x401348]寻址。

004012b4 | ff15 b8304000 | call dword ptr ds:[<&scanf>] |
004012ba | 8b45 fc | mov eax,dword ptr ss:[ebp-4] |
004012bd | 83c4 08 | add esp,8 电荷分布 |
004012c0 | 48 | dec eax | switch语句获取比例因子,需要减1
004012c1 | 83f8 06 | cmp eax,6 | 首先对比输入数据是否大于6
004012c4 | 77 6b | ja consoleapplication.401331 | 大于则说明switch分支无对应结构 (则直接跳转到结束)
004012c6 | ff2485 48134000 | jmp dword ptr ds:[eax*4+0x401348] | 跳转到指定代码段

地址0x401348对应的就是每一个分支的首地址,跳转后即可看到分支。

非线性索引优化: 如果两个ca值间隔较大,仍然使用switch的结尾地址或default地址代替地址表中缺少的ca地址,这样则会造成极大的空间浪费。

非线性的switch结构,可采用制作索引表的方式进行优化,索引表有两张,1.ca语句块地址表,2.ca语句块索引表。

地址表中每一项保存一个ca语句块首地址,有几个ca语句块或default语句块,就保存几项,结束地址在地址表中指挥保存一份。

索引表中保存了地址表中的下标值,索引表最多可容纳256项,每项1字节,所以ca值不可超过1字节,索引表也只能存储256项索引编号。

在执行时需要通过索引表来查询地址表,会多出一次查表的过程,因此效率上会有所下降。

004012b4 | ff15 b8304000 | call dword ptr ds:[<&scanf>] |
004012ba | 8b45 fc | mov eax,dword ptr ss:[ebp-4] |
004012bd | 83c4 08 | add esp,8 |
004012c0 | 48 | dec eax | switch语句获取比例因子,需要减1
004012c1 | 3d fe000000 | cmp eax,fe | 首先对比输入数据是否大于254
004012c6 | 0f87 80000000 | ja consoleapplication.40134c | 跳转到指定代码段
004012cc | 0fb680 70134000 | movzx eax,byte ptr ds:[eax+0x401370] | 从索引表找地址表下标
004012d3 | ff2485 54134000 | jmp dword ptr ds:[eax*4+0x401354] | 比例因子寻找函数地址

首先movzx eax, byte ptr ds:[eax+0x401370]从索引表中找到地址表下标。

然后通过索引表找到索引值,并带入jmp dword ptr ds:[eax*4+0x401354]找到地址表中的指定地址,地址表中每一个地址就代表一个分支结构里的函数。

这样的优势就是可以节约空间,每一个所以表字段只占1字节,如果两个ca差距较大同样会指向同一个地址表中的地址,地址表相对来说会变得简单,但这种查询方式会产生两次间接内存访问,在效率上远远低于线性表方式。

平衡判定树优化: 当最大ca值与最小ca值之差大于255时,则会采用判定树优化,将每个ca值作为一个节点,从节点中找出中间值作为根节点,以此形成一颗平衡二叉树,以每个节点为判定值,大于和小于关系分别对应左子树和右子树,从而提高查询效率。

如果打开编译器体积优先,编译器尽量会以二叉判定树的方式来降低程序占用体积,如果无法使用以上优化方式,则需要将switch做成树。

int main(int argc, char *argv[]){int index = 0;scanf("%d", &index);switch (index){ca 2:printf("index 2"); break;ca 3:printf("index 3"); break;ca 8:printf("index 8"); break;ca 10:printf("index 10"); break;ca 35:printf("ind婴儿湿疹怎么办ex 35"); break;ca 37:printf("index 37"); break;ca 666:printf("index 666"); break;}return 0;}

判定树反汇编形式。

004012c0 | 83f8 0a | cmp eax,a 黑龙江高考改革 | a:’\n’
004012c3 | 7f 63 | jg consoleapplication.401328 |
004012c5 | 74 4d | je consoleapplication.401314 |
004012c7 | 83e8 02 | sub eax,2 |
004012ca | 74 34 | je consoleapplication.401300 |
004012cc | 48 女工假 | dec eax |
004012cd | 74 1d | je consoleapplication.4012ec |
004012cf | 83e8 05 | sub eax,5 |
004012d2 | 0f85 97000000 | jne consoleapplication.40136f |
004012d8 | 68 a0314000 | push consol初一上学期英语eapplication.4031a0 | main.cpp:16, 4031a0:”index 8″
004012dd | ff15 b4304000 | call dword ptr ds:[<&printf>] | main.cpp:20
004012e3 | 83c4 04 | add esp,4 |

判定树,通过增加多条分支结构,从中位数开始判断,大于或小于分别走不同的分支,直到遇到函数地址位置。

为了降低数的高度,在优化过程中,会检查代码是否满足if-el优化,有序线性优化,非线性索引优化,利用三种优化来降低树高度,谁的效率高就优先使用谁,三种优化都无法匹配才会使用判定树。

到此这篇关于c++ 反汇编之关于switch语句的优化措施的文章就介绍到这了,更多相关c++ 反汇编switch语句优化内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

本文发布于:2023-04-04 19:43:08,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/c3f537deade365ac9303fab19081b44f.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:C++ 反汇编之关于Switch语句的优化措施.doc

本文 PDF 下载地址:C++ 反汇编之关于Switch语句的优化措施.pdf

标签:语句   地址   索引   分支
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图