Delphi でのアセンブリの使用例
-----前回に続き、こちらも2年生。あはは、プログラムを書いたときは少し乱雑でしたが、ご容赦ください :)。
Delphi でハイブリッド プログラミングにアセンブリを使用すると、非常に便利です。このように、効率を高めたい場合はアセンブリを選択できますが、ほとんどの作業では依然としてビジュアルおよびオブジェクト指向プログラミングの利便性を享受できます。 Delphi 言語では、asm...end プログラム セグメントを使用してアセンブリ コード部分を記述することで、アセンブリ コード セグメント内で高級言語変数を呼び出すことができます。注意する必要があるのは、特定のレジスタ変数を保護することです。次に、いくつかの詳細と作業を説明します。 以下のコンパイルは異なります。この例を見てください。
まず一般的な知識について話しましょう。
1. Delphi でアセンブリを呼び出す方法は 2 つあります。
まるで---
手順 TForm1.DrawRain;
変数
x1,y1,x2,y2,d,i:整数;
begin//delphi プログラムが開始します
for i:=0 ~ 100 を実行します
始める
x1:=ランダム(537);
y1:=ランダム(280);
d:=ランダム(7);
asm//組み込みアセンブリが開始されます
押します
移動 eax,x1
サブアックス、d
mov x2、eax
移動 eax,y1
eax,d を追加
mov y2,eax
ポップイーアックス
end;;//埋め込みアセンブリの終了
回:= 回+1;
drawLine2(x1,y1,x2,y2,clmedGray);
待って();
if (i div 2)=0 thendrawLine2(x1,y1,x2,y2,clwindow);
終わり;
end;//delphi プログラムが終了します
外側の begin...end を削除し、asm...end を通じてアセンブリに直接入力する別の方法もあります。
プロシージャ TForm1.Wait();
asm//組み込みアセンブリが開始されます
押します
移動 eax,0
@ループ:
eax,1を追加
cmp eax,1000000
jnz@ループ
ポップイーアックス
end;//インラインアセンブリの終わり
2.アセンブリでdelphi変数を使用する
最初のコード例を見ると、簡単に理解できます。
asm//組み込みアセンブリが開始されます
押します
mov eax,x1 //x1 は Delphi ローカル変数であり、ここで値として使用されます
サブアックス、d
mov x2,eax //x2 は Delphi ローカル変数であり、メモリ アドレスとしても使用されます
移動 eax,y1
eax,d を追加
mov y2,eax
ポップイーアックス
end;;//埋め込みアセンブリの終了
3. コンピレーションのさまざまな詳細
例は掲載しません。たとえば、次のように比較してみましょう。
@ループ:
//...
jnz@ループ
さらに、ほとんどの int 割り込みは使用できない可能性があります。私はそれを試したことがなく、それに関する情報も知りませんでした。知っている人はメッセージを送ってください。よろしくお願いします。
以下はアニメーション効果のより大きな例です。過去にこの知識を学び始めたばかりだったので、私の仕事は非常に雑でした。小さな森に雨が降り続く風景です --- 問題はたくさんありますが、最も顕著なのは、まず浮動小数点命令が使用されていないことです(浮動小数点命令のテスト例は後で試してみます) )、一部のアルゴリズムは当時まだ知られていなかったため、結果はかなり単調な画像になりました。第二に、木々は効果的に保護されず、後に「開花」しました。雨 :)。
しかし、まだ例を挙げているのを笑わないでください。第一に、この分野で例を書く時間がありません。第二に、Delphi でアセンブリを使用する方法を学べば、それでも特定の問題を説明できます。さらに、このアプリケーションは一般的な教材では避けられていますが、これをマスターしたい場合は、ほとんどの場合、この例から多くのことを学ぶことができます :)。
ユニットユニット1;
インタフェース
用途
ウィンドウ、メッセージ、SysUtils、バリアント、クラス、グラフィックス、コントロール、フォーム、
ダイアログ、ExtCtrls、メニュー、ExtDlgs、FileCtrl、StdCtrls、ComCtrls、ImgList;
タイプ
TForm1 = クラス(TForm)
MainMenu1: TMainMenu;
ファイル 1: TMenuItem;
Exit1: TMenuItem;
N1: TMenuItem;
ヘルプ 1: TMenuItem;
About1: TMenuItem;
g1: TMenuItem;
Spring1: TMenuItem;
Summer1: TMenuItem;
Autumn1: TMenuItem;
Winter1: TMenuItem;
ステータスバー1: Tステータスバー;
ext1: TMenuItem;
タイマー 1: T タイマー;
プロシージャ Exit1Click(送信者: TObject);
プロシージャ About1Click(送信者: TObject);
プロシージャ Spring1Click(送信者: TObject);
プロシージャ FormCreate(Sender: TObject);
プロシージャ Summer1Click(送信者: TObject);
プロシージャ Autumn1Click(送信者: TObject);
プロシージャ Winter1Click(送信者: TObject);
プロシージャ ext1Click(送信者: TObject);
プライベート
プロシージャ DrawLine1(x1,y1,x2,y2:integer;icolor:TColor);// x2>x1 および y2>y1
プロシージャ DrawLine2(x1,y1,x2,y2:integer;icolor:TColor);// x2<x1 and y2>y1
プロシージャ DrawLine3(x1,y1,x2,y2:integer;iColor:TColor);// x1=x2 または y1=y2
プロシージャ DrawRain;
プロシージャ DrawTree(x,y,height:integer);
プロシージャ Timer1Timer(送信者:TObject);
プロシージャdrawClear;
プロシージャ Wait();
{プライベート宣言}
公共
{公的宣言}
終わり;
変数
フォーム1: TForm1;
回:シングル;
実装
Unit3、Unit5を使用します。
{$R *.dfm}
プロシージャ TForm1.Wait();
アズム
押します
移動 eax,0
@ループ:
eax,1を追加
cmp eax,1000000
jnz@ループ
ポップイーアックス
終わり;
プロシージャ 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) 終了します。
for 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);
((x2-x1)=0) または ((y2-y1)=0) の場合は終了します。
アズム
押します
プッシュセブ
プッシュエク
プッシュEDX
移動ecx,0
移動 eax,x2
サブアックス、x1
移動 ebx,y2
サブebx,y1
モーヴ・ディー、ebx
ムーブ edx,0
ディビジョン
mov k2、eax
移動 eax,y2
サブ eax、y1
mov ebx,x2
サブebx、x1
モーヴ・ディー、ebx
ムーブ edx,0
ディビジョン
mov k1,eax
移動 eax,x1
@ループ2:
eax、iを追加
インセクス
cmpecx,k2
ジェイブ @loop2
mov x1、eax
移動 eax,y1
@ループ1:
eax、iを追加
インセクス
cmpecx,k1
ジェイブ @loop1
mov y1,eax
ポップエディックス
ポペクス
ポップebx
ポップイーアックス
終わり;
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) その後終了します。
for j:=0 to (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) の場合は終了します。
アズム
押します
プッシュセブ
プッシュエク
プッシュEDX
移動ecx,0
移動 eax,x1
サブアックス×2
移動 ebx,y2
サブebx,y1
モーヴ・ディー、ebx
ムーブ edx,0
ディビジョン
mov k2、eax
移動 eax,y2
サブ eax、y1
mov ebx,x1
サブebx、x2
モーヴ・ディー、ebx
ムーブ edx,0
ディビジョン
mov k1,eax
移動 eax,x1
@ループ2:
サブイーサ、私
インセクス
cmpecx,k2
ジェイブ @loop2
mov x1、eax
移動 eax,y1
@ループ1:
eax、iを追加
インセクス
cmpecx,k1
ジェイブ @loop1
mov y1,eax
ポップEDX
ポペクス
ポップebx
ポップイーアックス
終わり;
end;// 終了
終わり;
プロシージャ TForm1.DrawLine3(x1,y1,x2,y2:integer;icolor:TColor);
変数 j:整数;
始める
if((x2-x1)<>0)and((y2-y1)<>0) その後終了します。
(x2-x1)=0 の場合
for j:=0 to (y2-y1) do
始める
form1.Canvas.Pen.Color:=icolor;
form1.Canvas.Ellipse(x1-1,y1-1,x1+1,y1+1);
(y2-y1)=0 の場合は終了します。
アズム
押します
移動 eax,y1
株式会社イーエックス
mov y1,eax
ポップイーアックス
終わり;
終了// 終了
else for j:=0 to (x2-x1) do
始める
form1.Canvas.Pen.Color:=icolor;
form1.Canvas.Ellipse(x1-1,y1-1,x1+1,y1+1);
(x2-x1)=0 の場合は終了します。
アズム
押します
移動 eax,x1
株式会社イーエックス
mov x1、eax
ポップイーアックス
終わり;
end;// 終了
終わり;
プロシージャ TForm1.Timer1Timer(sender:TObject);
始める
終わり;
プロシージャ TForm1.DrawRain;
変数
x1,y1,x2,y2,d,i:整数;
始める
for i:=0 ~ 100 を実行します
始める
x1:=ランダム(537);
y1:=ランダム(280);
d:=ランダム(7);
アズム
押します
移動 eax,x1
サブアックス、d
mov x2、eax
移動 eax,y1
eax,d を追加
mov y2,eax
ポップイーアックス
終わり;
回:= 回+1;
drawLine2(x1,y1,x2,y2,clmedGray);
待って();
if (i div 2)=0 thendrawLine2(x1,y1,x2,y2,clwindow);
終わり;
終わり;
プロシージャ TForm1.DrawTree(x,y,height:integer);
変数
x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,d1:整数;
始める
アズム
押します
プッシュセブ
プッシュエク
プッシュEDX
移動 eax、高さ
ムーブ edx,0
移動ecx、2
ダイブックス
mov d1、eax
移動 eax,x
mov ebx,y
サブイーサ、高さ
mov x1、eax
サブEBX、高さ
ムーブ y1、ebx
eax、高さを追加
サブアックス、5
サブEBX、高さ
mov x2、eax
ムーブ y2、ebx
移動 eax,x
eaxを追加、3
サブEBX、高さ
mov x3、eax
ムーブ y3、ebx
eaxを追加、8
ebx、高さを追加
mov x4、eax
ムーブ y4、ebx
eax、高さを追加
サブアックス、5
ebx、高さを追加
mov x5、eax
ムーブ y5、ebx
ポップEDX
ポペックス
ポップebx
ポップイーアックス
終わり;
DrawLine2(x3,y3,x2-d1,y2,clcream);
DrawLine1(x3,y3,x4+d1,y4,clcream);
ドローライン3(x2-d1,y2,x2,y2,clcream);
ドローライン3(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);
ドローライン3(x1,y1,x5,y5,clcream);
ドローライン3(x1,y1-1,x5,y5-1,clcream);
ドローライン3(x,y5,x,y,clcream);
ドローライン3(x,y,x+5,y,clcream);
ドローライン3(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(送信者: TObject);
始める
近い;
終わり;
プロシージャ TForm1.About1Click(送信者: TObject);
始める
form3.表示;
終わり;
プロシージャ TForm1.Spring1Click(送信者: TObject);
変数 i,k,j:整数;
始める
StatusBar1.Panels[1].text:='嵐の春...';
form1.Canvas.Brush.Color:=clwindow;
form1.Canvas.FloodFill(1,1,clred,fsBorder);
for i:=0 ~ 10do
始める
k:=ランダム(10);
j:=ランダム(10);
j:=-j;
drawTree(10+k*50,300+j*20,20);
終わり;
for i:=0 ~ 10 を実行します
始める
form1.Canvas.Brush.Color:=clwindow;
form1.Canvas.FloodFill(1,1,clgreen,fsBorder);
雨を描く;
睡眠(100);
終わり;
終わり;
プロシージャ TForm1.FormCreate(送信者: TObject);
始める
回:=0;
form1.canvas.Brush.Color:=clwindow;
form1.caption:=form1.caption+' Pictype を選択してください!... ';
終わり;
プロシージャ TForm1.drawClear;
変数 i,k:整数;
始める
form1.Canvas.Brush.Color:=clblack;
form1.Canvas.FloodFill(15,15, clcream, fsBorder);
for i:=0 ~ 5 を実行します
始める
k:=ランダム(300);
DrawLine3(20+k,1,20+k,307,cl yellow);
DrawLine3(200+k,1,200+k,307,cl yellow);
終わり;
終わり;
プロシージャ TForm1.Summer1Click(送信者: TObject);
始める
ドロークリア;
form1.Canvas.Font.Color:=clblue;
form1.Canvas.Font.Size:=18;
form1.canvas.textOut(150,150,'緑の海...休憩時間^_^!');
//DrawTree;
終わり;
プロシージャ TForm1.Autumn1Click(送信者: TObject);
始める
ドロークリア;
form1.Canvas.Font.Color:=clblue;
form1.Canvas.Font.Size:=18;
form1.canvas.textOut(150,150,'紅葉と香る山…お休み中^_^!');
終わり;
プロシージャ TForm1.Winter1Click(送信者: TObject);
// 変数 i,x,y:整数;
始める
ドロークリア;
form1.Canvas.Font.Color:=clblue;
form1.Canvas.Font.Size:=18;
form1.canvas.textOut(150,150,'銀の蛇蝋象...まだ開いていません^_^!');
終わり;
プロシージャ TForm1.ext1Click(送信者: TObject);
始める
フォーム5.表示;
終わり;
終わり。
以下は浮動小数点命令を使用した添付のテスト プログラムです。当時のオリジナル バージョンでは効果が得られませんでした。
//ライブラリにチェックするように指示します:)
プロシージャ Tform1.xx;
変数
xmax,ymax,x,y,a,b:単一;
i、z:整数;
始める
a:=2.0;b:=10.0;
xmax:=image1.Width;
ymax:=image1.高さ;
for i:=0 から image1.Width まで
始める
アズム
//.80x87
有限の
fld xmax // xmax を st(0) にプッシュします
fdiv
fchs //st(0)=-st(0)にする
fadd i //st(0)=st(0)+i
fdiv b //st(0)=st(0)/b
fstp x //ポップせずに st(0) を x に入れる
×
fmul x
fchs
流行のymax
//frndint
//ファブ
fstpy
終わり;
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];
終わり;
終わり;
私はプロセスの 1 つを選択しました、はは、面白いですね。
自分の持ち物を取り出して、自分の経験を共有してみてもいいでしょう。私は聞く準備ができています :)。
お願いします - -