飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 3508|回复: 1

Delphi+汇编例子

[复制链接]
  • TA的每日心情
    开心
    2019-9-19 16:05
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2007-2-12 10:14:44 | 显示全部楼层 |阅读模式
    简单的,你现在就可以试一试:)。


    -----以前学汇编的时候做的测试。第一个程序只是给您个印象,后面还有一个帖子,在详细说说。

    unit Unit1;

    interface

    uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, StdCtrls, ExtCtrls;

    type
    TForm1 = class(TForm)
    Shape1: TShape;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Button1: TButton;
    Button2: TButton;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    //procedure Button3Click(Sender: TObject);
    //procedure BtCalcuClick(sender: TObject);
    private
    { Private declarations }
    public
    { Public declarations }
    end;

    var
    Form1: TForm1;
    function Sum1(X,Y:integer):integer;
    function Sum2(X,Y:integer):integer;stdcall;
    function Sum3(var X,Y:integer):integer;stdcall;
    implementation

    {$R *.dfm}

    procedure TForm1.Button1Click(Sender: TObject);
    var
    i,j:integer;
    begin
    label1.Caption:=inttostr(sum1(2,3));
    label2.Caption:=inttostr(sum2(2,3));
    i:=2;
    j:=3;
    label3.Caption:=inttostr(sum1(i,j));
    end;

    //delphi程序求和
    function Sum1(X,Y:integer):integer;
    begin
    result:=X+Y;
    end;

    //汇编求和1---
    function Sum2(X,Y:integer):integer;stdcall;
    begin
    asm
    mov eax,X
    add eax,Y
    mov @result,eax
    end;
    end;
    //汇编求和2---
    function Sum3(var X,Y:integer):integer;stdcall;
    begin
    asm
    mov eax,X
    mov eax,[eax]
    mov edx,Y
    add eax,[edx]
    mov @result,eax
    end;
    end;


    procedure TForm1.Button2Click(Sender: TObject);
    begin
    close;
    end;

    {procedure TForm1.Button3Click(Sender: TObject);
    var
    QuitFlag:Boolean;
    OutBufPtr:Word;
    begin
    asm
    mov al,QuitFlag
    mov bx,OutBufPtr
    end;
    end;}

    end.
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2019-9-19 16:05
  • 签到天数: 4 天

    [LV.2]偶尔看看I

     楼主| 发表于 2007-2-12 10:15:31 | 显示全部楼层
    -----也是大二的,接着上一个例子。呵呵,程序当时写的有点乱,请原谅:)。

    Delphi中使用汇编进行混合编程,是异乎寻常的方便。如此,当你希望得到效率的时候,你可选择汇编,然而大部分工作,你仍是享受着可视化、面向对象编程的方便。delphi的语言,通过使用asm...end程序段写汇编代码部分,在汇编代码段中可以调用高级语言的变量;你需要注意的是,保护某些寄存器变量,然后呢,某些细节和dos下的汇编不同。大家看这个例子。
    先大体说说一些小知识:
    一,Delphi调用汇编,有两种方式。
    一如---
    procedure TForm1.DrawRain;
    var
    x1,y1,x2,y2,d,i:integer;
    begin//delphi程序开始
    for i:=0 to 100 do
    begin
    x1:=random(537);
    y1:=random(280);
    d:=random(7);
    asm//内嵌汇编开始
    push eax
    mov eax,x1
    sub eax,d
    mov x2,eax
    mov eax,y1
    add eax,d
    mov y2,eax
    pop eax
    end;;//内嵌汇编结束
    times:=times+1;
    drawLine2(x1,y1,x2,y2,clmedGray);
    wait();
    if (i div 2)=0 then drawLine2(x1,y1,x2,y2,clwindow);
    end;
    end;//delphi程序结束


    还有一种,把外层的begin...end去掉,通过asm...end直接进入汇编。

    procedure TForm1.Wait();
    asm//内嵌汇编开始
    push eax
    mov eax,0
    @loop:
    add eax,1
    cmp eax,1000000
    jnz @loop
    pop eax
    end;//内嵌汇编结束

    二,在汇编中使用delphi的变量

    大家看第一段代码的例子,很容易明白:
    asm//内嵌汇编开始
    push eax
    mov eax,x1 //x1是delphi局部变量,此处用作值
    sub eax,d
    mov x2,eax //x2是delphi局部变量,又用作内存地址
    mov eax,y1
    add eax,d
    mov y2,eax
    pop eax
    end;;//内嵌汇编结束

    三,汇编的不同细节

    例子不帖了,大家自己比较了,如
    @loop:
    //...
    jnz @loop
    另外,大部分int中断可能不能用,我没有试通,也没见什么资料上介绍过。谁知道,给我发个消息好吗?谢谢了先。

    下面是一个比较大的例子,是一个动画效果。因为以前刚开始学这方面的知识,做的很粗糙。是一个小树林里,不停的下着雨的场景---很多问题,表现突出的是,首先浮点指令没有会用(我在后面会附上有待继续尝试的浮点数指令的测试例子),一些算法当时还不会,结果画面比较单调,其次,对景物间的协调不够好,比如树没有有效保护,后来就被雨“花”了:)。
    可还是做例子了,大家别笑我,一来没时间写这方面的例子了,二来,学Delphi中的汇编使用,它还是可以说明某些问题的。而且,一般的资料上,是回避这个应用的,个别的高级编程中,偶尔提及,可大家要想掌握,大都得要自己多实践,这个例子可以个给你许多教训:)。

    unit Unit1;

    interface

    uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, ExtCtrls, Menus, ExtDlgs, FileCtrl, StdCtrls, ComCtrls, ImgList;

    type
    TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    Exit1: TMenuItem;
    N1: TMenuItem;
    Help1: TMenuItem;
    About1: TMenuItem;
    g1: TMenuItem;
    Spring1: TMenuItem;
    Summer1: TMenuItem;
    Autumn1: TMenuItem;
    Winter1: TMenuItem;
    StatusBar1: TStatusBar;
    ext1: TMenuItem;
    Timer1: TTimer;
    procedure Exit1Click(Sender: TObject);
    procedure About1Click(Sender: TObject);
    procedure Spring1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Summer1Click(Sender: TObject);
    procedure Autumn1Click(Sender: TObject);
    procedure Winter1Click(Sender: TObject);
    procedure ext1Click(Sender: TObject);
    private
    procedure DrawLine1(x1,y1,x2,y2:integer;icolor:TColor);// x2>x1 and y2>y1
    procedure DrawLine2(x1,y1,x2,y2:integer;icolor:TColor);// x2<x1 and y2>y1
    procedure DrawLine3(x1,y1,x2,y2:integer;iColor:TColor);// x1=x2 or y1=y2
    procedure DrawRain;
    procedure DrawTree(x,y,height:integer);
    procedure Timer1Timer(sender:TObject);
    procedure drawClear;
    procedure Wait();
    { Private declarations }
    public
    { Public declarations }
    end;

    var
    Form1: TForm1;
    times:single;
    implementation
    uses Unit3,Unit5;
    {$R *.dfm}

    procedure TForm1.Wait();
    asm
    push eax
    mov eax,0
    @loop:
    add eax,1
    cmp eax,1000000
    jnz @loop
    pop eax
    end;

    procedure TForm1.DrawLine1(x1,y1,x2,y2:integer;iColor:TColor);
    const i:integer=1;
    var j,k1,k2,d:integer;
    begin
    if((x2-x1)<=0)or((y2-y1)<=0) then exit;
    for j:=0 to (x2-x1) do
    begin
    form1.Canvas.Pen.Color:=icolor;
    form1.Canvas.Ellipse(x1,y1,x1+2,y1+2);
    form1.Canvas.Ellipse(x1-1,y1-1,x1+1,y1+1);
    if ((x2-x1)=0)or((y2-y1)=0) then exit;
    asm
    push eax
    push ebx
    push ecx
    push edx
    mov ecx,0
    mov eax,x2
    sub eax,x1
    mov ebx,y2
    sub ebx,y1
    mov d,ebx
    mov edx,0
    div d
    mov k2,eax

    mov eax,y2
    sub eax,y1
    mov ebx,x2
    sub ebx,x1
    mov d,ebx
    mov edx,0
    div d
    mov k1,eax

    mov eax,x1
    @loop2:
    add eax,i
    inc ecx
    cmp ecx,k2
    jb @loop2
    mov x1,eax

    mov eax,y1
    @loop1:
    add eax,i
    inc ecx
    cmp ecx,k1
    jb @loop1
    mov y1,eax

    pop edx
    pop ecx
    pop ebx
    pop eax
    end;
    end;// end for
    end;
    procedure TForm1.DrawLine2(x1,y1,x2,y2:integer;icolor:TColor);
    const i:integer=1;
    var j,k1,k2,d:integer;
    begin
    if((x1-x2)<=0)or((y2-y1)<=0) then exit;
    for j:=0 to (x1-x2) do
    begin
    form1.Canvas.Pen.Color:=icolor;
    form1.Canvas.Ellipse(x1,y1,x1+2,y1+2);
    form1.Canvas.Ellipse(x1-1,y1-1,x1+1,y1+1);
    if ((x1-x2)=0)or((y2-y1)=0) then exit;
    asm
    push eax
    push ebx
    push ecx
    push edx

    mov ecx,0

    mov eax,x1
    sub eax,x2
    mov ebx,y2
    sub ebx,y1
    mov d,ebx
    mov edx,0
    div d
    mov k2,eax

    mov eax,y2
    sub eax,y1
    mov ebx,x1
    sub ebx,x2
    mov d,ebx
    mov edx,0
    div d
    mov k1,eax

    mov eax,x1
    @loop2:
    sub eax,i
    inc ecx
    cmp ecx,k2
    jb @loop2
    mov x1,eax

    mov eax,y1
    @loop1:
    add eax,i
    inc ecx
    cmp ecx,k1
    jb @loop1
    mov y1,eax

    pop edx
    pop ecx
    pop ebx
    pop eax
    end;
    end;// end for
    end;
    procedure TForm1.DrawLine3(x1,y1,x2,y2:integer;icolor:TColor);
    var j:integer;
    begin
    if((x2-x1)<>0)and((y2-y1)<>0) then exit;
    if (x2-x1)=0 then
    for j:=0 to (y2-y1) do
    begin
    form1.Canvas.Pen.Color:=icolor;
    form1.Canvas.Ellipse(x1-1,y1-1,x1+1,y1+1);
    if (y2-y1)=0 then exit;
    asm
    push eax
    mov eax,y1
    inc eax
    mov y1,eax
    pop eax
    end;
    end// end for
    else for j:=0 to (x2-x1) do
    begin
    form1.Canvas.Pen.Color:=icolor;
    form1.Canvas.Ellipse(x1-1,y1-1,x1+1,y1+1);
    if (x2-x1)=0 then exit;
    asm
    push eax
    mov eax,x1
    inc eax
    mov x1,eax
    pop eax
    end;
    end;// end for
    end;
    procedure TForm1.Timer1Timer(sender:TObject);
    begin

    end;
    procedure TForm1.DrawRain;
    var
    x1,y1,x2,y2,d,i:integer;
    begin
    for i:=0 to 100 do
    begin
    x1:=random(537);
    y1:=random(280);
    d:=random(7);
    asm
    push eax
    mov eax,x1
    sub eax,d
    mov x2,eax
    mov eax,y1
    add eax,d
    mov y2,eax
    pop eax
    end;
    times:=times+1;
    drawLine2(x1,y1,x2,y2,clmedGray);
    wait();
    if (i div 2)=0 then drawLine2(x1,y1,x2,y2,clwindow);
    end;
    end;

    procedure TForm1.DrawTree(x,y,height:integer);
    var
    x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,d1:integer;
    begin
    asm
    push eax
    push ebx
    push ecx
    push edx
    mov eax,height
    mov edx,0
    mov ecx,2
    div ecx
    mov d1,eax
    mov eax,x
    mov ebx,y

    sub eax,height
    mov x1,eax
    sub ebx,height
    mov y1,ebx
    add eax,height
    sub eax,5
    sub ebx,height
    mov x2,eax
    mov y2,ebx
    mov eax,x
    add eax,3
    sub ebx,height
    mov x3,eax
    mov y3,ebx
    add eax,8
    add ebx,height
    mov x4,eax
    mov y4,ebx
    add eax,height
    sub eax,5
    add ebx,height
    mov x5,eax
    mov y5,ebx

    pop edx
    pop ecx
    pop ebx
    pop eax
    end;
    DrawLine2(x3,y3,x2-d1,y2,clcream);
    DrawLine1(x3,y3,x4+d1,y4,clcream);
    drawline3(x2-d1,y2,x2,y2,clcream);
    drawline3(x4,y4,x4+d1,y4,clcream);
    DrawLine2(x2,y2,x1,y1,clcream);
    DrawLine1(x4,y4,x5,y5,clcream);
    DrawLine2(x2+2,y2,x1,y1+2,clcream);
    DrawLine1(x4-2,y4,x5,y5+2,clcream);
    drawline3(x1,y1,x5,y5,clcream);
    drawline3(x1,y1-1,x5,y5-1,clcream);
    drawline3(x,y5,x,y,clcream);
    drawline3(x,y,x+5,y,clcream);
    drawline3(x+5,y5,x+5,y,clcream);
    form1.Canvas.Brush.Color:=clgreen;
    form1.Canvas.FloodFill(x,y1-5,clcream,fsBorder);
    form1.Canvas.FloodFill(x+2,y-5,clcream,fsBorder);

    end;
    procedure TForm1.Exit1Click(Sender: TObject);
    begin
    close;
    end;

    procedure TForm1.About1Click(Sender: TObject);
    begin
    form3.Show;
    end;

    procedure TForm1.Spring1Click(Sender: TObject);
    var i,k,j:integer;
    begin
    StatusBar1.Panels[1].text:='风雨之春...';
    form1.Canvas.Brush.Color:=clwindow;
    form1.Canvas.FloodFill(1,1,clred,fsBorder);
    for i:=0 to 10do
    begin
    k:=random(10);
    j:=random(10);
    j:=-j;
    drawTree(10+k*50,300+j*20,20);
    end;
    for i:=0 to 10 do
    begin
    form1.Canvas.Brush.Color:=clwindow;
    form1.Canvas.FloodFill(1,1,clgreen,fsBorder);
    drawRain;
    sleep(100);
    end;

    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    times:=0;
    form1.canvas.Brush.Color:=clwindow;
    form1.caption:=form1.caption+' Please select the Pictype!... ';
    end;
    procedure TForm1.drawClear;
    var i,k:integer;
    begin
    form1.Canvas.Brush.Color:=clblack;
    form1.Canvas.FloodFill(15,15, clcream, fsBorder);
    for i:=0 to 5 do
    begin
    k:=random(300);
    DrawLine3(20+k,1,20+k,307,clyellow);
    DrawLine3(200+k,1,200+k,307,clyellow);
    end;
    end;
    procedure TForm1.Summer1Click(Sender: TObject);
    begin
    drawClear;
    form1.Canvas.Font.Color:=clblue;
    form1.Canvas.Font.Size:=18;
    form1.canvas.textOut(150,150,'绿色海洋...休整时间^_^!');
    //DrawTree;

    end;

    procedure TForm1.Autumn1Click(Sender: TObject);
    begin
    drawClear;
    form1.Canvas.Font.Color:=clblue;
    form1.Canvas.Font.Size:=18;
    form1.canvas.textOut(150,150,'红叶香山...正在休整^_^!');
    end;

    procedure TForm1.Winter1Click(Sender: TObject);
    //var i,x,y:integer;
    begin
    drawClear;
    form1.Canvas.Font.Color:=clblue;
    form1.Canvas.Font.Size:=18;
    form1.canvas.textOut(150,150,'银蛇腊象...暂不开放^_^!');
    end;

    procedure TForm1.ext1Click(Sender: TObject);
    begin
    form5.Show;
    end;

    end.

    下面是附带的使用浮点数指令的测试程序,当时的原本,未达到效果的:):
    //指令图书馆查的:)
    procedure Tform1.xx;
    var
    xmax,ymax,x,y,a,b:single;
    i,z:integer;
    begin
    a:=2.0;b:=10.0;
    xmax:=image1.Width;
    ymax:=image1.Height;
    for i:=0 to image1.Width do
    begin
    asm
    //.80x87

    finit
    fld xmax //push xmax in st(0)
    fdiv a
    fchs //let st(0)=-st(0)
    fadd i //st(0)=st(0)+i
    fdiv b //st(0)=st(0)/b
    fstp x //put st(0) in x without pop
    fld x
    fmul x
    fchs
    fadd ymax
    //frndint
    //fabs
    fstp y
    end;
    x:=(i-xmax/2)/10;
    y:=-x*x+ymax;
    z:=trunc(z);
    image1.canvas.Ellipse(i-1,trunc(y)-1,i+1,trunc(y)+1);
    //image1.Canvas.Pixels[x,y];
    end;
    end;

    选的是其中一个过程,呵呵,见笑了。
    大家不妨把自己的东西拿出来,经验说一说,我准备洗耳恭听:)。
    请----
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表