• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

Delphi-循环的秘密

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

技术交流,DH讲解.

哈哈,我承认我是标题党.
最近看天书夜读里面是对C语言的代码反汇编,不错,可惜Delphi没有这样的书,那我们自己动手吧.
首先进入For循环了.

Function TestFor( a, b: Integer ): Integer ;
Var
  I: Integer ;
Begin
  Result := a + b ;
  For I := 0 To 49 Do
    Result := Result + I ;
End ;
{$R *.dfm}

Procedure TForm1.btn1Click( Sender: TObject ) ;
Begin
  ShowMessage( IntToStr( TestFor( 1, 2 ) ) ) ;
End ;

反汇编代码:

Unit4.pas.28: Result := a + b ;
00523AE0 03D0             add edx,eax //执行a+b,但是我很奇怪为什么不用add eax,edx 这样最后就不用执行那句mov eax,edx了,节约一句
Unit4.pas.29: For I := 0 To 49 Do
00523AE2 33C0             xor eax,eax //清除eax,来充当I这个循环变量
Unit4.pas.30: Result := Result + I ;
00523AE4 03D0             add edx,eax //累计和,并把循环变量+1,这里就是循环体的执行代码
00523AE6 40               inc eax
Unit4.pas.29: For I := 0 To 49 Do
00523AE7 83F832           cmp eax,$32 //边界比较,不等于就跳回去,继续执行循环体代码.
00523AEA 75F8             jnz $00523ae4 //看来还是再写个函数来看看
Unit4.pas.31: End ;
00523AEC 8BC2             mov eax,edx
00523AEE C3               ret 

对比书中C的反汇编代码,Delphi反汇编出来的代码很精简,虽然声明了局部变量,但是函数直接用寄存器代替了.很好.
书中C循环体先直接用Jmp跳过去与临界变量比较,然后再来看是否执行循环体,而改变循环变量它用了add eax,1,然后再把eax传给栈上面的I.
后来我尝试改成0 to -1 Delphi编译器会识别出来,然后不会添加任何循环代码到函数中去的.

接下来是do循环,也就是Repeat

function TestRepeat(a,b:Integer):Integer ;
var
  I:Integer;
begin
  Result:=a + b;
  I:=0;
  repeat
    Result:= Result + I;
    Inc(I);
  until I = 50;
end;

反汇编代码:

Unit4.pas.30: Result:=a + b;
00523AE0 03D0             add edx,eax
Unit4.pas.31: I:=0;
00523AE2 33C0             xor eax,eax
Unit4.pas.33: Result:= Result + I;
00523AE4 03D0             add edx,eax
Unit4.pas.34: Inc(I);
00523AE6 40               inc eax
Unit4.pas.35: until I = 50;
00523AE7 83F832           cmp eax,$32
00523AEA 75F8             jnz $00523ae4
Unit4.pas.36: end;
00523AEC 8BC2             mov eax,edx
00523AEE C3               ret 

我们发现反汇编代码和For是一样的.
这段代码就和VC反编译出来的差不多了,先执行循环体然后再比较边界.
好,看看while呢?

Function TestWhile(A, B: Integer): Integer;
Var
  I: Integer;
Begin
  Result:= A+ B;
  I:= 0;
  While I< 50 Do
  Begin
    Result:= Result+ I;
    Inc(I);
  End;
End;

反汇编代码:

Unit4.pas.38: Result:= A+ B;
00523AE0 03D0             add edx,eax
Unit4.pas.39: I:= 0;
00523AE2 33C0             xor eax,eax
Unit4.pas.42: Result:= Result+ I;
00523AE4 03D0             add edx,eax
Unit4.pas.43: Inc(I);
00523AE6 40               inc eax
Unit4.pas.40: While I< 50 Do
00523AE7 83F832           cmp eax,$32
00523AEA 7CF8             jl $00523ae4
Unit4.pas.45: End;
00523AEC 8BC2             mov eax,edx
00523AEE C3               ret 

我晕,居然还是一样的.也就是Delphi里面3种循环执行效率是一样的吧.
而VC同样是先初始化循环变量,然后无条件跳转到边界检测,然后才执行循环体代码.
循环就这么多,以后该是条件判断


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
MATLAB三维作图——隐函数发布时间:2022-07-18
下一篇:
小小知识点(三)——MATLAB如何把三维图用二维图表示发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap