老码识途 switch机制
来源:互联网 发布:手机淘宝详情页尺寸 编辑:程序博客网 时间:2024/04/29 15:20
flag稠密时的switch算法:
1:i=flag-n;n=case分支中最小的整数;
2: if i>num jmp default;num=case 分支max-min;即中间数个数-1(无须比较小于是因为当小于是,i<0;存在计算机中为负数,无符号比较会大于num);
3:跳转到address[i]中存储的地址。address是预先准备好的数组,其中存储了对应case分支的起始地址
flag稀疏时的switch算法:增加了地址索引表
1:i=flag-min;min=case分支中最小的整数;
2:if(i>max-min)则跳到default(用ja无符号比较);
3:否则addIndex=Index[i];
4:jmp address[addIndex];
再稀疏的话则相当于if else
#include <iostream>using namespace std;int main(int n,char **s){ int flag=20; switch(flag) { case 2: printf("%d",&flag); break; case 4: printf("%d",flag);break; case 5: cout<<flag;break; case 6: cout<<&flag<<endl;break; default: cout<<6<<endl; break; }}汇编代码:int flag=20;00401588 C7 45 FC 14 00 00 00 mov dword ptr [ebp-4],14h6: switch(flag)7: {0040158F 8B 45 FC mov eax,dword ptr [ebp-4]00401592 89 45 F8 mov dword ptr [ebp-8],eax00401595 8B 4D F8 mov ecx,dword ptr [ebp-8]00401598 83 E9 03 sub ecx,2//减去第一个的大小,0040159B 89 4D F8 mov dword ptr [ebp-8],ecx0040159E 83 7D F8 03 cmp dword ptr [ebp-8],4//大于最后一个则跳到default004015A2 77 5C ja $L7390+1Ch (00401600) //ja=大于就跳004015A4 8B 55 F8 mov edx,dword ptr [ebp-8]004015A7 FF 24 95 29 16 40 00 jmp dword ptr [edx*4+401629h] //跳到case处,edx*4是偏移地址8: case 2:9: printf("%d",&flag);004015AE 8D 45 FC lea eax,[ebp-4]004015B1 50 push eax004015B2 68 1C C0 46 00 push offset string "%d" (0046c01c)004015B7 E8 C4 F2 01 00 call printf (00420880)004015BC 83 C4 08 add esp,810: break;004015BF EB 57 jmp $L7390+34h (00401618)11: case 4:12: printf("%d",flag);break;004015C1 8B 4D FC mov ecx,dword ptr [ebp-4]004015C4 51 push ecx004015C5 68 1C C0 46 00 push offset string "%d" (0046c01c)004015CA E8 B1 F2 01 00 call printf (00420880)004015CF 83 C4 08 add esp,8004015D2 EB 44 jmp $L7390+34h (00401618)13: case 5:14: cout<<flag;break;004015D4 8B 55 FC mov edx,dword ptr [ebp-4]004015D7 52 push edx004015D8 B9 F0 77 47 00 mov ecx,offset std::cout (004777f0)004015DD E8 22 FB FF FF call @ILT+255(std::basic_ostream<char,std::char_traits<char> >::operator<<) (00401104)004015E2 EB 34 jmp $L7390+34h (00401618)15: case 6:16: cout<<&flag<<endl;break;004015E4 68 CD 10 40 00 push offset @ILT+200(std::endl) (004010cd)004015E9 8D 45 FC lea eax,[ebp-4]004015EC 50 push eax004015ED B9 F0 77 47 00 mov ecx,offset std::cout (004777f0)004015F2 E8 4A FA FF FF call @ILT+60(std::basic_ostream<char,std::char_traits<char> >::operator<<) (00401041)004015F7 8B C8 mov ecx,eax004015F9 E8 E7 FB FF FF call @ILT+480(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004011e5)004015FE EB 18 jmp $L7390+34h (00401618)17: default:18: cout<<6<<endl;00401600 68 CD 10 40 00 push offset @ILT+200(std::endl) (004010cd)00401605 6A 06 push 600401607 B9 F0 77 47 00 mov ecx,offset std::cout (004777f0)0040160C E8 F3 FA FF FF call @ILT+255(std::basic_ostream<char,std::char_traits<char> >::operator<<) (00401104)00401611 8B C8 mov ecx,eax00401613 E8 CD FB FF FF call @ILT+480(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004011e5)19: break;20: }21: }00401618 5F pop edi00401619 5E pop esi0040161A 5B pop ebx
稀疏:
#include <iostream>using namespace std;int main(int n,char **s){ int flag=20; switch(flag) { case 2: printf("%d",&flag); break; case 40: printf("%d",flag);break; case 50: cout<<flag;break; case 60: cout<<&flag<<endl;break; default: cout<<6<<endl; break; }}5: int flag=20;00401588 C7 45 FC 14 00 00 00 mov dword ptr [ebp-4],14h6: switch(flag)7: {0040158F 8B 45 FC mov eax,dword ptr [ebp-4]00401592 89 45 F8 mov dword ptr [ebp-8],eax00401595 8B 4D F8 mov ecx,dword ptr [ebp-8]00401598 83 E9 02 sub ecx,20040159B 89 4D F8 mov dword ptr [ebp-8],ecx0040159E 83 7D F8 3A cmp dword ptr [ebp-8],3Ah004015A2 77 64 ja $L7390+1Ch (00401608)004015A4 8B 45 F8 mov eax,dword ptr [ebp-8]004015A7 33 D2 xor edx,edx004015A9 8A 90 45 16 40 00 mov dl,byte ptr (00401645)[eax]004015AF FF 24 95 31 16 40 00 jmp dword ptr [edx*4+401631h]//跳转到跳转表,每个地址1个字节,59*1+(4+1)*4=79B ;否则(59+1)*4=240B
再稀疏:
#include <iostream>using namespace std;int main(int n,char **s){ int flag=20; switch(flag) { case 2: printf("%d",&flag); break; case 40: printf("%d",flag);break; case 50: cout<<flag;break; case 600: cout<<&flag<<endl;break; default: cout<<6<<endl; break; }}
则:
int flag=20;00401588 C7 45 FC 14 00 00 00 mov dword ptr [ebp-4],14h6: switch(flag)7: {0040158F 8B 45 FC mov eax,dword ptr [ebp-4]00401592 89 45 F8 mov dword ptr [ebp-8],eax00401595 83 7D F8 32 cmp dword ptr [ebp-8],32h00401599 7F 14 jg main+3Fh (004015af)0040159B 83 7D F8 32 cmp dword ptr [ebp-8],32h0040159F 74 3F je main+70h (004015e0)004015A1 83 7D F8 02 cmp dword ptr [ebp-8],2004015A5 74 13 je main+4Ah (004015ba)004015A7 83 7D F8 28 cmp dword ptr [ebp-8],28h004015AB 74 20 je main+5Dh (004015cd)004015AD EB 5D jmp main+9Ch (0040160c)004015AF 81 7D F8 58 02 00 00 cmp dword ptr [ebp-8],258h004015B6 74 38 je main+80h (004015f0)004015B8 EB 52 jmp main+9Ch (0040160c)
相当于if else了
0 0
- 老码识途 switch机制
- Switch语句的实现机制
- Switch语句的实现机制(2)
- 利用Java反射机制取代switch判断
- if else 与switch 效率&实现机制
- switch
- Switch
- Switch
- switch
- switch
- switch
- Switch
- switch
- switch
- switch
- SWITCH
- Switch
- switch
- Linux Or Unix 下安装git进行版本控制!
- 基于nagios的监控环境(一):Nagios监控基本环境安装
- Android下的dimen转成int型的值
- 基于nagios的监控环境(四):第三方插件监控流量、CPU、内存、进程
- MyEclipse将java项目改为web项目
- 老码识途 switch机制
- 基于nagios的监控环境(二):nrpe监控远程机器
- 基于nagios的监控环境(三):nconf页面配置nagios
- CentOS-6.4安装配置Nginx【转】
- IntelliJ IDEA WEB项目的部署配置
- Intellij IDEA 的使用
- 使用 IDEA + Maven + Git 快速开发 Java Web 应用
- Oracle sequence属性值说明
- [LeetCode 43]Multiply Strings