Delphi에서 어셈블리를 사용하는 예
-----앞의 예에 이어 2학년이기도 합니다. 하하, 프로그램을 작성할 때 좀 지저분했는데 양해해 주세요 :).
Delphi에서 하이브리드 프로그래밍을 위해 어셈블리를 사용하는 것은 매우 편리합니다. 이런 식으로 효율성을 얻고 싶을 때는 어셈블리를 선택할 수 있지만 대부분의 작업에서는 여전히 시각적 개체 지향 프로그래밍의 편리함을 누릴 수 있습니다. Delphi 언어에서는 asm...end 프로그램 세그먼트를 사용하여 어셈블리 코드 부분을 작성함으로써 어셈블리 코드 세그먼트에서 고급 언어 변수를 호출할 수 있습니다. 주의해야 할 점은 특정 레지스터 변수를 보호하는 것입니다. 그런 다음 몇 가지 세부 사항과 해야 할 일 아래 편집 내용은 다릅니다. 이 예를 보세요.
먼저 몇 가지 일반적인 지식에 대해 이야기해 보겠습니다.
1. 델파이에서 어셈블리를 호출하는 방법에는 두 가지가 있습니다.
마치---
절차 TForm1.DrawRain;
var
x1,y1,x2,y2,d,i:정수;
시작 //델파이 프로그램 시작
i:=0 ~ 100 do
시작하다
x1:=무작위(537);
y1:=무작위(280);
d:=random(7);
asm//임베디드 어셈블리 시작
푸시 eax
이동 eax,x1
서브엑스,디
movx2,eax
이동 eax,y1
eax,d 추가
mov y2,eax
팝 eax
end;;//임베디드 어셈블리 끝
회:=회+1;
drawLine2(x1,y1,x2,y2,clmedGray);
기다리다();
if (i div 2)=0이면 drawLine2(x1,y1,x2,y2,clwindow);
끝;
end;//델파이 프로그램 종료
외부 시작...끝을 제거하고 조립...끝을 통해 직접 어셈블리에 들어가는 또 다른 방법이 있습니다.
프로시저 TForm1.Wait();
asm//임베디드 어셈블리 시작
푸시 eax
이동 eax,0
@고리:
eax를 추가하고,1
cmp eax,1000000
jnz @loop
팝 eax
end;//인라인 어셈블리 끝
2. 어셈블리에서 델파이 변수 사용
첫 번째 코드 예제를 보면 이해하기 쉽습니다.
asm//임베디드 어셈블리 시작
푸시 eax
mov eax,x1 //x1은 델파이 로컬 변수이며 여기서 값으로 사용됩니다.
서브엑스,디
mov x2,eax //x2는 델파이 지역 변수이며 메모리 주소로도 사용됩니다.
이동 eax,y1
eax,d 추가
mov y2,eax
팝 eax
end;;//임베디드 어셈블리 끝
3. 편집의 다양한 세부 사항
예제를 직접 비교하지는 않겠습니다.
@고리:
//...
jnz @loop
또한 대부분의 int 인터럽트는 사용하지 못할 수도 있으며 이에 대한 정보도 본 적이 없습니다. 아시는 분 저에게 메시지를 보내주세요. 미리 감사드립니다.
다음은 애니메이션 효과의 더 큰 예입니다. 과거에 이 지식을 배우기 시작했기 때문에 작업이 매우 힘들었습니다. 작은 숲속에 계속해서 비가 내리는 장면입니다---문제가 많은데 가장 눈에 띄는 것은 우선 부동소수점 명령어를 사용하지 않는다는 점입니다.(부동소수점 명령어의 테스트 예시는 추후에 첨부하겠습니다. ), 당시에는 일부 알고리즘이 아직 알려지지 않았으며 결과는 다소 단조로운 그림이었습니다. 둘째, 풍경 간의 조화가 충분하지 않았습니다. 비 :).
하지만 저는 여전히 예를 들고 있습니다. 웃지 마세요. 첫째, 이 분야에서는 예제를 작성할 시간이 없습니다. 둘째, 델파이에서 어셈블리를 사용하는 방법을 배우면 여전히 특정 문제를 설명할 수 있습니다. 또한 이 응용 프로그램은 일반 자료에서는 피하며 일부 고급 프로그래밍에서는 가끔 언급되지만, 이를 마스터하려면 대부분 직접 연습해야 합니다. :)
단위 Unit1;
인터페이스
용도
Windows, 메시지, SysUtils, 변형, 클래스, 그래픽, 컨트롤, 양식,
대화 상자, ExtCtrls, 메뉴, ExtDlgs, FileCtrl, StdCtrls, ComCtrls, ImgList;
유형
TForm1 = 클래스(TForm)
메인메뉴1: TMainMenu;
파일1: TMenuItem;
Exit1: TMenuItem;
N1: TMenuItem;
도움말1: TMenuItem;
About1: TMenuItem;
g1: TMenuItem;
스프링1: TMenuItem;
여름1: TMenuItem;
Autumn1: TMenuItem;
Winter1: TMenuItem;
StatusBar1: TStatusBar;
ext1: TMenuItem;
타이머1: T타이머;
절차 Exit1Click(Sender: TObject);
절차 About1Click(보내는 사람: TObject);
절차 Spring1Click(Sender: TObject);
절차 FormCreate(보내는 사람: TObject);
절차 Summer1Click(보내는 사람: TObject);
절차 Autumn1Click(보내는 사람: TObject);
절차 Winter1Click(보내는 사람: TObject);
절차 ext1Click(Sender: TObject);
사적인
절차 DrawLine1(x1,y1,x2,y2:integer;icolor:TColor);// x2>x1 및 y2>y1
절차 DrawLine2(x1,y1,x2,y2:integer;icolor:TColor);// x2<x1 및 y2>y1
절차 DrawLine3(x1,y1,x2,y2:integer;iColor:TColor);// x1=x2 또는 y1=y2
절차 DrawRain;
절차 DrawTree(x,y,높이:정수);
절차 Timer1Timer(sender:TObject);
절차 drawClear;
절차 대기();
{비공개 선언}
공공의
{공개 선언}
끝;
var
Form1: TForm1;
시간:단일;
구현
Unit3,Unit5를 사용합니다.
{$R *.dfm}
프로시저 TForm1.Wait();
asm
푸시 eax
이동 eax,0
@고리:
eax를 추가하고,1
cmp eax,1000000
jnz @loop
팝 eax
끝;
프로시저 TForm1.DrawLine1(x1,y1,x2,y2:integer;iColor:TColor);
const i:정수=1;
var j,k1,k2,d:정수;
시작하다
if((x2-x1)<=0)or((y2-y1)<=0) then 종료;
j:=0 ~ (x2-x1)의 경우
시작하다
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)또는((y2-y1)=0) 그런 다음 종료합니다.
asm
푸시 eax
pushebx
푸시섹
푸시 edx
이동 ECX,0
이동 eax,x2
서브엑스,x1
mov ebx,y2
하위 ebx,y1
mov d,ebx
이동 edx,0
사업부 D
mov k2,eax
이동 eax,y2
하위 eax,y1
이동 EBX,x2
서브 ebx,x1
mov d,ebx
이동 edx,0
사업부 D
mov k1,eax
이동 eax,x1
@loop2:
eax를 추가하세요.
incecx
cmpecx,k2
JB @loop2
movx1,eax
이동 eax,y1
@loop1:
eax를 추가하세요.
incecx
cmpecx,k1
JB@loop1
mov y1,eax
팝 edx
교황
팝 ebx
팝 eax
끝;
end;//끝
끝;
프로시저 TForm1.DrawLine2(x1,y1,x2,y2:integer;icolor:TColor);
const i:정수=1;
var j,k1,k2,d:정수;
시작하다
if((x1-x2)<=0)or((y2-y1)<=0) then 종료;
j:=0 ~ (x1-x2)의 경우
시작하다
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);
((x1-x2)=0)또는((y2-y1)=0)이면 종료합니다.
asm
푸시 eax
pushebx
푸시섹
푸시 edx
이동 ECX,0
이동 eax,x1
서브엑스,x2
mov ebx,y2
하위 ebx,y1
mov d,ebx
이동 edx,0
사업부 D
mov k2,eax
이동 eax,y2
하위 eax,y1
이동 EBX,x1
서브 ebx,x2
mov d,ebx
이동 edx,0
사업부 D
mov k1,eax
이동 eax,x1
@loop2:
서브 eax, 나는
incecx
cmpecx,k2
JB @loop2
movx1,eax
이동 eax,y1
@loop1:
eax를 추가하세요.
incecx
cmpecx,k1
JB @loop1
mov y1,eax
팝 edx
교황
팝 ebx
팝 eax
끝;
end;//끝
끝;
프로시저 TForm1.DrawLine3(x1,y1,x2,y2:integer;icolor:TColor);
var j:정수;
시작하다
if((x2-x1)<>0)and((y2-y1)<>0) 그런 다음 종료합니다.
(x2-x1)=0이면
j:=0 ~ (y2-y1)의 경우
시작하다
form1.Canvas.Pen.Color:=icolor;
form1.Canvas.Ellipse(x1-1,y1-1,x1+1,y1+1);
(y2-y1)=0이면 종료합니다.
asm
푸시 eax
이동 eax,y1
inc eax
mov y1,eax
팝 eax
끝;
종료 // 종료
else for j:=0 ~ (x2-x1) do
시작하다
form1.Canvas.Pen.Color:=icolor;
form1.Canvas.Ellipse(x1-1,y1-1,x1+1,y1+1);
(x2-x1)=0이면 종료합니다.
asm
푸시 eax
이동 eax,x1
inc eax
movx1,eax
팝 eax
끝;
end;//끝
끝;
절차 TForm1.Timer1Timer(sender:TObject);
시작하다
끝;
절차 TForm1.DrawRain;
var
x1,y1,x2,y2,d,i:정수;
시작하다
i:=0 ~ 100 do
시작하다
x1:=무작위(537);
y1:=무작위(280);
d:=random(7);
asm
푸시 eax
이동 eax,x1
서브엑스,디
movx2,eax
이동 eax,y1
eax,d 추가
mov y2,eax
팝 eax
끝;
회:=회+1;
drawLine2(x1,y1,x2,y2,clmedGray);
기다리다();
if (i div 2)=0이면 drawLine2(x1,y1,x2,y2,clwindow);
끝;
끝;
프로시저 TForm1.DrawTree(x,y,height:integer);
var
x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,d1:정수;
시작하다
asm
푸시 eax
pushebx
푸시섹
푸시 edx
mov eax, 높이
이동 edx,0
이동 ECX,2
디벡스
mov d1,eax
mov eax,x
mov ebx,y
하위 eax, 높이
movx1,eax
하위 ebx, 높이
mov y1,ebx
eax, 높이 추가
서브엑스,5
하위 ebx, 높이
movx2,eax
mov y2,ebx
mov eax,x
eax를 추가하세요,3
하위 ebx, 높이
mov x3, eax
mov y3,ebx
eax를 추가하세요,8
ebx, 높이 추가
mov x4, eax
mov y4,ebx
eax, 높이 추가
서브엑스,5
ebx, 높이 추가
mov x5, eax
mov y5,ebx
팝 edx
교황
팝 ebx
팝 eax
끝;
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);
끝;
절차 TForm1.Exit1Click(Sender: TObject);
시작하다
닫다;
끝;
절차 TForm1.About1Click(Sender: TObject);
시작하다
form3.Show;
끝;
절차 TForm1.Spring1Click(Sender: TObject);
var i,k,j:정수;
시작하다
StatusBar1.Panels[1].text:='폭풍의 봄...';
form1.Canvas.Brush.Color:=clwindow;
form1.Canvas.FloodFill(1,1,clred,fsBorder);
i:=0 ~ 10do의 경우
시작하다
k:=무작위(10);
j:=random(10);
j:=-j;
drawTree(10+k*50,300+j*20,20);
끝;
for i:=0 ~ 10 do
시작하다
form1.Canvas.Brush.Color:=clwindow;
form1.Canvas.FloodFill(1,1,clgreen,fsBorder);
무승부비;
수면(100);
끝;
끝;
절차 TForm1.FormCreate(Sender: TObject);
시작하다
횟수:=0;
form1.canvas.Brush.Color:=clwindow;
form1.caption:=form1.caption+' Pictype을 선택해주세요!...';
끝;
절차 TForm1.drawClear;
var i,k:정수;
시작하다
form1.Canvas.Brush.Color:=clblack;
form1.Canvas.FloodFill(15,15, clcream, fsBorder);
for i:=0 ~ 5 do
시작하다
k:=무작위(300);
DrawLine3(20+k,1,20+k,307,clyellow);
DrawLine3(200+k,1,200+k,307,clyellow);
끝;
끝;
절차 TForm1.Summer1Click(Sender: TObject);
시작하다
drawClear;
form1.Canvas.Font.Color:=clblue;
form1.Canvas.Font.Size:=18;
form1.canvas.textOut(150,150,'푸른바다...휴식시간^_^!');
//나무 그리기;
끝;
절차 TForm1.Autumn1Click(Sender: TObject);
시작하다
drawClear;
form1.Canvas.Font.Color:=clblue;
form1.Canvas.Font.Size:=18;
form1.canvas.textOut(150,150,'붉은 단풍과 향기로운 산이...쉬고있습니다^_^!');
끝;
절차 TForm1.Winter1Click(Sender: TObject);
//var i,x,y:integer;
시작하다
drawClear;
form1.Canvas.Font.Color:=clblue;
form1.Canvas.Font.Size:=18;
form1.canvas.textOut(150,150,'은뱀 왁스 코끼리...아직 열리지 않았습니다^_^!');
끝;
절차 TForm1.ext1Click(Sender: TObject);
시작하다
form5.표시;
끝;
끝.
다음은 부동 소수점 명령어를 사용한 첨부된 테스트 프로그램입니다. 당시 원본 버전에서는 효과를 얻지 못했습니다. :)
//라이브러리에 확인을 지시합니다. :)
절차 Tform1.xx;
var
xmax,ymax,x,y,a,b:단일;
i,z:정수;
시작하다
a:=2.0;b:=10.0;
xmax:=이미지1.폭;
ymax:=이미지1.높이;
i:=0에서 image1.Width로
시작하다
asm
//.80x87
유한
fld xmax //st(0)에 xmax를 입력합니다.
fdiv a
fchs //st(0)=-st(0)하자
fadd i //st(0)=st(0)+i
fdiv b //st(0)=st(0)/b
fstp x //팝 없이 x에 st(0)을 넣습니다.
엑스
fmul x
fchs
유행 ymax
//frndint
//팹
fstp y
끝;
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);
//이미지1.Canvas.Pixels[x,y];
끝;
끝;
프로세스 중 하나를 선택했습니다. 하하, 재밌네요.
당신은 당신의 물건을 꺼내서 당신의 경험을 공유할 수도 있습니다. 나는 들을 준비가 되어 있습니다 :).
제발----