Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей
|
Для разработки приложения используем, как и в большинстве задач, главную
форму с размещенными на ней полей редактирования Edit и кнопкой
Button. Исходный текст программы представлен в листинге 6.15.
Листинг 6.15. Программа, выполняющая подсчет суммы элементов в массиве целых чисел
unit sarpas;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls;
type
TForml = class(TForm)
Buttonl: TButton;
Editl : TEdit;
procedure ButtonlClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Forml: TForml;
IARRAY: array [1..5] of Integer = (45, -23, -5, 11, 7);
IL: Integer;
ISUM: Integer;
implementation
{$R *.dfm}
procedure TForml.ButtonlClick(Sender: TObject);
begin
IL := SizeOf(IARRAY) div 4;
asm
push ESI
mov ESI, offset IARRAY
mov ECX, DWORD PTR IL
dec ECX
f init
fild DWORD PTR [ESI]
@L1:
fiadd DWORD PTR [ESI+4]
add ESI, 4
loop @L1
fistp DWORD PTR ISUM
fwait
pop ESI
end;
Editl.Text := IntToStr(ISUM);
end;
end.
Вычисление суммы элементов выполняется в блоке asm-end с использованием
команд математического сопроцессора. Доступ к элементам массива
осуществляется через регистр E S I , в который командой:
mov ESI, offset IARRAY
загружается адрес массива, равный адресу его первого элемента. В стек сопроцессора
загружается первый элемент массива, после чего в каждой итеграции цикла содержимое стека суммируется с последующим элементом
массива. Каждый из элементов массива занимает в памяти 4 байта, поэтому
следующий операнд адресуется командой:
add ESI, 4
По окончанию вычислений содержимое вершины стека запоминается в переменной
ISUM командой:
fistp DWORD PTR ISUM
одновременно с очисткой вершины стека сопроцессора.
Обратите внимание на использование меток в программе. У нас всего одна
метка цикла, организованного командой loop. Поскольку метка является
локальной (используется внутри блока asm-end), то предварительно
объявлять ее не нужно.
Попробуем изменить исходный текст ассемблерного блока таким образом,
чтобы его можно было применить в отдельной процедуре. Для начала определим,
какие входные параметры будут использоваться. Если еще раз проанализировать
исходный текст программы, то можно прийти к выводу, что
в качестве входных параметров процедуры можно передавать адрес массива
и его размер. В качестве результата в основную программу можно вернуть
значение суммы элементов. Исходный текст приложения с учетом сделанных
изменений выглядит, как показано в листинге 6.16.
Листинг 6.16. Программа подсчета суммы элементов массива с использованием
отдельной процедуры
unit sarray;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls;
type
TForml = class(TForm)
Buttonl: TButton;
Editl : TEdit;
procedure ButtonlClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Forml: TForml;
iarray: array [1..5] of Integer
IL: Integer;
isum: Integer;
implementation
{$R *.dfm}
function SumArray(var iaddr; cnt: Integer): Pinteger;
begin
asm
push ESI
mov ESI, DWORD PTR iaddr
mov ECX, DWORD PTR cnt
dec ECX
finit
fild DWORD PTR [ESI]
@L1:
fiadd DWORD PTR [ESI+4]
add ESI, 4
loop @L1
fistp DWORD PTR isum
fwait
mov EAX, offset isum
mov @Result, EAX
pop ESI
end;
end;
<< Назад В начало Далее >> |
|