switch语句
switch(常数表达式)
{
case 常数表达式:
语句;
break;
case 常熟表达式:
语句;
break;
case 常数表达式:
语句;
break;
......
default:
语句;
break;
}
其中表达式为常数表达式,case后的数据可以连续也可以不连续,与编译器的分配有关。
汇编语句
关键点:jmp dword ptr [edx*4+4110E2h],这是编译器生成的一张表,表中存储case的每种情况(包括default的情况),edx为索引值,来自mov ecx,dword ptr [ebp-4]和sub ecx,1。可以根据查表定位到情况。
传入的值先与最大的值进行比较,后按表寻找。
switch的多种情况
1 三项/以下选择
与if/else语句反汇编相同。
2 三项以上选择
生成一张大表用来进行语句的寻址。
3 数值大的连续数据选择
编译器自行减少12Dh = 301。其他相同创建大表。
4 不连续的选择
不会产生影响,因为生成的大表对应的位置就是寻找的位置。
4 部分连续的选择
编译器会将断开的选择的大表数据复制为default的地址。同样可以寻址。
5 断开一定程度的选择
关键点mov dl,byte ptr (004010d0)[eax] jmp dword ptr [edx4+4010BCh]
(004010d0)[eax] = [004010d0 + eax4] 在这个地址中得到一个偏移 作为查询大表的edx值。
生成大表的条件
连续相近,且与顺序无关
生成小表的条件
添加default到一定程度之后生成。先通过小表找到索引值edx在通过edx找到大表内的跳转位置。