当前位置: 首页 > news >正文

稀疏值(sparse)的switch-case语句,编译器生成了条件跳转链(if-else链)的实现方式

文章目录

    • 完整代码
    • 汇编部分
    • 汇编特征分析
      • 1. 初始比较和分支
      • 2. 大于100的分支处理
      • 3. 各case块执行
    • 关键特征总结
    • 对应的C++代码推测

完整代码

#include <string>// 基础输出模拟
void output(int val) {static int buffer;buffer = val;
}// 1. 密集连续值 - 可能生成跳转表
void switch_dense_sequential(int value) {switch (value) {case 1: output(100); break;case 2: output(200); break;case 3: output(300); break;case 4: output(400); break;case 5: output(500); break;case 6: output(100); break;case 7: output(200); break;case 8: output(300); break;case 9: output(400); break;case 10: output(500); break;default: output(0); break;}
}// 2. 稀疏值 - 可能生成条件跳转链
void switch_sparse(int value) {switch (value) {case 10: output(1000); break;case 50: output(5000); break;case 100: output(10000); break;case 500: output(50000); break;default: output(0); break;}
}// 3. 有小间隔的值 - 可能使用小表优化
void switch_small_gaps(int value) {switch (value) {case 1: output(10); break;case 3: output(30); break;case 5: output(50); break;case 7: output(70); break;case 9: output(90); break;default: output(0); break;}
}// 4. 带fall-through的case
void switch_fallthrough(int value) {switch (value) {case 1:case 2:case 3: output(123); break;  // 1,2,3共享代码case 4: output(40);case 5: output(50); break;   // 4会fall through到5default: output(0); break;}
}// 5. 枚举类型的switch
enum class Color { RED, GREEN, BLUE, YELLOW, BLACK };void switch_enum(Color color) {switch (color) {case Color::RED: output(1); break;case Color::GREEN: output(2); break;case Color::BLUE: output(3); break;case Color::YELLOW: output(4); break;default: output(0); break;}
}// 6. 字符类型switch
void switch_char(char c) {switch (c) {case 'A': case 'a': output(65); break;case 'B': case 'b': output(66); break;case 'C': case 'c': output(67); break;default: output(0); break;}
}// 7. 边界测试:最小/最大值差距大但case少
void switch_large_range(int value) {switch (value) {case 0: output(0); break;case 1000: output(1000); break;case 1000000: output(1000000); break;default: output(-1); break;}
}// 8. 嵌套switch语句
void switch_nested(int x, int y) {switch (x) {case 1:switch (y) {case 1: output(11); break;case 2: output(12); break;default: output(10); break;}break;case 2:switch (y) {case 1: output(21); break;case 2: output(22); break;default: output(20); break;}break;default: output(0); break;}
}// 9. 只有少量case的情况
void switch_few_cases(int value) {switch (value) {case 1: output(1); break;case 2: output(2); break;default: output(0); break;}
}// 10. 用于状态机的switch(典型应用)
void state_machine_example() {enum State { START, PROCESSING, END };static State state = START;static int counter = 0;switch (state) {case START:counter = 0;state = PROCESSING;break;case PROCESSING:counter++;if (counter >= 5) state = END;break;case END:output(999);break;}
}// 测试函数
int main() {// 测试各种switch情况switch_dense_sequential(3);  // 密集连续switch_sparse(50);          // 稀疏值switch_small_gaps(5);       // 小间隔switch_fallthrough(4);      // fall-throughswitch_enum(Color::GREEN);  // 枚举switch_char('b');           // 字符switch_large_range(1000);   // 大范围switch_nested(1, 2);        // 嵌套switch_few_cases(1);        // 少量case// 状态机多次执行for (int i = 0; i < 10; i++) {state_machine_example();}return 0;
}

汇编部分

    26: // 2. 稀疏值 - 可能生成条件跳转链27: void switch_sparse(int value) {
00A520D0  push        ebp  
00A520D1  mov         ebp,esp  
00A520D3  sub         esp,0C4h  
00A520D9  push        ebx  
00A520DA  push        esi  
00A520DB  push        edi  
00A520DC  lea         edi,[ebp-4]  
00A520DF  mov         ecx,1  
00A520E4  mov         eax,0CCCCCCCCh  
00A520E9  rep stos    dword ptr es:[edi]  
00A520EB  mov         ecx,offset _FA199733_if语句@cpp (0A5D058h)  
00A520F0  call        @__CheckForDebuggerJustMyCode@4 (0A51348h)  
00A520F5  nop  28:     switch (value) {
00A520F6  mov         eax,dword ptr [value]  
00A520F9  mov         dword ptr [ebp-0C4h],eax  
00A520FF  cmp         dword ptr [ebp-0C4h],64h  
00A52106  jg          __$EncStackInitStart+49h (0A52125h)  
00A52108  cmp         dword ptr [ebp-0C4h],64h  
00A5210F  je          __$EncStackInitStart+75h (0A52151h)  
00A52111  cmp         dword ptr [ebp-0C4h],0Ah  
00A52118  je          __$EncStackInitStart+57h (0A52133h)  
00A5211A  cmp         dword ptr [ebp-0C4h],32h  
00A52121  je          __$EncStackInitStart+66h (0A52142h)  
00A52123  jmp         __$EncStackInitStart+93h (0A5216Fh)  
00A52125  cmp         dword ptr [ebp-0C4h],1F4h  
00A5212F  je          __$EncStackInitStart+84h (0A52160h)  
00A52131  jmp         __$EncStackInitStart+93h (0A5216Fh)  29:     case 10: output(1000); break;
00A52133  push        3E8h  
00A52138  call        output (0A5105Ah)  
00A5213D  add         esp,4  
00A52140  jmp         __$EncStackInitStart+9Dh (0A52179h)  30:     case 50: output(5000); break;
00A52142  push        1388h  
00A52147  call        output (0A5105Ah)  
00A5214C  add         esp,4  
00A5214F  jmp         __$EncStackInitStart+9Dh (0A52179h)  31:     case 100: output(10000); break;
00A52151  push        2710h  
00A52156  call        output (0A5105Ah)  
00A5215B  add         esp,4  
00A5215E  jmp         __$EncStackInitStart+9Dh (0A52179h)  32:     case 500: output(50000); break;
00A52160  push        0C350h  
00A52165  call        output (0A5105Ah)  
00A5216A  add         esp,4  
00A5216D  jmp         __$EncStackInitStart+9Dh (0A52179h)  33:     default: output(0); break;
00A5216F  push        0  
00A52171  call        output (0A5105Ah)  
00A52176  add         esp,4  34:     }35: }
00A52179  pop         edi  
00A5217A  pop         esi  
00A5217B  pop         ebx  
00A5217C  add         esp,0C4h  
00A52182  cmp         ebp,esp  
00A52184  call        __RTC_CheckEsp (0A51258h)  
00A52189  mov         esp,ebp  
00A5218B  pop         ebp  
00A5218C  ret  

根据提供的汇编代码,这是一个稀疏值(sparse)的switch-case语句,编译器生成了**条件跳转链(if-else链)**的实现方式。

汇编特征分析

1. 初始比较和分支

00A520F6  mov         eax,dword ptr [value]  
00A520F9  mov         dword ptr [ebp-0C4h],eax  
00A520FF  cmp         dword ptr [ebp-0C4h],64h  ; 比较 value 和 100
00A52106  jg          0A52125h                  ; 大于100跳转
00A52108  cmp         dword ptr [ebp-0C4h],64h  ; 再次比较100
00A5210F  je          0A52151h                  ; 等于100跳转(case 100)
00A52111  cmp         dword ptr [ebp-0C4h],0Ah  ; 比较10
00A52118  je          0A52133h                  ; 等于10跳转(case 10)
00A5211A  cmp         dword ptr [ebp-0C4h],32h  ; 比较50
00A52121  je          0A52142h                  ; 等于50跳转(case 50)
00A52123  jmp         0A5216Fh                  ; 跳转到default

2. 大于100的分支处理

00A52125  cmp         dword ptr [ebp-0C4h],1F4h ; 比较500
00A5212F  je          0A52160h                  ; 等于500跳转(case 500)
00A52131  jmp         0A5216Fh                  ; 跳转到default

3. 各case块执行

; case 10
00A52133  push        3E8h        ; 1000
00A52138  call        output  
00A52140  jmp         0A52179h    ; 跳出switch; case 50  
00A52142  push        1388h       ; 5000
00A52147  call        output
00A5214F  jmp         0A52179h; case 100
00A52151  push        2710h       ; 10000
00A52156  call        output
00A5215E  jmp         0A52179h; case 500
00A52160  push        0C350h      ; 50000
00A52165  call        output
00A5216D  jmp         0A52179h; default
00A5216F  push        0
00A52171  call        output

关键特征总结

  1. 条件跳转链: 使用连续的cmp和条件跳转指令(je, jg)来测试每个case值
  2. 二分搜索优化: 先比较中间值(100),然后分别处理小于等于和大于的情况
  3. 没有跳转表: 由于case值稀疏(10, 50, 100, 500),编译器没有生成跳转表
  4. 线性搜索: 在各自的分支内,case值是线性比较的
  5. 明确的边界检查: 通过比较指令建立明确的执行路径

对应的C++代码推测

void switch_sparse(int value) {switch (value) {case 10: output(1000); break;case 50: output(5000); break; case 100: output(10000); break;case 500: output(50000); break;default: output(0); break;}
}

这种实现方式在case值较少且分布稀疏时效率较高,避免了大型跳转表的内存开销。

http://www.dtcms.com/a/500429.html

相关文章:

  • 广州市住房和城乡建设局网站唐山网站建设开发设计公司
  • 做博客的网站有哪些网站推广技巧
  • 烟台做外贸网站网站开发商品排序逻辑
  • 想学网站开发北京网智易通科技有限公司
  • 网站从建设到运营管理的理解php网站运行很慢
  • NetBeans下载和安装教程(附安装包,适合新手)
  • php做的网站怎么发布哪里有广告设计制作的培训
  • 现在什么网站做外贸的最好只有asp网站代码可以重新编译吗
  • 【UCIe】协议演进
  • 重庆装修公司前十强优化网站技术
  • 从遍历序列到原树:二叉树重建的逻辑与实现
  • 第3章,[标签 Win32] :窗口类03,窗口过程函数与消息机制
  • 网站空间 数据库网站源码防盗原理
  • 网站开发 提成项目分享网
  • 有模板了怎么建设网站网站推广活动策划
  • 手机用什么软件做网站台州企业免费建站
  • 网约车平台app网站建设活动策划案格式模板和范文
  • 【C语言初阶】算术操纵符,移位操作符,位操作符,赋值操作符,单目操作符,关系操作符,逻辑操作符,条件操作符,
  • 郑州各区房价一览表seo页面优化技术
  • 虚拟主机怎么弄网站网页设计尺寸参考表
  • 创建用户组、用户、权限
  • LLMs:nanochat(仿照GPT-3 Small)的简介、安装和使用方法、案例应用之详细攻略
  • 从能量到位移:混合模式分层失效临界位移推导
  • 算法_记忆知识点汇总
  • 网站下载织梦模板潍坊网站排名公司
  • cnzz网站代做百度官方下载安装
  • (2)路由表
  • 电商网站开发需要掌握哪些知识技能设计一个企业网站报价
  • 做平面资源比较好的网站安卓优化清理大师
  • 公司做网站好豌豆荚应用商店