当前位置: 首页 > Linux

Switch语句的机器级表示

时间:2023-04-06 21:18:28 Linux

switch语句switch语句有几个特殊用途:它可以关联多个选项。如果5和6的处理方式相同,则可以实现drop,即实现语句块的遍历。如果2中没有break语句,则执行完2会继续执行3。C语言中,switch选项必须是整型,不支持其他类型。本质上,switch的所有功能都可以用条件分支if-else语句来表达,既然有等价的表示,为什么还要定义switch语法呢?首先,从switch语句机器指令的执行。switch语句通过跳转表等数据结构来实现机器指令。跳转表是一个数组,每个元素都是一个地址,指向对应case语句块的起始地址。switch语句工作时,根据x变量的值,在跳转表中找到对应的元素,即case语句块的目标地址,然后执行跳转语句,跳转到起始处真实目标条目的位置。这种实现使得switch语句相对于if-else有很大的优势,因为switch语句无论跳转到哪个语句块所花费的时间都是固定的,即时间复杂度是常量类型。但是if-else执行第n个语句块,必须先判断前n个语句块,时间复杂度不固定。所以switch语句使用跳转表将时间复杂度转化为常量,也决定了变量必须是整数。因为只有整数才能搜索数组下标。实现开关机指令。在进入switch语句之前,先将汇编级所做的准备工作传入变量X中进行判断,存放在rdi寄存器中,由ja指令排除。和大于6的数。ja指令用于判断一个无符号数是否大于。即使x是有符号数,也会被判断为无符号数。如果x是负数,ja会认为是正数,最高位为1,所以可以用ja指令排除掉小于0大于6的数jmpindirectjump什么是indirect跳?跳转语句有两种分类方法,一种分为无条件跳转和条件跳转;另一种根据跳跃目标分为直接跳跃和间接跳跃。跳跃目标是确定位置为直接跳跃;跳转目标需要根据某个变量来计算,这就是间接跳转jmp间接跳转指令的操作数是寻址方式的四元组。其中:L4为跳转表起始地址。跳转表是编译器在编译时产生的一组固定的只读数据,一共有7个。编译器在内存中分配一块不可修改的区域,起始地址标为L4,每个数据宽度为8字节。相应的数据值称为标签。标签其实就是一个地址,标签地址就是跳转码。块的地址。rdi是跳转表中要查找的数据的下标,8代表每个元素的大小,*表示取出地址(上图中L3)中的数据,作为跳转语句的目标地址,由于跳转表元素只有7个,所以switch最多只支持0到6范围内的变化,小于0或者大于6会调整到默认位置,即default(同时解释了ja语句的功能)。switch语句实例分析下图为跳转表和case语句块2和3对应关系的理解:w为1的赋值是在进入switch语句块的时候完成的,因为并不是所有的语句块都需要给w赋值(比如2),如果赋值在switch语句块之前给w赋值,就会浪费指令,导致性能下降。先检查哪个语句块需要赋值,然后根据需要赋值。虽然会稍微增加代码量,但是会大大加快效率。进一步讨论switch查找表(跳转表)可以提高switch语句的性能,但它仍然有一定的局限性。性别。当case语句的值很大的时候,如果起始地址还是0,那么查找表的大小就会很大,而且大部分地址其实都指向default,这些地址的存储是没有意义的。两种解决方案:当case语句的地址密集时,可以认为是从0地址整体偏移。这时,编译器只需要减去一个固定的偏移量,就可以使case语句的值在一个较小的范围内。当个案数据范围较大,数轴上不密集时,不宜采用查表法。此时我们使用二分查找找到对应的语句块。关注公众号,让我们一起努力