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

  • 相关阅读:
    PAT 解题报告 1009. Product of Polynomials (25)
    PAT 解题报告 1007. Maximum Subsequence Sum (25)
    PAT 解题报告 1003. Emergency (25)
    PAT 解题报告 1004. Counting Leaves (30)
    【转】DataSource高级应用
    tomcat下jndi配置
    java中DriverManager跟DataSource获取getConnection有什么不同?
    理解JDBC和JNDI
    JDBC
    Dive into python 实例学python (2) —— 自省,apihelper
  • 原文地址:https://www.cnblogs.com/huangjacky/p/1663847.html
Copyright © 2011-2022 走看看