Ejemplos de uso del ensamblaje en Delphi
-----También un estudiante de segundo año, siguiendo el ejemplo anterior. Jaja, el programa estaba un poco desordenado cuando lo escribí, perdóname :).
Usar ensamblador para programación híbrida en Delphi es inusualmente conveniente. De esta manera, cuando desee ganar eficiencia, puede elegir el ensamblaje, pero para la mayoría de los trabajos aún disfrutará de la comodidad de la programación visual y orientada a objetos. En el lenguaje Delphi, al usar el segmento de programa asm...end para escribir la parte del código ensamblador, se pueden llamar variables del lenguaje de alto nivel en el segmento del código ensamblador. A lo que debe prestar atención es a proteger ciertas variables de registro; Luego, algunos detalles y dos La compilación a continuación es diferente. Mira este ejemplo.
Primero hablemos de algunos conocimientos generales:
1. Hay dos formas de convocar una asamblea en Delphi.
Al igual que---
Procedimiento TForm1.DrawRain;
var
x1,y1,x2,y2,d,i:entero;
comenzar//se inicia el programa delphi
para i:=0 a 100 hacer
comenzar
x1:=aleatorio(537);
y1:=aleatorio(280);
d:=aleatorio(7);
asm//se inicia el ensamblaje integrado
empujar eax
movimiento eax,x1
subaxial,d
mov x2,eax
movimiento eax,y1
añadir eax,d
movimiento y2,eax
eax pop
end;;//Fin del ensamblaje integrado
veces:=veces+1;
drawLine2(x1,y1,x2,y2,clmedGray);
esperar();
si (i div 2)=0 entonces drawLine2(x1,y1,x2,y2,clwindow);
fin;
fin;//el programa delphi finaliza
Hay otra forma de quitar el comienzo...final exterior y entrar directamente al ensamblaje a través de asm...end.
procedimiento TForm1.Wait();
asm//se inicia el ensamblaje integrado
empujar eax
movimiento eax,0
@bucle:
añadir eax,1
cmp eax,1000000
@loop
eax pop
end;//fin del ensamblaje en línea
2. Utilice variables de Delphi en el ensamblaje.
Si observa el primer ejemplo de código, es fácil de entender:
asm//se inicia el ensamblaje integrado
empujar eax
mov eax,x1 //x1 es una variable local de Delphi, utilizada como valor aquí
subaxial,d
mov x2,eax //x2 es una variable local de Delphi y también se usa como dirección de memoria
movimiento eax,y1
añadir eax,d
movimiento y2,eax
eax pop
end;;//Fin del ensamblaje integrado
3. Diferentes detalles de la recopilación
No publicaré los ejemplos. Comparémoslos nosotros mismos.
@bucle:
//...
@loop
Además, es posible que la mayoría de las interrupciones int no estén disponibles. No lo he probado y no he visto ninguna información al respecto. ¿Quién sabe? Por favor envíame un mensaje. Gracias de antemano.
A continuación se muestra un ejemplo más amplio de un efecto de animación. Debido a que comencé a aprender este conocimiento en el pasado, mi trabajo fue muy duro. Es una escena de lluvia constante en un pequeño bosque. Hay muchos problemas, el más destacado es que, en primer lugar, no se utilizan instrucciones de punto flotante (adjuntaré ejemplos de prueba de instrucciones de punto flotante para probar más adelante). ), Algunos algoritmos aún no se conocían y el resultado era una imagen bastante monótona. En segundo lugar, la coordinación entre los paisajes no era lo suficientemente buena. Por ejemplo, los árboles no estaban protegidos de manera efectiva y luego fueron "florecidos". lluvia :).
Pero todavía estoy dando un ejemplo. No se ría de mí. En primer lugar, no tengo tiempo para escribir ejemplos en esta área. En segundo lugar, si aprende a usar el ensamblaje en Delphi, aún puede explicar ciertos problemas. Además, esta aplicación se evita en materiales generales. Ocasionalmente se menciona en alguna programación avanzada, pero si quieres dominarla, debes practicarla tú mismo. Este ejemplo te puede enseñar muchas lecciones :).
unidad Unidad1;
interfaz
usos
Windows, Mensajes, SysUtils, Variantes, Clases, Gráficos, Controles, Formularios,
Diálogos, ExtCtrls, Menús, ExtDlgs, FileCtrl, StdCtrls, ComCtrls, ImgList;
tipo
TForm1 = clase(TForm)
Menú principal1: TMenú principal;
Archivo1: TMenuItem;
Salir1: TMenuItem;
N1: TMenuItem;
Ayuda1: TMenuItem;
Acerca de1: TMenuItem;
g1: TMenuItem;
Primavera1: TMenuItem;
Verano1: TMenuItem;
Otoño1: TMenuItem;
Invierno1: TMenuItem;
Barra de estado1: TStatusBar;
ext1: TMenuItem;
Temporizador1: Temporizador T;
procedimiento Salir1Click(Remitente: TObject);
procedimiento About1Click(Remitente: TObject);
procedimiento Spring1Click (Remitente: TObject);
procedimiento FormCreate(Remitente: TObject);
procedimiento Summer1Click(Remitente: TObject);
procedimiento Autumn1Click (Remitente: TObject);
procedimiento Winter1Click(Remitente: TObject);
procedimiento ext1Click(Remitente: TObject);
privado
procedimiento DrawLine1(x1,y1,x2,y2:integer;icolor:TColor);// x2>x1 y y2>y1
procedimiento DrawLine2(x1,y1,x2,y2:integer;icolor:TColor);// x2<x1 y y2>y1
procedimiento DrawLine3(x1,y1,x2,y2:integer;iColor:TColor);// x1=x2 o y1=y2
procedimiento DrawRain;
procedimiento DrawTree(x,y,altura:entero);
procedimiento Timer1Timer(remitente:TObject);
procedimiento drawClear;
procedimiento Esperar();
{Declaraciones privadas}
público
{Declaraciones públicas}
fin;
var
Formulario1: TForm1;
tiempos:soltero;
implementación
utiliza Unidad3, Unidad5;
{$R *.dfm}
procedimiento TForm1.Wait();
ENSAMBLE
empujar eax
movimiento eax,0
@bucle:
añadir eax,1
cmp eax,1000000
@loop
eax pop
fin;
procedimiento TForm1.DrawLine1(x1,y1,x2,y2:integer;iColor:TColor);
const i: entero = 1;
var j,k1,k2,d:entero;
comenzar
if((x2-x1)<=0)o((y2-y1)<=0) entonces salga;
para j:=0 a (x2-x1) hacer
comenzar
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)o((y2-y1)=0) entonces salga;
ENSAMBLE
empujar eax
pushebx
pushecx
empujar edx
movimiento ecx,0
movimiento eax,x2
subaxial,x1
movimiento ebx,y2
sub ebx,y1
mov d, ebx
movimiento edx,0
división d
mov k2,eax
movimiento eax,y2
subeje,y1
movimiento ebx,x2
sub ebx,x1
mov d, ebx
movimiento edx,0
división d
movimiento k1,eax
movimiento eax,x1
@bucle2:
agregar eax, yo
incecx
cmpecx,k2
jb @bucle2
movimiento x1,eax
movimiento eax,y1
@bucle1:
agregar eax, yo
incecx
cmpecx,k1
jb @bucle1
movimiento y1,eax
pop edx
popecx
pop ebx
eax pop
fin;
fin;// fin para
fin;
procedimiento TForm1.DrawLine2(x1,y1,x2,y2:integer;icolor:TColor);
const i: entero = 1;
var j,k1,k2,d:entero;
comenzar
si((x1-x2)<=0)o((y2-y1)<=0) entonces salga;
para j:=0 a (x1-x2) hacer
comenzar
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)o((y2-y1)=0) entonces salga;
ENSAMBLE
empujar eax
pushebx
pushecx
empujar edx
movimiento ecx,0
movimiento eax,x1
subaxial,x2
movimiento ebx,y2
sub ebx,y1
mov d, ebx
movimiento edx,0
división d
mov k2,eax
movimiento eax,y2
subeje,y1
movimiento ebx,x1
sub ebx,x2
mov d, ebx
movimiento edx,0
división d
movimiento k1,eax
movimiento eax,x1
@bucle2:
sub eax, yo
incecx
cmpecx,k2
jb @bucle2
movimiento x1,eax
movimiento eax,y1
@bucle1:
agregar eax, yo
incecx
cmpecx,k1
jb @bucle1
movimiento y1,eax
pop edx
popecx
pop ebx
eax pop
fin;
fin;// fin para
fin;
procedimiento TForm1.DrawLine3(x1,y1,x2,y2:integer;icolor:TColor);
var j: entero;
comenzar
if((x2-x1)<>0)y((y2-y1)<>0) entonces salga;
si (x2-x1)=0 entonces
para j:=0 a (y2-y1) hacer
comenzar
form1.Canvas.Pen.Color:=icolor;
form1.Canvas.Ellipse(x1-1,y1-1,x1+1,y1+1);
si (y2-y1)=0 entonces salga;
ENSAMBLE
empujar eax
movimiento eax,y1
inc eax
movimiento y1,eax
eax pop
fin;
fin// fin para
de lo contrario, para j:=0 a (x2-x1) hacer
comenzar
form1.Canvas.Pen.Color:=icolor;
form1.Canvas.Ellipse(x1-1,y1-1,x1+1,y1+1);
si (x2-x1)=0 entonces salga;
ENSAMBLE
empujar eax
movimiento eax,x1
inc eax
movimiento x1,eax
eax pop
fin;
fin;// fin para
fin;
procedimiento TForm1.Timer1Timer(remitente:TObject);
comenzar
fin;
procedimiento TForm1.DrawRain;
var
x1,y1,x2,y2,d,i:entero;
comenzar
para i:=0 a 100 hacer
comenzar
x1:=aleatorio(537);
y1:=aleatorio(280);
d:=aleatorio(7);
ENSAMBLE
empujar eax
movimiento eax,x1
subaxial,d
mov x2,eax
movimiento eax,y1
añadir eax,d
movimiento y2,eax
eax pop
fin;
veces:=veces+1;
drawLine2(x1,y1,x2,y2,clmedGray);
esperar();
si (i div 2)=0 entonces drawLine2(x1,y1,x2,y2,clwindow);
fin;
fin;
procedimiento TForm1.DrawTree(x,y,altura:entero);
var
x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,d1:entero;
comenzar
ENSAMBLE
empujar eax
pushebx
pushecx
empujar edx
movimiento eax, altura
movimiento edx,0
movimiento ecx,2
buceox
movimiento d1,eax
movimiento eax,x
mov ebx,y
subeje, altura
movimiento x1,eax
sub ebx, altura
movimiento y1,ebx
agregar eax, altura
subaxial,5
sub ebx, altura
mov x2,eax
movimiento y2,ebx
movimiento eax,x
añadir eax,3
sub ebx, altura
mov x3,eax
movimiento y3, ebx
añadir eax,8
agregar ebx, altura
mov x4,eax
movimiento y4,ebx
agregar eax, altura
subaxial,5
agregar ebx, altura
mov x5,eax
movimiento y5, ebx
pop edx
popecx
pop ebx
eax pop
fin;
DrawLine2(x3,y3,x2-d1,y2,clcrema);
DrawLine1(x3,y3,x4+d1,y4,clcrema);
drawline3(x2-d1,y2,x2,y2,clcrema);
drawline3(x4,y4,x4+d1,y4,clcrema);
DrawLine2(x2,y2,x1,y1,clcrema);
DrawLine1(x4,y4,x5,y5,clcrema);
DrawLine2(x2+2,y2,x1,y1+2,clcrema);
DrawLine1(x4-2,y4,x5,y5+2,clcrema);
drawline3(x1,y1,x5,y5,clcrema);
drawline3(x1,y1-1,x5,y5-1,clcrema);
drawline3(x,y5,x,y,clcrema);
drawline3(x,y,x+5,y,clcrema);
drawline3(x+5,y5,x+5,y,clcrema);
form1.Canvas.Brush.Color:=clgreen;
form1.Canvas.FloodFill(x,y1-5,clcream,fsBorder);
form1.Canvas.FloodFill(x+2,y-5,clcream,fsBorder);
fin;
procedimiento TForm1.Exit1Click(Remitente: TObject);
comenzar
cerca;
fin;
procedimiento TForm1.About1Click(Remitente: TObject);
comenzar
formulario3.Mostrar;
fin;
procedimiento TForm1.Spring1Click (Remitente: TObject);
var i,k,j:entero;
comenzar
StatusBar1.Panels[1].text:='La primavera de la tormenta...';
form1.Canvas.Brush.Color:=clwindow;
form1.Canvas.FloodFill(1,1,clred,fsBorder);
para i:=0 a 10do
comenzar
k:=aleatorio(10);
j:=aleatorio(10);
j:=-j;
dibujarÁrbol(10+k*50,300+j*20,20);
fin;
para i:=0 a 10 hacer
comenzar
form1.Canvas.Brush.Color:=clwindow;
form1.Canvas.FloodFill(1,1,clgreen,fsBorder);
dibujarLluvia;
dormir(100);
fin;
fin;
procedimiento TForm1.FormCreate(Remitente: TObject);
comenzar
veces:=0;
form1.canvas.Brush.Color:=clwindow;
form1.caption:=form1.caption+' ¡Seleccione el tipo de imagen!... ';
fin;
procedimiento TForm1.drawClear;
var i,k:entero;
comenzar
form1.Canvas.Brush.Color:=clnegro;
form1.Canvas.FloodFill(15,15, clcream, fsBorder);
para i:=0 a 5 hacer
comenzar
k:=aleatorio(300);
DrawLine3(20+k,1,20+k,307,clamarillo);
DrawLine3(200+k,1,200+k,307,clamarillo);
fin;
fin;
procedimiento TForm1.Summer1Click (Remitente: TObject);
comenzar
dibujarBorrar;
form1.Canvas.Font.Color:=clblue;
form1.Canvas.Font.Size:=18;
form1.canvas.textOut(150,150,'Océano verde...tiempo de descanso^_^!');
//Dibujarárbol;
fin;
procedimiento TForm1.Autumn1Click (Remitente: TObject);
comenzar
dibujarBorrar;
form1.Canvas.Font.Color:=clblue;
form1.Canvas.Font.Size:=18;
form1.canvas.textOut(150,150,'Hojas rojas y montañas fragantes... están descansando^_^!');
fin;
procedimiento TForm1.Winter1Click (Remitente: TObject);
//var i,x,y:entero;
comenzar
dibujarBorrar;
form1.Canvas.Font.Color:=clblue;
form1.Canvas.Font.Size:=18;
form1.canvas.textOut(150,150,'Elefante de cera de serpiente plateada... ¡aún no abierto^_^!');
fin;
procedimiento TForm1.ext1Click(Remitente: TObject);
comenzar
formulario5.Mostrar;
fin;
fin.
El siguiente es el programa de prueba adjunto que utiliza instrucciones de punto flotante. La versión original en ese momento no logró el efecto :):
//Indica a la biblioteca que verifique :)
procedimiento Tform1.xx;
var
xmax,ymax,x,y,a,b:único;
i,z:entero;
comenzar
a:=2,0;b:=10,0;
xmax:=imagen1.Ancho;
ymax:=imagen1.Altura;
para i:=0 a image1.Width hacer
comenzar
ENSAMBLE
//.80x87
finito
fld xmax //empuja xmax en st(0)
fdiv a
fchs //dejemos st(0)=-st(0)
moda i //st(0)=st(0)+i
fdiv b //st(0)=st(0)/b
fstp x //poner st(0) en x sin pop
incógnita
fmul x
fchs
moda pasajera ymax
//frndint
//fabulosos
fstp y
fin;
x:=(i-xmax/2)/10;
y:=-x*x+ymax;
z:=trunc(z);
imagen1.canvas.Ellipse(i-1,trunc(y)-1,i+1,trunc(y)+1);
//imagen1.Canvas.Pixels[x,y];
fin;
fin;
Elegí uno de los procesos, jaja, curioso.
También puedes sacar tus cosas y compartir tu experiencia, estoy listo para escuchar :).
por favor----