• Delphi 条件判断那些事


    技术交流,DH讲解.

    之前照着天书夜读,用Delphi来弄了下循环体,现在就来弄一下条件判断吧.
    首先肯定是我们经常看见的IF语句咯.

    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.

    反汇编出来会是什么样子的呢?

    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):

    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.

    反汇编一下:

    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
    就是这样不停的对比,如果相等就跳.这样符合我们思维一些.
    好的,这书这一节会有一个课后题.哈哈,我也去做一下.
    下一次讲下结构体 反汇编的东西吧.

  • 相关阅读:
    Bootstrap中,模态框嵌套模态框时,关闭第二个模态框时,导致第一个模态框的滚动条消失
    heidisql 远程登录本地虚拟机中的 MariaDB
    ssh-keygen -t rsa -C "content" 解释
    IIS 环境 CodeIgniter 隐藏 URL 中的 index.php
    Windows 环境下 PHP 安装 xdebug 及配置
    win10 更新后主机背部音频输出无声音
    MySql.Data.MySqlClient.MySqlException: Packets larger than max_allowed_packet are not allowed
    关于 IIS 中 iconfont.woff 报 404(Not Found) 的原因即解决方法
    IIS Web API 长时间不连接后第一次访问非常缓慢
    VS Code 中 HTML 文档注释 js 语句异常
  • 原文地址:https://www.cnblogs.com/huangjacky/p/1663847.html
Copyright © 2020-2023  润新知