第一种情况:分支小于4个
生成引导性的跳转表
cmp ....
je ....
cmp ....
je ...
.......
cmp ..
跳转到default或者 switch end ,不同编译器的表达形式可能不太一样
区分default和 switch end : 排除掉代码外提优化后,找一个break的点看跳的地方是否一样。
定式:
多个je跳到代码块,je之间只有影响标志位的代码,没有实质性功能的代码,代码块在别的位置,通常是连续的,因为在没写break的情况要顺序执行,所以写在一起可以降低代码复杂度。
第二种情况:多分支,且case的数据比较有线性规律,不连续的地方相差不是很多。
这种情况会做一个case的地址表
一上来先和case里最大的比较
ja ;跳default 或 switch end
.....
jmp [reg * 4 + CASE_ADDRESS_TABLE]
这个CASE_ADDRESS_TABLE就是跳转表,anzhao case 值从小到大排序,中间间隔的case值会跳到default,如果没有defual会跳到 switch end
如果case的最小值不是0,会做平移调整,保证最小值在0的下标。
第三种情况:多分支,case值没有明显顺序,MAX - MIN 在255以内
采用调色板的压缩手法:首先用一个一维数组存放所有的case数据,case间隔的值填同一个数字对应defaual,再用一个移位数组,填充对应的跳转地址。
根据不同的输入,对齐0后在第一张表中找到索引,再去第二张表找到跳转地址。
这种方法拿时间换空间。
识别:第一次寻址用的是 byte数组。 值给到reg8
第四种情况:多分支,case值没有明显顺序,MAX - MIN > 255
以二分法判断,很容易识别
网友评论