Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей





В Object Pascal обращение к переменной означает обращение к ее значению. Обращение к переменной во встроенном ассемблере означает обращение к адресу, где находится переменная. Например, выражение х + 2 в Object Pascal, где х — переменная, означает сумму х и 2. Встроенный ассемблер трактует выражение х + 2 как содержимое ячейки памяти с адресом на 2 байта больше, чем х. Поэтому следующая команда
asm
mov ЕАХ, Х+2
end;
вместо суммы переменной х и 2 загрузит в регистр ЕАХ значение ячейки памяти по адресу х + 2. Правильно будет выполняться следующий фрагмент кода:
asm
mov ЕАХ, X
add ЕАХ, 2
end;

Следующий пример раскрывает более подробно особенности операций с переменными. Требуется найти сумму первого элемента целочисленного массива х и числа 4. Решим эту задачу двумя способами, причём отобразим результат вычисления в двух разных окнах.
Для этого разместим на главной форме приложения два поля редактирования Edit и две кнопки Button. Напишем программный код обработчиков нажатия кнопок. Исходный текст программы приведен далее в листинге 6.1.
Листинг 6.1. Программа, демонстрирующая особенности работы с переменными встроенного ассемблера
unit demopas;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls;
type
TForml = class(TForm)
Editl : TEdit;
Edit2 : TEdit;
Buttonl: TButton;
Button2: TButton;
procedure ButtonlClick(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Forml: TForml;
X: array [1..5] of Integer = (2, -5, 8, 1, - 4 ) ;
IX: Integer;
Implementation
{$R *.dfm}
procedure TForml.ButtonlClick(Sender: TObj ect);
begin
asm
mov EAX, DWORD PTR X+4
mov IX, EAX
end;
Editl.Text := IntToStr(IX);
end;
procedure TForml.Button2Click(Sender: TObject);
begin
asm
mov EAX, DWORD PTR X
add EAX, 4
mov IX, EAX
end;
Edit2.Text := IntToStr(IX);
end;
end.

Внимательно проанализируем код программы. Начнем с обработчика нажатия кнопки Buttoniciick. Результат выполнения кода:
mov ЕАХ, DWORD PTR X+4
mov IX, EAX
будет отображен в поле редактирования Editl (левое поле на рис. 6.1). Вместо ожидаемого значения 6 мы получили значение второго элемента массива, т. е. —5. Первая команда ассемблера помещает в регистр ЕАХ значение второго элемента массива. Поскольку массив состоит из целых чисел, то каждый последующий элемент отстоит от предыдущего на 4 байта, следовательно, мы попадаем на второй элемент массива.
Обработчик кнопки Button2 выполняет операцию сложения так, как нам нужно:
mov EAX, DWORD PTR X
add ЕАХ, 4
mov IX, ЕАХ;

После выполнения этого фрагмента кода в поле редактирования Edit2 будет выведен правильный результат, т. е. 6. Первая команда загружает в регистр ЕАХ значение первого элемента массива, а вторая прибавляет к содержимому этого регистра 4.

6.4. Использование меток во встроенном ассемблере
Метки используются во встроенном ассемблере так же, как и в Object Pascal. Они должны быть объявлены в разделе деклараций блока begin-end, содержащего блок asm-end, с помощью зарезервированного слова label.
Следующий фрагмент кода, в котором выполняется сравнение двух вещественных чисел и запоминание меньшего из них в переменной xres, приводится в листинге 6.2.
Листинг 6.2 Фрагмент кода, демонстрирующий использование меток var
xl, х2, xres: Single;
Label xlLx2, xlGx2;
begin
xl := -98.23;
x2 := -151.87;
asm
f init
fid DWORD PTR xl
fcomp
fstsw
sahf
fwait
jb
mov
jmp
xlLx2:
mov
xlGx2:
mov
end;
DWORD PTR x2
xlLx2
EAX, x2
xlGx2
EAX, xl
DWORD PTR xres, EAX
end;

Есть только одно исключение из этого правила, которое касается локальных меток. Локальная метка начинается всегда с символа "@", и предварительно
ее декларировать не нужно. Она представляет собой последовательность литер, цифр и знаков подчеркивания. Область видимости локальных меток
ограничена блоком asm-end. Предыдущий фрагмент кода, в котором вместо обычных используются локальные метки, приведен в листинге 6.3.
Применение локальных меток в блоке asm-end _ vvar
xl, x2, xres: Single;
begin
xl := -98.23;
x2 := -151.87;
asm
f init
fid DWORD PTR xl
fcomp DWORD PTR x2
fstsw
sahf
fwait
jb @xlLx2
432 Гпава 6
mov ЕАХ, х2
jmp @xlGx2
@xlLx2:
mov EAX, xl
@xlGx2:
mov DWORD PTR xres, EAX
end;
end;

6.5. Примеры использования встроенного ассемблера в Delphi-приложениях
Для иллюстрации основных моментов использования встроенного ассемблера
разработаем несколько простых приложений. Пусть в нашем первом
примере требуется найти сумму двух целых чисел. Вначале разработаем вариант
программы, в которой нет ассемблерных команд, а используются
только операторы Delphi.

Разместим на главной форме три поля редактирования Edit с именами
Editl, Edit2 и Edit3, а также кнопку Button. Ввод операндов должен выполняться
с помощью полей редактирования Editl, Edit2, вывод результата
по нажатию кнопки Buttoni — в поле Edit3.
Исходный текст программы приведен в листинге 6.4 с помощью обычных операторов Delphi
unit basmlpas;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls;
type
TForml = class(TForm)
Buttonl: TButton;
Editl : TEdit;
Labell : TLabel;
Edit2 : TEdit;
Edit3 : TEdit;
Label2 : TLabel;
Label3 : TLabel;
procedure ButtonlClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Forml: TForml ;
II, 12, IRES: Integer;
Implementation
{$R *.dfm}
procedure TForml.ButtonlClick(Sender: TObject);
begin
11 := StrToInt(Editl.Text);
12 := StrToInt(Edit2.Text);
IRES := II + 12;
Edit3.Text := IntToStr(IRES);
end;
end.

Обработчик нажатия кнопки Buttonl очень прост и содержит всего три
оператора. Смысл переменных и, 12 и I R E S , как и операторов обработчика,
скорее всего, понятен.


 
 
 

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