Примеры использования сборки в Delphi
-----Тоже второкурсник, по предыдущему примеру. Ха-ха, когда я писал программу, она была немного запутанной, пожалуйста, простите меня :).
Использовать ассемблер для гибридного программирования в Delphi необычайно удобно. Таким образом, если вы хотите повысить эффективность, вы можете выбрать ассемблер, но для большей части работы вы по-прежнему будете наслаждаться удобством визуального и объектно-ориентированного программирования. В языке Delphi, используя сегмент программы asm...end для записи части ассемблерного кода, в сегменте ассемблерного кода можно вызывать переменные языка высокого уровня; на что вам нужно обратить внимание, так это на защиту определенных переменных регистра и затем некоторые подробности и действия. Компиляция ниже отличается. Посмотрите на этот пример.
Давайте сначала поговорим об общих знаниях:
1. Вызвать сборку в Delphi можно двумя способами.
Просто как---
ПРОЦЕДУРА TForm1.DrawRain;
вар
x1,y1,x2,y2,d,i: целое число;
начать // программа Delphi запускается
для i:= от 0 до 100 сделать
начинать
х1:=случайный(537);
у1:=случайный(280);
д:=случайный(7);
asm//встроенная сборка начинается
нажмите eax
перемещение eax,x1
субакс,d
мов x2,eax
перемещение eax,y1
добавить eax,d
mov y2,eax
поп-экспресс
end;;//Конец встроенной сборки
раз:=раз+1;
drawLine2(x1,y1,x2,y2,clmedGray);
ждать();
если (i div 2)=0, то drawLine2(x1,y1,x2,y2,clwindow);
конец;
end;//программа Delphi завершается
Есть еще один способ удалить внешнее начало...конец и напрямую войти в сборку через asm...end.
процедура TForm1.Wait();
asm//встроенная сборка начинается
нажмите eax
перемещение eax,0
@петля:
добавить eax, 1
cmp eax,1000000
jnz @loop
поп-экспресс
end;//конец встроенной сборки
2. Используйте переменные Delphi в сборке
Если вы посмотрите на первый пример кода, это легко понять:
asm//встроенная сборка начинается
нажмите eax
mov eax,x1 //x1 — локальная переменная Delphi, используемая здесь в качестве значения
субэкс,d
mov x2,eax //x2 — локальная переменная Delphi, которая также используется как адрес памяти
перемещение eax,y1
добавить eax,d
mov y2,eax
поп-экспресс
end;;//Конец встроенной сборки
3. Различные детали компиляции
Примеры публиковать не буду. Давайте сравним сами. Например:
@петля:
//...
jnz @loop
Кроме того, большинство int прерываний могут быть недоступны, я не пробовал и не видел никакой информации по этому поводу. Кто знает, пожалуйста, пришлите мне сообщение? Заранее спасибо.
Ниже приведен более крупный пример эффекта анимации. Поскольку раньше я только начал осваивать эти знания, моя работа была очень грубой. Это сцена постоянного дождя в небольшом лесу. Есть много проблем, наиболее заметной из которых является то, что, во-первых, не используются инструкции с плавающей запятой (я приложу тестовые примеры инструкций с плавающей запятой, которые можно будет попробовать позже). ), Некоторые алгоритмы на тот момент еще не были известны, и в результате получилась довольно однообразная картинка. Во-вторых, координация между декорациями была недостаточно хорошей. Например, деревья не были эффективно защищены и позже «зацвели». дождь :).
Но я всё равно привожу пример. Не смейтесь надо мной. Во-первых, у меня нет времени писать примеры в этой области. Во-вторых, если вы научитесь использовать ассемблер, это всё равно сможет объяснить определённые проблемы. Более того, это приложение избегается в общих материалах. Оно иногда упоминается в некоторых продвинутых программах, но если вы хотите освоить его, вам, как правило, придется практиковаться самостоятельно. Этот пример может преподать вам много уроков :).
блок Unit1;
интерфейс
использует
Windows, сообщения, SysUtils, варианты, классы, графика, элементы управления, формы,
Диалоги, ExtCtrls, Меню, ExtDlgs, FileCtrl, StdCtrls, ComCtrls, ImgList;
тип
ТФорм1 = класс (ТФорма)
ГлавноеМеню1: ТМаинМеню;
Файл1: TMenuItem;
Выход1: TMenuItem;
N1: ТМенюитем;
Справка1: TMenuItem;
О1: TMenuItem;
g1: TMenuItem;
Весна1: TMenuItem;
Лето1: TMenuItem;
Осень1: TMenuItem;
Зима1: TMenuItem;
СтатусБар1: ТСтатусБар;
ext1: TMenuItem;
Таймер1: ТТаймер;
процедура Exit1Click (Отправитель: TObject);
процедура About1Click (Отправитель: TObject);
процедура Spring1Click (Отправитель: TObject);
процедура FormCreate (Отправитель: 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 и y2>y1
процедура DrawLine3(x1,y1,x2,y2:integer;iColor:TColor);// x1=x2 или y1=y2
процедура DrawRain;
процедура DrawTree(x,y,height:integer);
процедура Timer1Timer(отправитель:TObject);
процедура drawClear;
процедура Подождите();
{Частные заявления}
общественный
{Публичные заявления}
конец;
вар
Форма1: ТФорм1;
раз: одиночный;
выполнение
использует Unit3, Unit5;
{$R *.dfm}
процедура TForm1.Wait();
асм
нажмите eax
перемещение eax,0
@петля:
добавить eax, 1
cmp eax,1000000
jnz @loop
поп-экспресс
конец;
процедура TForm1.DrawLine1(x1,y1,x2,y2:integer;iColor:TColor);
константа я: целое число = 1;
вар j,k1,k2,d: целое число;
начинать
если((x2-x1)<=0)или((y2-y1)<=0), то выходим;
для 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), то выходим;
асм
нажмите eax
pushebx
pushecx
нажать edx
перемещение ecx, 0
перемещение eax,x2
субакс,x1
мов ebx,y2
суб ebx,y1
мов д, ebx
перемещение EDX, 0
делитель д
mov k2,eax
перемещение eax,y2
суб-eax,y1
перемещение ebx, x2
саб ebx,x1
мов д, ebx
перемещение EDX, 0
делитель д
mov k1,eax
перемещение eax, x1
@цикл2:
добавить eax, я
incecx
cmpecx,k2
джб @loop2
мов x1,eax
перемещение eax,y1
@цикл1:
добавить eax, я
incecx
cmpecx,k1
джб @loop1
mov y1,eax
поп-edx
попеккс
поп-эбкс
поп-экспресс
конец;
конец;// конец для
конец;
процедура TForm1.DrawLine2(x1,y1,x2,y2:integer;icolor:TColor);
константа я: целое число = 1;
вар j,k1,k2,d: целое число;
начинать
если((x1-x2)<=0)или((y2-y1)<=0) то выходим;
для 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), то выходим;
асм
нажмите eax
pushebx
pushecx
нажать edx
перемещение ecx,0
перемещение eax,x1
субакс,x2
мов ebx,y2
суб ebx,y1
мов д, ebx
перемещение EDX, 0
делитель д
mov k2,eax
перемещение eax,y2
суб-eax,y1
перемещение ebx,x1
саб ebx,x2
мов д, ebx
перемещение edx, 0
делитель д
mov k1,eax
перемещение eax, x1
@цикл2:
суб-eax, я
incecx
cmpecx,k2
джб @loop2
мов x1,eax
перемещение eax,y1
@цикл1:
добавить eax, я
incecx
cmpecx,k1
джб @loop1
mov y1,eax
поп-edx
попекс
поп-эбкс
поп-экспресс
конец;
конец;// конец для
конец;
процедура TForm1.DrawLine3(x1,y1,x2,y2:integer;icolor:TColor);
вар j: целое число;
начинать
if((x2-x1)<>0) и ((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, то выходим;
асм
нажмите eax
перемещение eax,y1
Inc EAX
mov y1,eax
поп-экспресс
конец;
конец // конец для
иначе для j:=0 до (x2-x1) сделайте
начинать
form1.Canvas.Pen.Color:=icolor;
form1.Canvas.Ellipse(x1-1,y1-1,x1+1,y1+1);
если (x2-x1)=0, то выходим;
асм
нажмите eax
перемещение eax, x1
Inc EAX
мов x1,eax
поп-экспресс
конец;
конец;// конец для
конец;
процедура TForm1.Timer1Timer(отправитель:TObject);
начинать
конец;
процедура TForm1.DrawRain;
вар
x1,y1,x2,y2,d,i: целое число;
начинать
для i:= от 0 до 100 сделать
начинать
х1:=случайный(537);
у1:=случайный(280);
д:=случайный(7);
асм
нажмите eax
перемещение eax,x1
субакс,d
мов x2,eax
перемещение eax,y1
добавить eax,d
mov y2,eax
поп-экспресс
конец;
раз:=раз+1;
drawLine2(x1,y1,x2,y2,clmedGray);
ждать();
если (i div 2)=0, то drawLine2(x1,y1,x2,y2,clwindow);
конец;
конец;
процедура TForm1.DrawTree(x,y,height:integer);
вар
x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,d1: целое число;
начинать
асм
нажмите eax
pushebx
pushecx
нажать edx
перемещение eax, высота
перемещение EDX, 0
перемещение ecx, 2
погружение
mov d1,eax
перемещение eax,x
мов ebx, y
сабвуфер, высота
мов x1,eax
саб ebx, высота
мов y1,ebx
добавить eax,высоту
субакс, 5
саб ebx, высота
мов x2, eax
мов у2, ebx
перемещение eax,x
добавить eax, 3
саб ebx, высота
мов x3, eax
мов y3,ebx
добавить eax, 8
добавить ebx,высоту
мов x4,eax
мов y4,ebx
добавить eax,высоту
субакс, 5
добавить ebx,высоту
мов x5,eax
мов y5,ebx
поп-edx
попекс
поп-эбкс
поп-экспресс
конец;
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(Отправитель: TObject);
начинать
закрывать;
конец;
процедура TForm1.About1Click(Отправитель: TObject);
начинать
форма3.Показать;
конец;
процедура TForm1.Spring1Click(Отправитель: TObject);
вар я, к, j: целое число;
начинать
StatusBar1.Panels[1].text:='Весна бури...';
form1.Canvas.Brush.Color:=clwindow;
form1.Canvas.FloodFill(1,1,clred,fsBorder);
для я: = от 0 до 10do
начинать
к:=случайный(10);
j:=случайный(10);
j:=-j;
drawTree(10+k*50,300+j*20,20);
конец;
для 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+' Пожалуйста, выберите тип изображения!... ';
конец;
процедура TForm1.drawClear;
вар я, к: целое число;
начинать
form1.Canvas.Brush.Color:=clblack;
form1.Canvas.FloodFill(15,15, clcream, fsBorder);
для i:= от 0 до 5 сделать
начинать
к:=случайный(300);
DrawLine3(20+k,1,20+k,307,clyellow);
DrawLine3(200+k,1200+k,307,clyellow);
конец;
конец;
процедура TForm1.Summer1Click(Отправитель: TObject);
начинать
нарисоватьОчистить;
form1.Canvas.Font.Color:=clblue;
form1.Canvas.Font.Size:=18;
form1.canvas.textOut(150,150,'Зеленый океан... время отдыха^_^!');
//РисоватьДерево;
конец;
процедура TForm1.Autumn1Click(Отправитель: TObject);
начинать
нарисоватьОчистить;
form1.Canvas.Font.Color:=clblue;
form1.Canvas.Font.Size:=18;
form1.canvas.textOut(150,150,'Красные листья и ароматные горы... отдыхают^_^!');
конец;
процедура TForm1.Winter1Click(Отправитель: TObject);
//var i,x,y:integer;
начинать
нарисоватьОчистить;
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:одиночный;
я, г: целое число;
начинать
а:=2,0;б:=10,0;
xmax:=image1.Width;
ymax:=image1.Height;
для i:=0 до image1.Width do
начинать
асм
//.80x87
окончание
fld xmax //вставляем xmax в st(0)
fdiv а
fchs //пусть st(0)=-st(0)
причуда я //st(0)=st(0)+i
fdiv b //st(0)=st(0)/b
fstp x // помещаем st(0) в x без pop
х
фмул х
фчс
причуда ymax
//фрндинт
//фабрики
fstp y
конец;
х:=(я-хмакс/2)/10;
y:=-x*x+ymax;
г: = trunc (г);
image1.canvas.Ellipse(i-1,trunc(y)-1,i+1,trunc(y)+1);
//image1.Canvas.Pixels[x,y];
конец;
конец;
Я выбрал один из процессов, хаха, смешно.
С таким же успехом можно достать свои вещи и поделиться опытом, я готов выслушать :).
пожалуйста----