Exemplos de uso de assembly em Delphi
-----Também estudante do segundo ano, seguindo o exemplo anterior. Haha, o programa estava um pouco bagunçado quando o escrevi, por favor, me perdoe :).
Usar assembly para programação híbrida em Delphi é extremamente conveniente. Dessa forma, quando quiser ganhar eficiência, você pode optar pela montagem, mas para a maioria dos trabalhos você ainda aproveita a comodidade da programação visual e orientada a objetos. Na linguagem Delphi, usando o segmento de programa asm...end para escrever a parte do código assembly, variáveis de linguagem de alto nível podem ser chamadas no segmento de código assembly, o que você precisa prestar atenção é proteger certas variáveis de registro, e então, alguns detalhes e procedimentos. A compilação abaixo é diferente. Veja este exemplo.
Vamos falar primeiro sobre alguns conhecimentos gerais:
1. Existem duas maneiras de chamar assembly no Delphi.
Assim como ---
Procedimento TForm1.DrawRain;
var
x1,y1,x2,y2,d,i:inteiro;
começar // programa delphi inicia
para i:=0 a 100 faça
começar
x1:=aleatório(537);
y1:=aleatório(280);
d:=aleatório(7);
asm // montagem incorporada começa
empurrar eax
mov eax,x1
subeax,d
mov x2,eax
mov eax,y1
adicione eax,d
movimento y2,eax
pop eax
end;;//Fim da montagem incorporada
vezes:=vezes+1;
drawLine2(x1,y1,x2,y2,clmedGray);
espere();
se (i div 2)=0 então drawLine2(x1,y1,x2,y2,clwindow);
fim;
end; // programa delphi termina
Existe outra maneira de remover o início...fim externo e entrar diretamente na montagem através de asm...fim.
procedimento TForm1.Wait();
asm // montagem incorporada começa
empurrar eax
mov eax,0
@laço:
adicione eax,1
cmp eax,1000000
jnz @loop
pop eax
end; //fim da montagem in-line
2. Use variáveis delphi em montagem
Se você observar o primeiro exemplo de código, é fácil de entender:
asm // montagem incorporada começa
empurrar eax
mov eax,x1 //x1 é uma variável local do Delphi, usada como valor aqui
subeax,d
mov x2,eax //x2 é uma variável local do Delphi e também é usada como endereço de memória
mov eax,y1
adicione eax,d
movimento y2,eax
pop eax
end;;//Fim da montagem incorporada
3. Diferentes detalhes da compilação
Não vou postar os exemplos. Vamos compará-los sozinhos.
@laço:
//...
jnz @loop
Além disso, a maioria das interrupções int pode não estar disponível. Não tentei e não vi nenhuma informação sobre isso. Quem sabe, por favor me envie uma mensagem? Agradeço antecipadamente.
Abaixo está um exemplo maior de um efeito de animação. Como comecei a aprender esse conhecimento no passado, meu trabalho foi muito difícil. É uma cena de chuva constante em uma pequena floresta --- há muitos problemas, o mais proeminente é que antes de tudo, as instruções de ponto flutuante não são usadas (anexarei exemplos de teste de instruções de ponto flutuante para serem tentadas mais tarde ), Alguns algoritmos ainda não eram conhecidos na época e o resultado foi uma imagem bastante monótona. Em segundo lugar, a coordenação entre os cenários não era boa o suficiente. Por exemplo, as árvores não foram protegidas de forma eficaz e foram posteriormente “florescidas” pelo. chuva :).
Mas ainda estou dando um exemplo. Em primeiro lugar, não tenho tempo para escrever exemplos nesta área. Em segundo lugar, se você aprender a usar assembly em Delphi, ele ainda poderá explicar alguns problemas. Além disso, esta aplicação é evitada em materiais gerais. É ocasionalmente mencionada em alguma programação avançada, mas se você quiser dominá-la, terá que praticá-la você mesmo. Este exemplo pode lhe ensinar muitas lições :).
unidade Unidade1;
interface
usa
Windows, Mensagens, SysUtils, Variantes, Classes, Gráficos, Controles, Formulários,
Diálogos, ExtCtrls, Menus, ExtDlgs, FileCtrl, StdCtrls, ComCtrls, ImgList;
tipo
TForm1 = classe(TForm)
MainMenu1: TMainMenu;
Arquivo1: TMenuItem;
Saída1: TMenuItem;
N1: TMenuItem;
Ajuda1: TMenuItem;
Sobre1: TMenuItem;
g1: TMenuItem;
Primavera1: TMenuItem;
Verão1: TMenuItem;
Outono1: TMenuItem;
Inverno1: TMenuItem;
StatusBar1: TStatusBar;
ext1: TMenuItem;
Temporizador1: TTimer;
procedimento Exit1Click(Remetente: TObject);
procedimento About1Click(Remetente: TObject);
procedimento Spring1Click(Remetente: TObject);
procedimento FormCreate(Remetente: TObject);
procedimento Summer1Click(Remetente: TObject);
procedimento Autumn1Click(Remetente: TObject);
procedimento Winter1Click(Remetente: TObject);
procedimento ext1Click(Remetente: TObject);
privado
procedimento DrawLine1(x1,y1,x2,y2:inteiro;icolor:TColor);// x2>x1 e y2>y1
procedimento DrawLine2(x1,y1,x2,y2:inteiro;icolor:TColor);// x2<x1 e y2>y1
procedimento DrawLine3(x1,y1,x2,y2:inteiro;iColor:TColor);// x1=x2 ou y1=y2
procedimento DrawRain;
procedimento DrawTree(x,y,altura:inteiro);
procedimento Timer1Timer(remetente:TObject);
procedimento drawClear;
procedimento Wait();
{Declarações privadas}
público
{Declarações públicas}
fim;
var
Formulário1: TForm1;
vezes: solteiro;
implementação
usa Unidade3, Unidade5;
{$R *.dfm}
procedimento TForm1.Wait();
asm
empurrar eax
mov eax,0
@laço:
adicione eax,1
cmp eax,1000000
jnz @loop
pop eax
fim;
procedimento TForm1.DrawLine1(x1,y1,x2,y2:inteiro;iColor:TColor);
const i:inteiro=1;
var j,k1,k2,d:inteiro;
começar
if((x2-x1)<=0)ou((y2-y1)<=0) então saia;
para j:=0 para (x2-x1) faça
começar
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);
se ((x2-x1)=0)ou((y2-y1)=0) então saia;
asm
empurrar eax
pushebx
pushecx
empurrar edx
mov ecx,0
mov eax,x2
subeixo,x1
mov ebx,y2
sub ebx, y1
movimento d,ebx
mov edx,0
divisão d
mov k2,eax
mov eax,y2
sub eax,y1
mov ebx,x2
sub ebx,x1
movimento d,ebx
mov edx,0
divisão d
mov k1,eax
mov eax,x1
@loop2:
adicione eax, eu
incecx
cmpecx,k2
jb @loop2
mov x1,eax
mov eax,y1
@loop1:
adicione eax, eu
incecx
cmpecx,k1
jb @loop1
movimento y1,eax
pop edx
popecx
pop ebx
pop eax
fim;
fim; // fim para
fim;
procedimento TForm1.DrawLine2(x1,y1,x2,y2:inteiro;icolor:TColor);
const i:inteiro=1;
var j,k1,k2,d:inteiro;
começar
if((x1-x2)<=0)ou((y2-y1)<=0) então saia;
para j:=0 para (x1-x2) faça
começar
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);
se ((x1-x2)=0)ou((y2-y1)=0) então saia;
asm
empurrar eax
pushebx
pushecx
empurrar edx
mov ecx,0
mov eax,x1
subeixo,x2
mov ebx,y2
sub ebx, y1
movimento d,ebx
mov edx,0
divisão d
mov k2,eax
mov eax,y2
sub eax,y1
mov ebx,x1
sub ebx,x2
movimento d,ebx
mov edx,0
divisão d
mov k1,eax
mov eax,x1
@loop2:
sub eax, eu
incecx
cmpecx,k2
jb @loop2
mov x1,eax
mov eax,y1
@loop1:
adicione eax, eu
incecx
cmpecx,k1
jb @loop1
movimento y1,eax
pop edx
papacx
pop ebx
pop eax
fim;
fim; // fim para
fim;
procedimento TForm1.DrawLine3(x1,y1,x2,y2:inteiro;icolor:TColor);
var j:inteiro;
começar
if((x2-x1)<>0)and((y2-y1)<>0) então saia;
se (x2-x1)=0 então
para j:=0 para (y2-y1) faça
começar
form1.Canvas.Pen.Color:=icolor;
form1.Canvas.Ellipse(x1-1,y1-1,x1+1,y1+1);
se (y2-y1)=0 então saia;
asm
empurrar eax
mov eax,y1
aumento eax
movimento y1,eax
pop eax
fim;
fim // fim para
senão para j:=0 para (x2-x1) faça
começar
form1.Canvas.Pen.Color:=icolor;
form1.Canvas.Ellipse(x1-1,y1-1,x1+1,y1+1);
se (x2-x1)=0 então saia;
asm
empurrar eax
mov eax,x1
aumento eax
mov x1,eax
pop eax
fim;
fim; // fim para
fim;
procedimento TForm1.Timer1Timer(remetente:TObject);
começar
fim;
procedimento TForm1.DrawRain;
var
x1,y1,x2,y2,d,i:inteiro;
começar
para i:=0 a 100 faça
começar
x1:=aleatório(537);
y1:=aleatório(280);
d:=aleatório(7);
asm
empurrar eax
mov eax,x1
subeax,d
mov x2,eax
mov eax,y1
adicione eax,d
movimento y2,eax
pop eax
fim;
vezes:=vezes+1;
drawLine2(x1,y1,x2,y2,clmedGray);
espere();
se (i div 2)=0 então drawLine2(x1,y1,x2,y2,clwindow);
fim;
fim;
procedimento TForm1.DrawTree(x,y,altura:inteiro);
var
x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,d1:inteiro;
começar
asm
empurrar eax
pushebx
pushecx
empurrar edx
mov eax, altura
mov edx,0
movimento ecx,2
mergulhox
mov d1,eax
mov eax,x
mov ebx,y
sub eax,altura
mov x1,eax
sub ebx, altura
movimento y1,ebx
adicione eax, altura
subeixo,5
sub ebx, altura
mov x2,eax
movimento y2,ebx
mov eax,x
adicione eax,3
sub ebx, altura
mov x3,eax
movimento y3,ebx
adicione eax,8
adicione ebx, altura
mov x4,eax
movimento y4,ebx
adicione eax, altura
subeixo,5
adicione ebx, altura
mov x5,eax
movimento y5,ebx
pop edx
papacx
pop ebx
pop eax
fim;
DrawLine2(x3,y3,x2-d1,y2,clcream);
DrawLine1(x3,y3,x4+d1,y4,clcream);
drawline3(x2-d1,y2,x2,y2,clcreme);
drawline3(x4,y4,x4+d1,y4,clcreme);
DrawLine2(x2,y2,x1,y1,clcreme);
DrawLine1(x4,y4,x5,y5,clcreme);
DrawLine2(x2+2,y2,x1,y1+2,clcreme);
DrawLine1(x4-2,y4,x5,y5+2,clcreme);
drawline3(x1,y1,x5,y5,clcreme);
drawline3(x1,y1-1,x5,y5-1,clcreme);
drawline3(x,y5,x,y,clcreme);
drawline3(x,y,x+5,y,clcreme);
drawline3(x+5,y5,x+5,y,clcreme);
form1.Canvas.Brush.Color:=clverde;
form1.Canvas.FloodFill(x,y1-5,clcream,fsBorder);
form1.Canvas.FloodFill(x+2,y-5,clcream,fsBorder);
fim;
procedimento TForm1.Exit1Click(Remetente: TObject);
começar
fechar;
fim;
procedimento TForm1.About1Click(Remetente: TObject);
começar
formulário3.Mostrar;
fim;
procedimento TForm1.Spring1Click(Remetente: TObject);
var i,k,j:inteiro;
começar
StatusBar1.Panels[1].text:='A Primavera da Tempestade...';
form1.Canvas.Brush.Color:=clwindow;
form1.Canvas.FloodFill(1,1,clred,fsBorder);
para i:=0 a 10fazer
começar
k:=aleatório(10);
j:=aleatório(10);
j:=-j;
desenharÁrvore(10+k*50,300+j*20,20);
fim;
para i:=0 a 10 faça
começar
form1.Canvas.Brush.Color:=clwindow;
form1.Canvas.FloodFill(1,1,clgreen,fsBorder);
desenharChuva;
dormir(100);
fim;
fim;
procedimento TForm1.FormCreate(Remetente: TObject);
começar
vezes:=0;
form1.canvas.Brush.Color:=clwindow;
form1.caption:=form1.caption+' Selecione o Pictype!... ';
fim;
procedimento TForm1.drawClear;
var i,k:inteiro;
começar
form1.Canvas.Brush.Color:=clblack;
form1.Canvas.FloodFill(15,15, clcream, fsBorder);
para i:=0 a 5 faça
começar
k:=aleatório(300);
DrawLine3(20+k,1,20+k,307,clyellow);
DrawLine3(200+k,1.200+k,307,clyellow);
fim;
fim;
procedimento TForm1.Summer1Click(Remetente: TObject);
começar
desenharLimpar;
form1.Canvas.Font.Color:=clazul;
form1.Canvas.Font.Size:=18;
form1.canvas.textOut(150,150,'Oceano verde...tempo de descanso^_^!');
//DesenharÁrvore;
fim;
procedimento TForm1.Autumn1Click(Remetente: TObject);
começar
desenharLimpar;
form1.Canvas.Font.Color:=clazul;
form1.Canvas.Font.Size:=18;
form1.canvas.textOut(150,150,'Folhas vermelhas e montanhas perfumadas...estão descansando^_^!');
fim;
procedimento TForm1.Winter1Click(Remetente: TObject);
//var i,x,y:inteiro;
começar
desenharLimpar;
form1.Canvas.Font.Color:=clblue;
form1.Canvas.Font.Size:=18;
form1.canvas.textOut(150,150,'Elefante de cera de cobra prateada... ainda não aberto^_^!');
fim;
procedimento TForm1.ext1Click(Remetente: TObject);
começar
formulário5.Mostrar;
fim;
fim.
A seguir está o programa de teste anexado usando instruções de ponto flutuante. A versão original na época não obteve o efeito :):
//Instrui a biblioteca para verificar :)
procedimento Tform1.xx;
var
xmax,ymax,x,y,a,b:único;
eu,z:inteiro;
começar
a:=2,0;b:=10,0;
xmax:=image1.Largura;
ymax:=image1.Altura;
para i:=0 para image1.Width faça
começar
asm
//.80x87
finito
fld xmax //empurra xmax em st(0)
fdiv a
fchs //deixe st(0)=-st(0)
modismo i //st(0)=st(0)+i
fdivb //st(0)=st(0)/b
fstp x //coloca st(0) em x sem pop
x
fmul x
FCS
modismo ymax
//frndint
//fabs
fstp e
fim;
x:=(i-xmax/2)/10;
y:=-x*x+ymax;
z:=trunc(z);
imagem1.canvas.Ellipse(i-1,trunc(y)-1,i+1,trunc(y)+1);
//image1.Canvas.Pixels[x,y];
fim;
fim;
Escolhi um dos processos, haha, engraçado.
Você também pode pegar suas coisas e compartilhar sua experiência, estou pronto para ouvir :).
por favor----