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





Как видите, в исходном тексте произошли существенные изменения. Для извлечения адреса переменной из стека и передачи значения, хранящегося по этому адресу, используется регистр E S I . Переменная и помещается в регистр ЕАХ с помощью двух команд:
mov ESI, DWORD PTR [EBP+12]
mov EAX, [ESI]

Поскольку мы сохранили предварительно содержимое регистра E S I в стеке, то переменная и хранится по адресу ЕВР + 12, а переменная 12 — по адресу ЕВР + 16.

Команды:
mov subRes, ЕАХ
mov ЕАХ, offset subRes
сохраняют результат в переменной subRes, а в регистре ЕАХ .возвращают адрес этой переменной. Посмотрим, как изменится исходный текст приложения на Delphi по сравнению с предыдущим примером. В секции implementation переопределим нашу процедуру:
implementation
{$R *.dfm} '
{$L subtwop.obj}
function subtwop(pil:PInteger; pi2:Pinteger):PInteger; stdcaii; external;

В обработчике нажатия кнопки исходный текст также изменится (листинг 3.25).
Листинг 3.25. Обработчик нажатия кнопки в программе на Delphi 7
procedure TForml.ButtonlClick(Sender: TObject);
var
II, 12: Integer;
begin
11 := StrToInt(IlEdit.Text);
12 := StrToInt(I2Edit.Text);
subResuit.Text := IntToStr(subtwop(@I1, @12)л);
end;

В модифицированном варианте программы интерес вызывает строка
subResuit.Text:= IntToStr (subtwop (@I1, @I2)A);

Символы "@" перед переменными п и 12 означают операцию взятия адреса этих переменных, т. к. процедура subtwop в качестве параметров принимает указатели типа pinteger. Символ "Л" после идентификатора процедуры означает разыменование указателя (dereferencing). Так как subtwop возвращает указатель на переменную целого типа, то разыменование возвращает целое значение, находящееся по этому адресу. Функция IntToStr принимает в качестве параметра целочисленную переменную, поэтому все наши преобразования корректны.

Использование указателей в Delphi — это отдельная тема, но она настолько важна, что необходимо остановиться на ней более подробно. Применение указателей лучше всего продемонстрировать на примере (листинг 3.26).
Листинг 3.26. Пример использования указателей в программе на Delphi
var
II, 12: Integer;
Р: AInteger;
begin
11 := 10;
P := @I1;
12 := Рл;
end;

Переменные и и 12 объявляются как це\лые, а переменная p — как указатель на целое. Затем переменной и присваивается значение ю. Строка:
Р := @11;
присваивает указателю р адрес, где хранится переменная и. Оператор:
12 := Рл;
выполняет разыменование указателя р и присваивает переменной 12 значение, находящееся по адресу р. Таким образом, в результате выполнения этого фрагмента программного кода переменной 12 будет присвоено значения il, т. е. 12 = 10. Оператор взятия адреса "@" применяется также и для работы с процедурами и функциями.
Программный код ассемблерной процедуры для работы с приложением на С++ .NET изменится в части именования функции subtwop (листинг 3.27).
Листинг 3.27. Ассемблерная процедура для работы с программой на С++
.386
.model flat
public _subtwop@8
.data
subRes DD 0
.code
_subtwop@8 proc
_subtwop@8 endp
end

Фрагмент кода для вызова ассемблерной процедуры из С + + .NET приведен в листинге 3.28.
Листинг 3.28. Фрагмент кода для вызова ассемблерной процедуры из программы на С++
void CSubstractTwoByPointersDlg:rOnBnClickedButtonl()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
SubRes = *subtwop(&Il, &I2);
UpdateData(FALSE);
}


 
 
 

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