delphi中使用汇编例子
-----也是大二的,接着上一个例子。呵呵,程序当时写的有点乱,请原谅:)。
delphi中使用汇编进行混合编程,是异乎寻常的方便。如此,当你希望得到效率的时候,你可选择汇编,然而大部分工作,你仍是享受着可视化、面向对象编程的方便。delphi的语言,通过使用asm...end程序段写汇编代码部分,在汇编代码段中可以调用高级语言的变量;你需要注意的是,保护某些寄存器变量,然后呢,某些细节和dos下的汇编不同。大家看这个例子。
先大体说说一些小知识:
一,delphi调用汇编,有两种方式。
一如---
procedure tform1.drawrain;
var
x1,y1,x2,y2,d,i:integer;
begin//delphi程序开始
for i:=0 to 100 do
begin
x1:=random(537);
y1:=random(280);
d:=random(7);
asm//内嵌汇编开始
push eax
mov eax,x1
sub eax,d
mov x2,eax
mov eax,y1
add eax,d
mov y2,eax
pop eax
end;;//内嵌汇编结束
times:=times+1;
drawline2(x1,y1,x2,y2,clmedgray);
wait();
if (i div 2)=0 then drawline2(x1,y1,x2,y2,clwindow);
end;
end;//delphi程序结束
还有一种,把外层的begin...end去掉,通过asm...end直接进入汇编。
procedure tform1.wait();
asm//内嵌汇编开始
push eax
mov eax,0
@loop:
add eax,1
cmp eax,1000000
jnz @loop
pop eax
end;//内嵌汇编结束
二,在汇编中使用delphi的变量
大家看第一段代码的例子,很容易明白:
asm//内嵌汇编开始
push eax
mov eax,x1 //x1是delphi局部变量,此处用作值
sub eax,d
mov x2,eax //x2是delphi局部变量,又用作内存地址
mov eax,y1
add eax,d
mov y2,eax
pop eax
end;;//内嵌汇编结束
三,汇编的不同细节
例子不帖了,大家自己比较了,如
@loop:
//...
jnz @loop
另外,大部分int中断可能不能用,我没有试通,也没见什么资料上介绍过。谁知道,给我发个消息好吗?谢谢了先。
下面是一个比较大的例子,是一个动画效果。因为以前刚开始学这方面的知识,做的很粗糙。是一个小树林里,不停的下着雨的场景---很多问题,表现突出的是,首先浮点指令没有会用(我在后面会附上有待继续尝试的浮点数指令的测试例子),一些算法当时还不会,结果画面比较单调,其次,对景物间的协调不够好,比如树没有有效保护,后来就被雨“花”了:)。
可还是做例子了,大家别笑我,一来没时间写这方面的例子了,二来,学delphi中的汇编使用,它还是可以说明某些问题的。而且,一般的资料上,是回避这个应用的,个别的高级编程中,偶尔提及,可大家要想掌握,大都得要自己多实践,这个例子可以个给你许多教训:)。
unit unit1;
interface
uses
windows, messages, sysutils, variants, classes, graphics, controls, forms,
dialogs, extctrls, menus, extdlgs, filectrl, stdctrls, comctrls, imglist;
type
tform1 = class(tform)
mainmenu1: tmainmenu;
file1: tmenuitem;
exit1: tmenuitem;
n1: tmenuitem;
help1: tmenuitem;
about1: tmenuitem;
g1: tmenuitem;
spring1: tmenuitem;
summer1: tmenuitem;
autumn1: tmenuitem;
winter1: tmenuitem;
statusbar1: tstatusbar;
ext1: tmenuitem;
timer1: ttimer;
procedure exit1click(sender: tobject);
procedure about1click(sender: tobject);
procedure spring1click(sender: tobject);
procedure formcreate(sender: tobject);
procedure summer1click(sender: tobject);
procedure autumn1click(sender: tobject);
procedure winter1click(sender: tobject);
procedure ext1click(sender: tobject);
private
procedure drawline1(x1,y1,x2,y2:integer;icolor:tcolor);// x2>x1 and y2>y1
procedure drawline2(x1,y1,x2,y2:integer;icolor:tcolor);// x2<x1 and y2>y1
procedure drawline3(x1,y1,x2,y2:integer;icolor:tcolor);// x1=x2 or y1=y2
procedure drawrain;
procedure drawtree(x,y,height:integer);
procedure timer1timer(sender:tobject);
procedure drawclear;
procedure wait();
{ private declarations }
public
{ public declarations }
end;
var
form1: tform1;
times:single;
implementation
uses unit3,unit5;
{$r *.dfm}
procedure tform1.wait();
asm
push eax
mov eax,0
@loop:
add eax,1
cmp eax,1000000
jnz @loop
pop eax
end;
procedure tform1.drawline1(x1,y1,x2,y2:integer;icolor:tcolor);
const i:integer=1;
var j,k1,k2,d:integer;
begin
if((x2-x1)<=0)or((y2-y1)<=0) then exit;
for j:=0 to (x2-x1) do
begin
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)or((y2-y1)=0) then exit;
asm
push eax
push ebx
push ecx
push edx
mov ecx,0
mov eax,x2
sub eax,x1
mov ebx,y2
sub ebx,y1
mov d,ebx
mov edx,0
div d
mov k2,eax
mov eax,y2
sub eax,y1
mov ebx,x2
sub ebx,x1
mov d,ebx
mov edx,0
div d
mov k1,eax
mov eax,x1
@loop2:
add eax,i
inc ecx
cmp ecx,k2
jb @loop2
mov x1,eax
mov eax,y1
@loop1:
add eax,i
inc ecx
cmp ecx,k1
jb @loop1
mov y1,eax
pop edx
pop ecx
pop ebx
pop eax
end;
end;// end for