Обучающие курсы:

Обучение профессии "Разработчик C#" + стажировка в Mail.ru
Обучение профессии "Разработчик Python" + трудоустройство
Обучение профессии "Веб-разработчик" + стажировка в Mail.ru


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





Остановимся теперь более подробно на передаче параметров в процедуры.
Входными параметрами могут выступать либо переменные, либо их адреса
(указатели), либо их комбинация. Передача параметров как значений не
изменяет исходные переменные, поскольку передается копия переменной,
которая не сохраняется при выходе из процедуры.
Модифицируем процедуру суммирования так, чтобы в качестве входных
параметров она принимала переменные и и 12. Исходный текст процедуры
и обработчика нажатия кнопки, где эта процедура вызывается, представлен
в листинге 6.8.

Листинг 6.8. Процедура суммирования двух чисел, использующая параметры
procedure AddTwo(il, i2: Integer);
begin
asm
mov EAX, DWORD PTR il
add EAX, DWORD PTR i2
mov DWORD PTR IRES, EAX
end;
end;
procedure TForml.ButtonlClick(Sender: TObject);
begin
11 := StrToInt(Editl.Text);
12 := StrToInt(Edit2.Text);
AddTwo(II, 12);
Edit3.Text := IntToStr(IRES);
end;

Как видно из листинга, передача параметров и их обработка в процедуре с использованием встроенного ассемблера никаких радикальных отличий по сравнению с обычными процедурами в Delphi не имеет.
Рассмотрим теперь использование процедуры, возвращающей значение. До сих пор наша процедура помещала результат вычисления в переменную IRES. Попробуем теперь обойтись без этой переменной, а результат выполнения процедуры поместить в системную переменную @Resuit, специально предназначенную для этих целей.

Исходный текст процедуры будет выглядеть так, как представлено в листинге 6.9.
Листинг 6.9. Процедура суммирования, возвращающая результат в системной переменной Result
function AddTwo(il, i2: Integer): Integer;
begin
asm
mov EAX, DWORD PTR il
add EAX, DWORD PTR i2
mov @Result, EAX
end;
end;

Исходный текст всей программы в этом случае также изменится. Приведем фрагменты кода, претерпевшие изменения (листинг 6.10).
Листинг 6.10. Фрагмент кода, отображающий изменения в программе, где неиспользуется переменная Resuit
var
Forml: TForml;
II, 12: Integer;
implementation
{$R *.dfm}
function AddTwo(il, i2: Integer): Integer;

begin
asm
mov ЕАХ, DWORD PTR il
add EAX, DWORD PTR i2
mov @Result, EAX
end;
end;
procedure TForml.ButtonlClick(Sender: TObject);
begin
11 := StrToInt(Editl.Text);
12 := StrToInt(Edit2.Text);
Edit3.Text := IntToStr(AddTwo(II, 12));
end;
end.

Поскольку процедура AddTwo возвращает целочисленное значение в системной переменной @Resuit, то нет необходимости использовать переменную IRES для сохранения результата, и ее можно убрать из секции объявления переменных. Мы можем использовать идентификатор процедуры в качестве аргумента при вызове процедуры IntToStr в обработчике нажатия кнопки. Все эти изменения отображены в листинге 6.8.
До сих пор мы работали со значениями переменных. Для обработки массивов данных и строк намного удобней использовать не сами значения, а их адреса в памяти (указатели). Для передачи параметров-указателей используется зарезервированное слово var, причем его область действия распространяется в пределах группы переменных до точки с запятой.
Заменим в предыдущем примере целочисленные параметры il и i2 процедуры AddTwo на их адреса. Для этого в начало списка параметров поместим зарезервированное слово var. Исходный текст обновленной процедуры приведен в листинге 6.11.
Листинг 6.11. Процедура суммирования двух чисел, принимающая в качестве параметров4 адреса, переменных
function AddTwo(var il, i2: Integer): Integer;
begin
asm
mov EAX, DWORD PTR il
mov EAX, [EAX]
mov ECX, DWORD PTR i2
add ЕАХ, [ЕСХ]
mov @Result, ЕАХ
end;
end;

Как видим, в ассемблерном блоке добавились некоторые команды. Первая команда:
загружает адрес переменной ив регистр ЕАХ. Следующая за ней команда извлекает содержимое по адресу, помещенному в регистр ЕАХ, В ЭТОТ же регистр. Для загрузки адреса переменной i2 используется регистр ЕСХ. Команда: суммирует содержимое регистра ЕАХ С содержимым ячейки памяти, чей адрес находится в регистре ЕСХ. КОД обработчика нажатия кнопки в этом случае не изменится.
Указать процедуре на то, что параметрами являются адреса переменных, можно и другим, часто используемым способом — явно определить параметр как указатель. При этом необходимо указать тип указателя, который соответствует типу переменной.

Например, для переменной типа integer указателем является pinteger, для переменной вещественного типа указателем является psingie и т. д. Следовательно, объявление нашей процедуры, если использовать указанные ранее соотношения, будет выглядеть так:
function AddTwo(il, i2: Pinteger): Integer;
Если используется такое определение параметров процедуры, то код обработчика нажатия кнопки изменится (листинг 6.12).

Листинг 6.12. Фрагмент кода обработчика нажатия кнопки с измененным вариантом вызова процедуры суммирования
procedure TForml.ButtonlClick(Sender: TObject);
begin
11 := StrToInt(Editl.Text);
12 := StrToInt(Edit2.Text);
mov EAX, DWORD PTR il
add EAX, [ECX]
Edit3.Text := IntToStr(AddTwo(011, 012));
end;


 
 
 

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