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

有小间隔值的switch-case语句,编译器使用了两级跳转表(two-level jump table)优化。

文章目录

    • 完整代码
    • 汇编代码
    • 汇编特征分析
      • 1. 范围检查和索引计算
      • 2. 两级跳转表查找
      • 3. 第一级表(索引表)分析
      • 4. 第二级表(跳转表)分析
      • 5. 各case块执行
    • 关键特征总结
    • 对应的C++代码推测
    • 优化策略分析

完整代码

void switch_small_gaps(int value) {switch (value) {case 1: output(10); break;case 4: output(30); break;case 7: output(50); break;case 10: output(70); break;case 13: output(90); break;default: output(0); break;}
}

汇编代码

    37: // 3. 有小间隔的值 - 可能使用小表优化38: void switch_small_gaps(int value) {
008F1FC0  push        ebp  
008F1FC1  mov         ebp,esp  
008F1FC3  sub         esp,0C4h  
008F1FC9  push        ebx  
008F1FCA  push        esi  
008F1FCB  push        edi  
008F1FCC  lea         edi,[ebp-4]  
008F1FCF  mov         ecx,1  
008F1FD4  mov         eax,0CCCCCCCCh  
008F1FD9  rep stos    dword ptr es:[edi]  
008F1FDB  mov         ecx,offset _FA199733_if语句@cpp (08FD058h)  
008F1FE0  call        @__CheckForDebuggerJustMyCode@4 (08F1348h)  
008F1FE5  nop  39:     switch (value) {
008F1FE6  mov         eax,dword ptr [value]  
008F1FE9  mov         dword ptr [ebp-0C4h],eax  
008F1FEF  mov         ecx,dword ptr [ebp-0C4h]  
008F1FF5  sub         ecx,1  
008F1FF8  mov         dword ptr [ebp-0C4h],ecx  
008F1FFE  cmp         dword ptr [ebp-0C4h],0Ch  
008F2005  ja          $LN9 (08F2057h)  
008F2007  mov         edx,dword ptr [ebp-0C4h]  
008F200D  movzx       eax,byte ptr [edx+8F2090h]  
008F2014  jmp         dword ptr [eax*4+8F2078h]  40:     case 1: output(10); break;
008F201B  push        0Ah  
008F201D  call        output (08F105Ah)  
008F2022  add         esp,4  
008F2025  jmp         $LN9+0Ah (08F2061h)  41:     case 4: output(30); break;
008F2027  push        1Eh  
008F2029  call        output (08F105Ah)  
008F202E  add         esp,4  
008F2031  jmp         $LN9+0Ah (08F2061h)  42:     case 7: output(50); break;
008F2033  push        32h  
008F2035  call        output (08F105Ah)  
008F203A  add         esp,4  
008F203D  jmp         $LN9+0Ah (08F2061h)  43:     case 10: output(70); break;
008F203F  push        46h  
008F2041  call        output (08F105Ah)  
008F2046  add         esp,4  
008F2049  jmp         $LN9+0Ah (08F2061h)  44:     case 13: output(90); break;
008F204B  push        5Ah  
008F204D  call        output (08F105Ah)  
008F2052  add         esp,4  
008F2055  jmp         $LN9+0Ah (08F2061h)  45:     default: output(0); break;
008F2057  push        0  
008F2059  call        output (08F105Ah)  
008F205E  add         esp,4  46:     }47: }
008F2061  pop         edi  
008F2062  pop         esi  
008F2063  pop         ebx  
008F2064  add         esp,0C4h  
008F206A  cmp         ebp,esp  
008F206C  call        __RTC_CheckEsp (08F1258h)  
008F2071  mov         esp,ebp  
008F2073  pop         ebp  
008F2074  ret  
008F2075  nop         dword ptr [eax]  
008F2078  sbb         esp,dword ptr [eax]  
008F207A  pop         dword ptr [eax]  
008F207C  daa  
008F207D  and         byte ptr [edi-70DFCD00h],cl  
008F2083  add         byte ptr [edi],bh  
008F2085  and         byte ptr [edi-70DFB500h],cl  
008F208B  add         byte ptr [edi+20h],dl  
008F208E  pop         dword ptr [eax]  
008F2090  add         byte ptr ds:[5050105h],al  
008F2096  add         al,byte ptr ds:[5050305h]  
008F209C  add         al,0CCh  

根据提供的汇编代码,这是一个有小间隔值的switch-case语句,编译器使用了**两级跳转表(two-level jump table)**优化。

汇编特征分析

1. 范围检查和索引计算

008F1FE6  mov         eax,dword ptr [value]  
008F1FE9  mov         dword ptr [ebp-0C4h],eax  
008F1FEF  mov         ecx,dword ptr [ebp-0C4h]  
008F1FF5  sub         ecx,1                    ; value - 1 (索引调整)
008F1FF8  mov         dword ptr [ebp-0C4h],ecx  
008F1FFE  cmp         dword ptr [ebp-0C4h],0Ch ; 比较是否大于12
008F2005  ja          008F2057h                ; 大于12跳转到default

2. 两级跳转表查找

008F2007  mov         edx,dword ptr [ebp-0C4h]  ; 加载索引
008F200D  movzx       eax,byte ptr [edx+8F2090h] ; 从第一级表加载字节
008F2014  jmp         dword ptr [eax*4+8F2078h]  ; 第二级跳转表查找

3. 第一级表(索引表)分析

地址8F2090h开始的索引表包含13个字节(0-12):

8F2090h: 00 00 00 00 01 00 00 02 00 00 03 00 00 04

对应case值映射:

  • 索引0-12对应value值1-13
  • 有效case:索引0(1), 3(4), 6(7), 9(10), 12(13)
  • 索引值:0→case1, 1→case4, 2→case7, 3→case10, 4→case13

4. 第二级表(跳转表)分析

地址8F2078h开始的跳转表包含5个条目:

8F2078h: 1B 20 8F 00  ; 指向 case 1 (8F201Bh)
8F207Ch: 27 20 8F 00  ; 指向 case 4 (8F2027h)  
8F2080h: 33 20 8F 00  ; 指向 case 7 (8F2033h)
8F2084h: 3F 20 8F 00  ; 指向 case 10 (8F203Fh)
8F2088h: 4B 20 8F 00  ; 指向 case 13 (8F204Bh)

5. 各case块执行

; case 1
008F201B  push        0Ah        ; 10
008F201D  call        output
008F2025  jmp         008F2061h; case 4  
008F2027  push        1Eh        ; 30
008F2029  call        output
008F2031  jmp         008F2061h; case 7
008F2033  push        32h        ; 50
008F2035  call        output
008F203D  jmp         008F2061h; case 10
008F203F  push        46h        ; 70
008F2041  call        output
008F2049  jmp         008F2061h; case 13
008F204B  push        5Ah        ; 90
008F204D  call        output
008F2055  jmp         008F2061h; default
008F2057  push        0
008F2059  call        output

关键特征总结

  1. 两级跳转表:

    • 第一级:字节索引表,将输入值映射到跳转表索引
    • 第二级:地址跳转表,执行实际跳转
  2. 内存优化: 使用字节数组作为索引表,比直接使用地址表更节省内存

  3. 稀疏值处理: 虽然case值有固定间隔(3),但编译器仍然使用两级表而不是简单计算

  4. O(1)时间复杂度: 通过两级查表实现常数时间跳转

  5. 紧凑的范围检查: 检查value是否在1-13范围内

对应的C++代码推测

void switch_small_gaps(int value) {switch (value) {case 1: output(10); break;case 4: output(30); break;case 7: output(50); break; case 10: output(70); break;case 13: output(90); break;default: output(0); break;}
}

优化策略分析

编译器选择两级跳转表优化是因为:

  • case值稀疏但范围紧凑:值分布在1-13范围内
  • 内存效率:字节索引表(13字节) + 地址跳转表(20字节) = 33字节
  • 相比单级跳转表:直接使用地址表需要13×4=52字节,节省了19字节
  • 相比条件链:提供O(1)性能而非O(n)

这种优化在case值相对稀疏但分布在一定连续范围内时特别有效,在性能和内存使用之间取得了良好平衡。

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

相关文章:

  • flash手机网站制作商家小程序怎么制作
  • 建设部指定招标网站phpcms做网站好吗
  • 桶装水网站建设江苏SEO网站建设
  • seo数据优化教程seo 网站title
  • (论文速读)文本引导的可探索图像超分辨率
  • 网站开发十大公司wordpress如何修改后台登录地址
  • 网站创建做网站分什么软件
  • 好的做淘宝详情页的网站有哪些分销网络建设
  • AI协同编程架构师岗位的诞生
  • 网站首页尺寸深圳龙华租房
  • wordpress网站好优化吗做网站难度大吗
  • 谷歌 Gemini 2.5 Pro 免费王炸 AI 战场格局剧变
  • 数据结构之线性表——循环链表
  • 百度竞价做网站建设安阳百度贴吧
  • 周学习记录分享
  • SQL Server从入门到项目实践(超值版)读书笔记 28
  • 2020年08月份04741计算机网络原理真题及答案
  • 第22讲:动态内存管理
  • 将 XMind 测试用例转换为 CSV 文件导入测试管理平台
  • 网站开发用什么语言写免费网站域名注册个人
  • ORB_SLAM2原理及代码解析:Viewer 线程——Viewer::Run()
  • FullCalendar:现代Web应用中的专业日历解决方案
  • 商城网站设计图哈尔滨网站建设贴吧
  • Windows安装MongoDB保姆级教程(图文详解)
  • 生活中花钱请人做网站昆明公司网站制作
  • 东莞专业网站推广平台网站功能价格表
  • 博客网站的建设流程邯郸网站建设网页设计网络推广
  • wordpress 发布站重庆响应式网站建设
  • 建网站联系电话上海公司注册核名查询
  • 制作企业网站价格网页版梦幻西游大闹天宫八卦炉