Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для 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;


 
 
 

Библиотека программиста. 2009.
Администратор: admin@programmer-lib.ru