5.6 降低判定树的高度(3)
图5-11中的编号off_4010D0并不容易识别,可将此标号重新命名—按N键重新命名为CASE_JMP_TABLE,表示这是一个case跳转表。这个表保存了10个case块的首地址,其中的5个地址值相同,这5个地址值表示的可能是default语句块的首地址或者switch的结束地址。将编号loc_401093修改为SWITCH_DEFAULT,这样,图5-11中还剩下4个地址标号需要解释。
根据之前所学的知识,这个表中的第0项为下标值加下标对齐值—下标对齐值为2,地址标号loc_401035为表中第0项,对应的case值为0 + 2,将其修改为CASE_2。类似地,标号loc_401044为 case 3代码块的首地址,可修改为CASE_3;标号loc_401053为 case 8代码块的首地址,可修改为CASE_8;标号loc_401062为 case 10代码块的首地址,可修改为CASE_10。这样线性表部分就全都分析完了。
在代码清单5-19中还有两个标号short loc_401080与short loc_401071。标号short loc_40107表示的是比较等于35后才会跳转到的地址,可以判断这个标号表示的地址为case 35语句块的首地址,将其重新命名为CASE_35。如果大于35,则会跳转到标号short loc_401080表示的地址处。继续分析汇编代码,如代码清单5-20所示。
代码清单5-20 树结构片段2—Release版
- .text:00401080 loc_401080:
- .text:00401080 cmp eax, 37
- ; 比较是否等于37,等于则跳转到标号short loc_4010C0
- .text:00401083 jz short loc_4010C0
- .text:00401085 cmp eax, 666
- ; 比较是否等于666,等于则跳转到标号short loc_4010B1
- .text:0040108A jz short loc_4010B1
- .text:0040108C cmp eax, 10000
- ; 比较是否等于10000,等于则跳转到标号short loc_4010A2
- .text:00401091 jz short loc_4010A2
代码清单5-20中的多分支结构为一个仿if else的switch结构,在两个比较跳转中间没有任何语句执行块。根据比较的数值可以知道跳转的地址标号代表的case语句。标号short loc_4010C0表示 case 37代码块的首地址,可修改为 CASE_37,标号short loc_4010B1表示 case 666代码块的首地址,可修改为 CASE_666,标号short loc_4010A2表示case 10000代码块的首地址,可修改为CASE_10000。至此,这个switch结构分析完毕。
为了降低树的高度,在树的优化过程中,检测树的左子树或右子树能否满足if else优化、有序线性优化、非线性索引优化,利用这三种优化来降低树高度。选择哪种优化也是有顺序的,谁的效率最高,又满足其匹配条件,就可以被优先使用。以上三种优化都无法匹配,就会选择使用判定树。