Delphi 条件判断那些事

摘要:
技术交流和DH解释。之前,我们根据天书使用Delphi制作下环体。现在让我们做出有条件的判断。首先,它必须是我们经常看到的IF语句。VarI:整数;BeginI:=99;如果(I˃0)和(I˂0)ThenWrittenElseIf和ThenWritenElseWriteln;拆卸后,末端会是什么样子?

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

免责声明:文章转载自《Delphi 条件判断那些事》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇继续推荐几款VisualStudio的插件(二)wpa_supplicant 常用操作下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Delphi中的操作二进制文件的两个重要函数

Delphi中的操作二进制文件的两个重要函数 对于通过Byte数组进行文件操作的,在FTP中经常会使用到,我也是在Delphi调用Web Service进行文件的上传和下载时找到这两个函数的,挺好用的,推荐给大家。(申明:非本人所写) 1. 将Byte数组生成文件 procedureByteArrayToFile(constByteArray : TB...

Delphi下使用指针的简单总结(指针的赋值,数组和指针的转换,函数指针的使用)

由于最近公司太忙,好久没有更新我的BLOG了。原来想着写写关于HOOK驱动的文章,可是最后想想好久已经没有做驱动的东西了,怕写出来有错误,于是作罢。开发游戏也有一段时间了,发现使用DELPHI来开发网络游戏不了解DELPHI下指针的使用是完全不行的。所以今天我简单总结以下我使用DELPHI指针的心得。希望对大家有所帮助。 记得在大学学习C语言的时候在谭浩强...

Delphi 编译程序乱码(非中文系统)的处理

Delphi 编译程序乱码(非中文系统)的处理 Delphi7 编译的程序是 非unicode程序,在非中文系统环境下,会出现乱码 方法一: 1、在控制面板,区域-格式:  2、区域,管理,设置:  3、在主界面程序里面加 initialization SetThreadLocale($0804); //2052 setconsoleoutpu...

delphi 中record 的类操作符重载简介

今天简单介绍一下 delphi 中record 的类操作符重载使用,就是如何 实现 record 之间的简单操作。 关于类操作符重载 ,大家可以看 官方的文档。 Delphi allows certain functions, or "operators", to be overloaded within record declarations. The...

Delphi XE5教程2:程序组织

内容源自Delphi XE5 UPDATE 2官方帮助《Delphi Reference》,本人水平有限,欢迎各位高人修正相关错误! 也欢迎各位加入到Delphi学习资料汉化中来,有兴趣者可QQ:34484690@qq.com   1 Program Organization 1         程序组织 Delphi programs are usuall...

Delphi中的Sender:TObject对象解析

procedure TForm1.Button1Click(Sender: TObject); begin end; 解析:Procedure是过程,TForm是窗体类,加上数字就是某个窗体,像TForm1就是Form1窗体。 Button1是你的按钮控件的名称,Button1Click就是按钮的单击事件,(Sender:Tobject)就是发送消息到对象...