Exemples d'utilisation de l'assembly dans Delphi
-----Également étudiant en deuxième année, suivant l'exemple précédent. Haha, le programme était un peu brouillon quand je l'ai écrit, s'il te plaît, pardonne-moi :).
L'utilisation de l'assembly pour la programmation hybride dans Delphi est particulièrement pratique. De cette façon, lorsque vous souhaitez gagner en efficacité, vous pouvez choisir l'assemblage, mais pour la plupart des travaux, vous bénéficiez toujours de la commodité de la programmation visuelle et orientée objet. En langage Delphi, en utilisant le segment de programme asm...end pour écrire la partie du code assembleur, des variables de langage de haut niveau peuvent être appelées dans le segment de code assembleur ; ensuite, quelques détails et choses à faire. La compilation ci-dessous est différente. Regardez cet exemple.
Parlons d’abord de quelques connaissances générales :
1. Il existe deux manières d’appeler assembly dans Delphi.
Tout comme ---
PRécédure TForm1.DrawRain;
var
x1,y1,x2,y2,d,i:entier ;
commencer//le programme Delphi démarre
pour i:=0 à 100 fais
commencer
x1:=aléatoire(537);
y1:=aléatoire(280);
d:=aléatoire(7);
asm // l'assemblage intégré démarre
pousser eax
déplacement eax,x1
sous-axe,d
mouvement x2,eax
déplacement eax,y1
ajouter eax,d
mouvement y2,eax
pop eax
end;;//Fin de l'assembly embarqué
fois :=fois+1 ;
drawLine2(x1,y1,x2,y2,clmedGray);
attendez();
si (i div 2)=0 alors drawLine2(x1,y1,x2,y2,clwindow);
fin;
fin;//le programme Delphi se termine
Il existe une autre façon de supprimer le début... la fin externe et d'entrer directement dans l'assemblage via asm... fin.
procédure TForm1.Wait();
asm // l'assemblage intégré démarre
pousser eax
déplacement eax,0
@boucle:
ajouter eax,1
cmp eax,1000000
jnz @loop
pop eax
fin;//fin de l'assemblage en ligne
2. Utiliser des variables Delphi dans l'assembly
Si vous regardez le premier exemple de code, il est facile de comprendre :
asm // l'assemblage intégré démarre
pousser eax
mov eax,x1 //x1 est une variable locale Delphi, utilisée comme valeur ici
sous-axe,d
mov x2,eax //x2 est une variable locale Delphi et est également utilisée comme adresse mémoire
déplacement eax,y1
ajouter eax,d
mouvement y2,eax
pop eax
end;;//Fin de l'assembly embarqué
3. Différents détails de la compilation
Je ne publierai pas les exemples. Comparons-les par nous-mêmes.
@boucle:
//...
jnz @loop
De plus, la plupart des interruptions int peuvent ne pas être disponibles. Je ne l'ai pas essayé et je n'ai vu aucune information à ce sujet. Qui sait, envoyez-moi un message s'il vous plaît ? Merci d'avance.
Vous trouverez ci-dessous un exemple plus grand d’un effet d’animation. Parce que j’ai juste commencé à acquérir ces connaissances dans le passé, mon expérience a été très difficile. C'est une scène de pluie constante dans une petite forêt --- il y a de nombreux problèmes, le plus important est que tout d'abord, les instructions à virgule flottante ne sont pas utilisées (je joindrai des exemples de test d'instructions à virgule flottante à essayer plus tard ), Certains algorithmes n'étaient pas connus à l'époque, et le résultat était une image plutôt monotone. Deuxièmement, la coordination entre les décors n'était pas assez bonne. Par exemple, les arbres n'étaient pas efficacement protégés et étaient ensuite « fleuris » par la pluie. :).
Mais je donne quand même un exemple. Ne vous moquez pas de moi. Premièrement, je n'ai pas le temps d'écrire des exemples dans ce domaine. Deuxièmement, si vous apprenez à utiliser l'assembly dans Delphi, cela peut encore expliquer certains problèmes. De plus, cette application est évitée dans les supports généraux. Elle est parfois mentionnée dans certaines programmations avancées, mais si vous souhaitez la maîtriser, vous devez surtout la pratiquer vous-même. Cet exemple peut vous apprendre beaucoup :).
unité Unité1 ;
interface
utilise
Windows, messages, SysUtils, variantes, classes, graphiques, contrôles, formulaires,
Boîtes de dialogue, ExtCtrls, Menus, ExtDlgs, FileCtrl, StdCtrls, ComCtrls, ImgList ;
taper
TForm1 = classe(TForm)
MenuMain1 : TMainMenu ;
Fichier1 : TMenuItem ;
Sortie1 : TMenuItem ;
N1 : TMenuItem ;
Aide1 : TMenuItem ;
À propos de1 : TMenuItem ;
g1 : TMenuItem ;
Printemps1 : TMenuItem ;
Été1 : TMenuItem ;
Automne1 : TMenuItem ;
Hiver1 : TMenuItem ;
StatusBar1 : TStatusBar ;
ext1 : TMenuItem ;
Minuterie1 : TIminuterie ;
procédure Exit1Click(Expéditeur : TObject);
procédure About1Click (Expéditeur : TObject);
procédure Spring1Click (Expéditeur : TObject);
procédure FormCreate(Expéditeur : TObject);
procédure Summer1Click(Expéditeur : TObject);
procédure Autumn1Click(Expéditeur : TObject);
procédure Winter1Click(Expéditeur : TObject);
procédure ext1Click(Expéditeur : TObject);
privé
procédure DrawLine1(x1,y1,x2,y2:integer;icolor:TColor);// x2>x1 et y2>y1
procédure DrawLine2(x1,y1,x2,y2:integer;icolor:TColor);// x2<x1 et y2>y1
procédure DrawLine3(x1,y1,x2,y2:integer;iColor:TColor);// x1=x2 ou y1=y2
procédure DrawRain ;
procédure DrawTree(x,y,hauteur:entier);
procédure Timer1Timer(expéditeur:TObject);
procédure drawClear ;
procédure Attendre();
{Déclarations privées}
publique
{Déclarations publiques}
fin;
var
Formulaire1 : TForm1 ;
fois : unique ;
mise en œuvre
utilise Unit3, Unit5 ;
{$R *.dfm}
procédure TForm1.Wait();
asme
pousser eax
déplacement eax,0
@boucle:
ajouter eax,1
cmp eax,1000000
jnz @loop
pop eax
fin;
procédure TForm1.DrawLine1(x1,y1,x2,y2:integer;iColor:TColor);
const je:entier=1;
var j,k1,k2,d:entier;
commencer
if((x2-x1)<=0)or((y2-y1)<=0) then exit ;
pour j:=0 à (x2-x1) faire
commencer
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);
si ((x2-x1)=0)ou((y2-y1)=0) alors quittez ;
asme
pousser eax
pushebx
pushecx
pousser edx
mouvement ecx,0
déplacement eax,x2
sous-axial,x1
mouvement ebx, y2
sous ebx, y1
mov d, ebx
déplacer edx,0
div d
mov k2, eax
déplacement eax, y2
sous-eax,y1
mouvement ebx,x2
sous-ebx,x1
mov d, ebx
déplacer edx,0
div d
mouvement k1,eax
déplacement eax,x1
@boucle2 :
ajouter eax, je
incecx
cmpecx,k2
jb @boucle2
mouvement x1,eax
déplacement eax, y1
@boucle1 :
ajouter eax, je
incecx
cmpecx,k1
jb @boucle1
mouvement y1,eax
pop-edx
popecx
pop ebx
pop eax
fin;
fin;// fin pour
fin;
procédure TForm1.DrawLine2(x1,y1,x2,y2:integer;icolor:TColor);
const je:entier=1;
var j,k1,k2,d:entier;
commencer
if((x1-x2)<=0)or((y2-y1)<=0) then exit ;
pour j:=0 à (x1-x2) faire
commencer
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);
si ((x1-x2)=0)ou((y2-y1)=0) alors quittez ;
asme
pousser eax
pushebx
pushecx
pousser edx
mouvement ecx,0
déplacement eax,x1
sous-axial,x2
mouvement ebx, y2
sous ebx, y1
mov d, ebx
déplacer edx,0
div d
mov k2, eax
déplacement eax, y2
sous-eax,y1
mouvement ebx,x1
sous ebx,x2
mov d, ebx
déplacer edx,0
div d
mouvement k1,eax
déplacement eax,x1
@boucle2 :
sous eax, je
incecx
cmpecx,k2
jb @boucle2
mouvement x1,eax
déplacement eax, y1
@boucle1 :
ajouter eax, je
incecx
cmpecx,k1
jb @boucle1
mouvement y1,eax
pop-edx
popecx
pop ebx
pop eax
fin;
fin;// fin pour
fin;
procédure TForm1.DrawLine3(x1,y1,x2,y2:integer;icolor:TColor);
var j:entier;
commencer
if((x2-x1)<>0)and((y2-y1)<>0) alors quittez ;
si (x2-x1)=0 alors
pour j:=0 à (y2-y1) faire
commencer
form1.Canvas.Pen.Color:=icolor;
form1.Canvas.Ellipse(x1-1,y1-1,x1+1,y1+1);
si (y2-y1)=0 alors quittez ;
asme
pousser eax
déplacement eax,y1
TTC
mouvement y1,eax
pop eax
fin;
fin// fin pour
sinon pour j:=0 à (x2-x1) faire
commencer
form1.Canvas.Pen.Color:=icolor;
form1.Canvas.Ellipse(x1-1,y1-1,x1+1,y1+1);
si (x2-x1)=0 alors quittez ;
asme
pousser eax
déplacement eax,x1
TTC
mouvement x1,eax
pop eax
fin;
fin;// fin pour
fin;
procédure TForm1.Timer1Timer(sender:TObject);
commencer
fin;
procédure TForm1.DrawRain ;
var
x1,y1,x2,y2,d,i:entier ;
commencer
pour i:=0 à 100 fais
commencer
x1:=aléatoire(537);
y1:=aléatoire(280);
d:=aléatoire(7);
asme
pousser eax
déplacement eax,x1
sous-axe,d
mouvement x2,eax
déplacement eax, y1
ajouter eax,d
mouvement y2,eax
pop eax
fin;
fois :=fois+1 ;
drawLine2(x1,y1,x2,y2,clmedGray);
attendez();
si (i div 2)=0 alors drawLine2(x1,y1,x2,y2,clwindow);
fin;
fin;
procédure TForm1.DrawTree(x,y,hauteur:entier);
var
x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,d1 :entier ;
commencer
asme
pousser eax
pushebx
pushecx
pousser edx
déplacement eax, hauteur
déplacer edx,0
mouvement ecx,2
plongéecx
mouvement d1,eax
déplacement eax,x
mov ebx,y
sous eax, hauteur
mouvement x1,eax
sous ebx, hauteur
mouvement y1,ebx
ajouter eax, hauteur
sous-axial,5
sous ebx, hauteur
mouvement x2,eax
mouvement y2,ebx
déplacement eax,x
ajouter eax,3
sous ebx, hauteur
mouvement x3, eax
mouvement y3,ebx
ajouter eax,8
ajouter ebx, hauteur
mouvement x4, eax
mouvement y4,ebx
ajouter eax, hauteur
sous-axial,5
ajouter ebx, hauteur
mouvement x5,eax
mov y5,ebx
pop-edx
popecx
pop ebx
pop eax
fin;
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);
fin;
procédure TForm1.Exit1Click(Expéditeur : TObject);
commencer
fermer;
fin;
procédure TForm1.About1Click(Expéditeur : TObject);
commencer
form3.Show;
fin;
procédure TForm1.Spring1Click(Expéditeur : TObject);
var je,k,j:entier;
commencer
StatusBar1.Panels[1].text:='Le printemps de la tempête...';
form1.Canvas.Brush.Color:=clwindow;
form1.Canvas.FloodFill(1,1,clred,fsBorder);
pour i:=0 à 10do
commencer
k:=aléatoire(10);
j:=aléatoire(10);
j:=-j;
drawTree(10+k*50,300+j*20,20);
fin;
pour i:=0 à 10 fais
commencer
form1.Canvas.Brush.Color:=clwindow;
form1.Canvas.FloodFill(1,1,clgreen,fsBorder);
dessinerPluie;
dormir (100);
fin;
fin;
procédure TForm1.FormCreate(Expéditeur : TObject);
commencer
fois :=0 ;
form1.canvas.Brush.Color:=clwindow;
form1.caption:=form1.caption+' Veuillez sélectionner le Pictype !... ';
fin;
procédure TForm1.drawClear ;
var je,k:entier;
commencer
form1.Canvas.Brush.Color:=clblack;
form1.Canvas.FloodFill(15,15, clcream, fsBorder);
pour i:=0 à 5 fais
commencer
k:=aléatoire(300);
DrawLine3(20+k,1,20+k,307,cljaune);
DrawLine3(200+k,1 200+k,307,cljaune);
fin;
fin;
procédure TForm1.Summer1Click(Expéditeur : TObject);
commencer
drawClear;
form1.Canvas.Font.Color:=clblue;
form1.Canvas.Font.Size:=18;
form1.canvas.textOut(150,150,'Océan vert...temps de repos^_^!');
//DrawTree;
fin;
procédure TForm1.Autumn1Click(Expéditeur : TObject);
commencer
drawClear;
form1.Canvas.Font.Color:=clblue;
form1.Canvas.Font.Size:=18;
form1.canvas.textOut(150,150,'Les feuilles rouges et les montagnes parfumées... se reposent^_^!');
fin;
procédure TForm1.Winter1Click(Expéditeur : TObject);
//var i,x,y:entier;
commencer
drawClear;
form1.Canvas.Font.Color:=clblue;
form1.Canvas.Font.Size:=18;
form1.canvas.textOut(150,150,'Éléphant de cire de serpent argenté... pas encore ouvert^_^ !');
fin;
procédure TForm1.ext1Click(Expéditeur : TObject);
commencer
form5.Show;
fin;
fin.
Ce qui suit est le programme de test ci-joint utilisant des instructions à virgule flottante. La version originale à l'époque n'a pas produit l'effet :) :
// Demandez à la bibliothèque de vérifier :)
procédure Tform1.xx ;
var
xmax,ymax,x,y,a,b:single ;
je,z:entier;
commencer
une :=2,0 ;b :=10,0 ;
xmax:=image1.Largeur;
ymax:=image1.Hauteur;
pour i:=0 à image1.Width faire
commencer
asme
//.80x87
fini
fld xmax //pousser xmax dans st(0)
fdiv un
fchs // soit st(0)=-st(0)
fadd je //st(0)=st(0)+i
fdiv b //st(0)=st(0)/b
fstp x //mettre st(0) dans x sans pop
x
fmul x
fchs
fadd ymax
//frndint
//fabriques
fstp y
fin;
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];
fin;
fin;
J'ai choisi l'un des procédés, haha, drôle.
Autant sortir vos affaires et partager votre expérience, je suis à votre écoute :).
s'il te plaît----