Beispiele für die Verwendung von Assembly in Delphi
-----Ebenfalls ein Student im zweiten Jahr, dem vorherigen Beispiel folgend. Haha, das Programm war etwas chaotisch, als ich es geschrieben habe, bitte verzeihen Sie mir :).
Die Verwendung von Assembly für die Hybridprogrammierung in Delphi ist ungewöhnlich praktisch. Auf diese Weise können Sie, wenn Sie die Effizienz steigern möchten, die Montage wählen, aber für die meisten Arbeiten genießen Sie immer noch den Komfort der visuellen und objektorientierten Programmierung. In der Delphi-Sprache können durch die Verwendung des Programmsegments asm...end zum Schreiben des Assemblercodeteils Hochsprachenvariablen im Assemblercodesegment aufgerufen werden, worauf Sie achten müssen, um bestimmte Registervariablen zu schützen Dann einige Details und Dos. Die folgende Zusammenstellung ist anders. Schauen Sie sich dieses Beispiel an.
Lassen Sie uns zunächst über etwas Allgemeinwissen sprechen:
1. Es gibt zwei Möglichkeiten, Assembly in Delphi aufzurufen.
Genau wie---
PROzedur TForm1.DrawRain;
var
x1,y1,x2,y2,d,i:integer;
begin//delphi-Programm startet
für i:=0 bis 100 do
beginnen
x1:=random(537);
y1:=random(280);
d:=random(7);
Die asm//embedded-Assembly beginnt
eax drücken
mov eax,x1
subeax,d
mov x2,eax
mov eax,y1
eax,d hinzufügen
mov y2,eax
Pop Eax
end;;//Ende der eingebetteten Baugruppe
mal:=mal+1;
drawLine2(x1,y1,x2,y2,clmedGray);
Warten();
if (i div 2)=0 then drawLine2(x1,y1,x2,y2,clwindow);
Ende;
end;//delphi-Programm endet
Es gibt eine andere Möglichkeit, das äußere begin...end zu entfernen und direkt über asm...end in die Assembly einzutreten.
Prozedur TForm1.Wait();
Die asm//embedded-Assembly beginnt
eax drücken
mov eax,0
@Schleife:
eax,1 hinzufügen
cmp eax,1000000
jnz @loop
Pop Eax
end;//Ende der Inline-Assembly
2. Verwenden Sie Delphi-Variablen in der Assembly
Wenn Sie sich das erste Codebeispiel ansehen, ist es leicht zu verstehen:
Die asm//embedded-Assembly beginnt
eax drücken
mov eax,x1 //x1 ist eine lokale Delphi-Variable, die hier als Wert verwendet wird
subeax,d
mov x2,eax //x2 ist eine lokale Delphi-Variable und wird auch als Speicheradresse verwendet
mov eax,y1
eax,d hinzufügen
mov y2,eax
Pop Eax
end;;//Ende der eingebetteten Baugruppe
3. Verschiedene Details der Zusammenstellung
Ich werde die Beispiele nicht veröffentlichen. Vergleichen wir sie zum Beispiel:
@Schleife:
//......
jnz @loop
Darüber hinaus sind die meisten Int-Interrupts möglicherweise nicht verfügbar und ich habe keine Informationen dazu gesehen. Wer weiß, bitte senden Sie mir eine Nachricht? Vielen Dank im Voraus.
Unten sehen Sie ein größeres Beispiel eines Animationseffekts. Da ich in der Vergangenheit gerade erst angefangen habe, mir dieses Wissen anzueignen, war meine Erfahrung sehr schwierig. Es handelt sich um eine Szene mit ständigem Regen in einem kleinen Wald – es gibt viele Probleme, das auffälligste ist, dass erstens die Gleitkomma-Anweisungen nicht verwendet werden (ich werde Testbeispiele für Gleitkomma-Anweisungen anhängen, die später ausprobiert werden sollen). ), Einige Algorithmen waren damals noch nicht bekannt und das Ergebnis war ein eher eintöniges Bild. Zweitens war die Abstimmung zwischen den Landschaften nicht gut genug. Beispielsweise waren die Bäume nicht wirksam geschützt und wurden später durch den Regen „blüht“. :).
Aber ich gebe immer noch ein Beispiel. Erstens habe ich keine Zeit, Beispiele in diesem Bereich zu schreiben. Wenn Sie lernen, wie man Assembler in Delphi verwendet, kann dies immer noch der Fall sein. Darüber hinaus wird diese Anwendung in allgemeinen Materialien vermieden. Sie wird gelegentlich in einigen fortgeschrittenen Programmiersprachen erwähnt, aber wenn Sie sie beherrschen möchten, müssen Sie sie meist selbst üben.
Einheit Einheit1;
Schnittstelle
verwendet
Windows, Nachrichten, SysUtils, Varianten, Klassen, Grafiken, Steuerelemente, Formulare,
Dialoge, ExtCtrls, Menüs, ExtDlgs, FileCtrl, StdCtrls, ComCtrls, ImgList;
Typ
TForm1 = Klasse(TForm)
MainMenu1: TMainMenu;
Datei1: TMenuItem;
Exit1: TMenuItem;
N1: TMenuItem;
Hilfe1: 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);
Privat
procedure DrawLine1(x1,y1,x2,y2:integer;icolor:TColor);// x2>x1 und y2>y1
procedure DrawLine2(x1,y1,x2,y2:integer;icolor:TColor);// x2<x1 und y2>y1
procedure DrawLine3(x1,y1,x2,y2:integer;iColor:TColor);// x1=x2 oder y1=y2
Prozedur DrawRain;
procedure DrawTree(x,y,height:integer);
procedure Timer1Timer(sender:TObject);
Prozedur drawClear;
Prozedur Wait();
{Private Erklärungen}
öffentlich
{Öffentliche Erklärungen}
Ende;
var
Form1: TForm1;
mal:einzeln;
Durchführung
verwendet Unit3,Unit5;
{$R *.dfm}
Prozedur TForm1.Wait();
asm
eax drücken
mov eax,0
@Schleife:
eax,1 hinzufügen
cmp eax,1000000
jnz @loop
Pop Eax
Ende;
procedure TForm1.DrawLine1(x1,y1,x2,y2:integer;iColor:TColor);
const i:integer=1;
var j,k1,k2,d:integer;
beginnen
if((x2-x1)<=0)or((y2-y1)<=0) then beenden;
für j:=0 bis (x2-x1) tun
beginnen
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);
wenn ((x2-x1)=0)oder((y2-y1)=0) dann beenden;
asm
eax drücken
pushebx
pushecx
edx drücken
mov ecx,0
mov eax,x2
subeax,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:
eax,i hinzufügen
Incecx
cmpecx,k2
jb @loop2
mov x1,eax
mov eax,y1
@loop1:
eax,i hinzufügen
Incecx
cmpecx,k1
jb @loop1
mov y1,eax
Pop-Edx
popecx
Pop EBX
Pop Eax
Ende;
Ende;// Ende für
Ende;
procedure TForm1.DrawLine2(x1,y1,x2,y2:integer;icolor:TColor);
const i:integer=1;
var j,k1,k2,d:integer;
beginnen
if((x1-x2)<=0)or((y2-y1)<=0) then exit;
für j:=0 bis (x1-x2) tun
beginnen
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);
wenn ((x1-x2)=0)oder((y2-y1)=0) dann beenden;
asm
eax drücken
pushebx
pushecx
edx drücken
mov ecx,0
mov eax,x1
subeax,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, ich
Incecx
cmpecx,k2
jb @loop2
mov x1,eax
mov eax,y1
@loop1:
eax,i hinzufügen
Incecx
cmpecx,k1
jb @loop1
mov y1,eax
Pop-Edx
popecx
Pop EBX
Pop Eax
Ende;
Ende;// Ende für
Ende;
procedure TForm1.DrawLine3(x1,y1,x2,y2:integer;icolor:TColor);
var j:integer;
beginnen
if((x2-x1)<>0)and((y2-y1)<>0) then exit;
wenn (x2-x1)=0 dann
für j:=0 bis (y2-y1) tun
beginnen
form1.Canvas.Pen.Color:=icolor;
form1.Canvas.Ellipse(x1-1,y1-1,x1+1,y1+1);
wenn (y2-y1)=0, dann beenden;
asm
eax drücken
mov eax,y1
inc. eax
mov y1,eax
Pop Eax
Ende;
Ende// Ende für
sonst gilt für j:=0 bis (x2-x1).
beginnen
form1.Canvas.Pen.Color:=icolor;
form1.Canvas.Ellipse(x1-1,y1-1,x1+1,y1+1);
wenn (x2-x1)=0, dann beenden;
asm
eax drücken
mov eax,x1
inc. eax
mov x1,eax
Pop Eax
Ende;
Ende;// Ende für
Ende;
procedure TForm1.Timer1Timer(sender:TObject);
beginnen
Ende;
procedure TForm1.DrawRain;
var
x1,y1,x2,y2,d,i:integer;
beginnen
für i:=0 bis 100 do
beginnen
x1:=random(537);
y1:=random(280);
d:=random(7);
asm
eax drücken
mov eax,x1
subeax,d
mov x2,eax
mov eax,y1
eax,d hinzufügen
mov y2,eax
Pop Eax
Ende;
mal:=mal+1;
drawLine2(x1,y1,x2,y2,clmedGray);
Warten();
if (i div 2)=0 then drawLine2(x1,y1,x2,y2,clwindow);
Ende;
Ende;
procedure TForm1.DrawTree(x,y,height:integer);
var
x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,d1:integer;
beginnen
asm
eax drücken
pushebx
pushecx
edx drücken
mov eax,height
mov edx,0
mov ecx,2
divecx
mov d1,eax
mov eax,x
mov ebx,y
sub eax,höhe
mov x1,eax
sub ebx,height
mov y1,ebx
eax,height hinzufügen
subeax,5
sub ebx,height
mov x2,eax
mov y2,ebx
mov eax,x
eax,3 hinzufügen
sub ebx,height
mov x3,eax
mov y3,ebx
eax,8 hinzufügen
ebx,height hinzufügen
mov x4,eax
mov y4,ebx
eax,height hinzufügen
subeax,5
ebx,height hinzufügen
mov x5,eax
mov y5,ebx
Pop-Edx
popecx
Pop EBX
Pop Eax
Ende;
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);
Ende;
procedure TForm1.Exit1Click(Sender: TObject);
beginnen
schließen;
Ende;
procedure TForm1.About1Click(Sender: TObject);
beginnen
form3.Show;
Ende;
procedure TForm1.Spring1Click(Sender: TObject);
var i,k,j:integer;
beginnen
StatusBar1.Panels[1].text:='Der Frühling des Sturms...';
form1.Canvas.Brush.Color:=clwindow;
form1.Canvas.FloodFill(1,1,clred,fsBorder);
für i:=0 bis 10do
beginnen
k:=random(10);
j:=random(10);
j:=-j;
drawTree(10+k*50,300+j*20,20);
Ende;
für i:=0 bis 10 do
beginnen
form1.Canvas.Brush.Color:=clwindow;
form1.Canvas.FloodFill(1,1,clgreen,fsBorder);
drawRain;
Schlaf(100);
Ende;
Ende;
procedure TForm1.FormCreate(Sender: TObject);
beginnen
mal:=0;
form1.canvas.Brush.Color:=clwindow;
form1.caption:=form1.caption+' Bitte wählen Sie den Bildtyp aus!... ';
Ende;
Prozedur TForm1.drawClear;
var i,k:integer;
beginnen
form1.Canvas.Brush.Color:=clblack;
form1.Canvas.FloodFill(15,15, clcream, fsBorder);
for i:=0 to 5 do
beginnen
k:=random(300);
DrawLine3(20+k,1,20+k,307,clgelb);
DrawLine3(200+k,1,200+k,307,clgelb);
Ende;
Ende;
procedure TForm1.Summer1Click(Sender: TObject);
beginnen
drawClear;
form1.Canvas.Font.Color:=clblue;
form1.Canvas.Font.Size:=18;
form1.canvas.textOut(150,150,'Grüner Ozean...Ruhezeit^_^!');
//DrawTree;
Ende;
procedure TForm1.Autumn1Click(Sender: TObject);
beginnen
drawClear;
form1.Canvas.Font.Color:=clblue;
form1.Canvas.Font.Size:=18;
form1.canvas.textOut(150,150,'Rote Blätter und duftende Berge...ruhen^_^!');
Ende;
procedure TForm1.Winter1Click(Sender: TObject);
//var i,x,y:integer;
beginnen
drawClear;
form1.Canvas.Font.Color:=clblue;
form1.Canvas.Font.Size:=18;
form1.canvas.textOut(150,150,'Silberner Schlangenwachs-Elefant...noch nicht geöffnet^_^!');
Ende;
procedure TForm1.ext1Click(Sender: TObject);
beginnen
form5.Show;
Ende;
Ende.
Das Folgende ist das beigefügte Testprogramm mit Gleitkommaanweisungen. Die damalige Originalversion erzielte den Effekt nicht :):
//Weisen Sie die Bibliothek an, dies zu überprüfen:)
Prozedur Tform1.xx;
var
xmax,ymax,x,y,a,b:single;
i,z:integer;
beginnen
a:=2,0;b:=10,0;
xmax:=image1.Width;
ymax:=image1.Height;
for i:=0 to image1.Width do
beginnen
asm
//.80x87
endlich
fld xmax //xmax in st(0) schieben
fdiv a
fchs //let st(0)=-st(0)
fadd i //st(0)=st(0)+i
fdiv b //st(0)=st(0)/b
fstp x //setze st(0) in x ohne Pop
X
fmul x
fchs
fadd ymax
//frndint
//fabs
fstp y
Ende;
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];
Ende;
Ende;
Ich habe mich für einen der Prozesse entschieden, haha, lustig.
Du kannst genauso gut deine Sachen rausholen und deine Erfahrungen teilen, ich bin bereit zuzuhören :).
Bitte----