Delphi - 条件判断那些事
技术交流,DH讲解.
之前照着天书夜读,用Delphi来弄了下循环体,现在就来弄一下条件判断吧.
首先肯定是我们经常看见的IF语句咯.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Var I: Integer ; Begin I:= 99 ; If (I> 0 ) And (I< 0 ) Then Writeln ( 'I>0' ) Else If (I> 10 ) And (I< 100 ) Then Writeln ( 'I>10 and I<100' ) Else Writeln ( 'I>100' ); End . |
反汇编出来会是什么样子的呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | Project5 . dpr .12 : I:= 99 ; 004AC44C B863000000 mov eax, $00000063 Project5 . dpr .13 : If (I> 0 ) And (I< 0 ) Then 004AC451 85C0 test eax,eax 004AC453 7E1F jle $004ac474 004AC455 85C0 test eax,eax 004AC457 7D1B jnl $004ac474 Project5 . dpr .14 : Writeln ( 'I>0' ) 004AC459 A1DC314B00 mov eax,[ $004b31dc ] 004AC45E BAC4C44A00 mov edx, $004ac4c4 004AC463 E874BAF5FF call @Write0UString 004AC468 E8BF89F5FF call @ WriteLn 004AC46D E83E7FF5FF call @_IOTest 004AC472 EB3E jmp $004ac4b2 Project5 . dpr .16 : If (I> 10 ) And (I< 100 ) Then 004AC474 83F80A cmp eax, $0a 004AC477 7E20 jle $004ac499 004AC479 83F864 cmp eax, $64 004AC47C 7D1B jnl $004ac499 Project5 . dpr .17 : Writeln ( 'I>10 and I<100' ) 004AC47E A1DC314B00 mov eax,[ $004b31dc ] 004AC483 BAD8C44A00 mov edx, $004ac4d8 004AC488 E84FBAF5FF call @Write0UString 004AC48D E89A89F5FF call @ WriteLn 004AC492 E8197FF5FF call @_IOTest 004AC497 EB19 jmp $004ac4b2 Project5 . dpr .19 : Writeln ( 'I>100' ); 004AC499 A1DC314B00 mov eax,[ $004b31dc ] 004AC49E BA04C54A00 mov edx, $004ac504 004AC4A3 E834BAF5FF call @Write0UString 004AC4A8 E87F89F5FF call @ WriteLn 004AC4AD E8FE7EF5FF call @_IOTest |
我们这里就容易得出来Delphi里面IF语句的结构了.
判断1
不满足就跳-------------------------|
满足条件代码 |
[无条件Jmp到所有判断外] |
[判断2] <------|
...............................................
就是这样的
在IF的反汇编上面 和 书中的VC反汇编出来的代码差不多.
接下来就是看switch语句(Delphi里面的Case):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | Var I: Integer ; Begin I:= 9 ; Case I Of 0 : Writeln ( '0' ); 1 : Writeln ( '1' ); 2 : Writeln ( '2' ); 3 : Writeln ( '3' ); 4 : Writeln ( '4' ); 5 : Writeln ( '5' ); 6 : Writeln ( '6' ); 7 : Writeln ( '7' ); Else Writeln ( '0' ); End ; End . |
反汇编一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | Project5 . dpr .12 : I:= 9 ; 004AC44C B809000000 mov eax, $00000009 Project5 . dpr .13 : Case I Of 004AC451 83F807 cmp eax, $07 004AC454 0F8703010000 jnbe $004ac55d 004AC45A FF248561C44A00 jmp dword ptr [eax* 4 + $4ac461 ] 004AC461 81C44A009EC4 add esp, $c49e004a 004AC467 4A dec edx 004AC468 00BBC44A00D8 add [ebx- $27ffb53c ],bh 004AC46E C44A00 les ecx,[edx+ $00 ] 004AC471 F5 cmc 004AC472 C44A00 les ecx,[edx+ $00 ] 004AC475 0FC54A0029 pextrw ecx,qword ptr [edx+ $00 ], $29 004AC47A C54A00 lds ecx,[edx+ $00 ] 004AC47D 43 inc ebx 004AC47E C54A00 lds ecx,[edx+ $00 ] Project5 . dpr .15 : Writeln ( '0' ); 004AC481 A1DC314B00 mov eax,[ $004b31dc ] 004AC486 66BA3000 mov dx, $0030 004AC48A E8DDADF5FF call @Write0WChar 004AC48F E89889F5FF call @ WriteLn 004AC494 E8177FF5FF call @_IOTest 004AC499 E9D7000000 jmp $004ac575 Project5 . dpr .17 : Writeln ( '1' ); 004AC49E A1DC314B00 mov eax,[ $004b31dc ] 004AC4A3 66BA3100 mov dx, $0031 004AC4A7 E8C0ADF5FF call @Write0WChar 004AC4AC E87B89F5FF call @ WriteLn 004AC4B1 E8FA7EF5FF call @_IOTest 004AC4B6 E9BA000000 jmp $004ac575 Project5 . dpr .19 : Writeln ( '2' ); 004AC4BB A1DC314B00 mov eax,[ $004b31dc ] 004AC4C0 66BA3200 mov dx, $0032 004AC4C4 E8A3ADF5FF call @Write0WChar 004AC4C9 E85E89F5FF call @ WriteLn 004AC4CE E8DD7EF5FF call @_IOTest 004AC4D3 E99D000000 jmp $004ac575 Project5 . dpr .21 : Writeln ( '3' ); 004AC4D8 A1DC314B00 mov eax,[ $004b31dc ] 004AC4DD 66BA3300 mov dx, $0033 004AC4E1 E886ADF5FF call @Write0WChar 004AC4E6 E84189F5FF call @ WriteLn 004AC4EB E8C07EF5FF call @_IOTest 004AC4F0 E980000000 jmp $004ac575 Project5 . dpr .23 : Writeln ( '4' ); 004AC4F5 A1DC314B00 mov eax,[ $004b31dc ] 004AC4FA 66BA3400 mov dx, $0034 004AC4FE E869ADF5FF call @Write0WChar 004AC503 E82489F5FF call @ WriteLn 004AC508 E8A37EF5FF call @_IOTest 004AC50D EB66 jmp $004ac575 Project5 . dpr .25 : Writeln ( '5' ); 004AC50F A1DC314B00 mov eax,[ $004b31dc ] 004AC514 66BA3500 mov dx, $0035 004AC518 E84FADF5FF call @Write0WChar 004AC51D E80A89F5FF call @ WriteLn 004AC522 E8897EF5FF call @_IOTest 004AC527 EB4C jmp $004ac575 Project5 . dpr .27 : Writeln ( '6' ); 004AC529 A1DC314B00 mov eax,[ $004b31dc ] 004AC52E 66BA3600 mov dx, $0036 004AC532 E835ADF5FF call @Write0WChar 004AC537 E8F088F5FF call @ WriteLn 004AC53C E86F7EF5FF call @_IOTest 004AC541 EB32 jmp $004ac575 Project5 . dpr .29 : Writeln ( '7' ); 004AC543 A1DC314B00 mov eax,[ $004b31dc ] 004AC548 66BA3700 mov dx, $0037 004AC54C E81BADF5FF call @Write0WChar 004AC551 E8D688F5FF call @ WriteLn 004AC556 E8557EF5FF call @_IOTest 004AC55B EB18 jmp $004ac575 Project5 . dpr .31 : Writeln ( '0' ); 004AC55D A1DC314B00 mov eax,[ $004b31dc ] 004AC562 66BA3000 mov dx, $0030 004AC566 E801ADF5FF call @Write0WChar 004AC56B E8BC88F5FF call @ WriteLn 004AC570 E83B7EF5FF call @_IOTest |
在这里我们看到了一个Delphi的优化,它首先把I和7比,如果大于就直接跳到else语句那里.
如果小于等于,我们看到是无条件Jmp到一个I为等间距偏移的地方,也就是每个writeln语句是等大小的.
要是我们改成不是01234567呢?大家自己试一下,不是等距case代码还是没有变.
而VC里面会怎么样?
cmp->je->cmp->je->cmp->je
就是这样不停的对比,如果相等就跳.这样符合我们思维一些.
好的,这书这一节会有一个课后题.哈哈,我也去做一下.
下一次讲下结构体 反汇编的东西吧.
分类:
Delphi基础
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 【非技术】说说2024年我都干了些啥