Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей
|
• Параметры в вызываемую процедуру передаются через стек, через регистры
или через общую область памяти. Передача параметров через общую
область памяти для 32-разрядных приложений — вещь довольно
экзотическая из-за сложности реализации и применяется обычно системными
программистами и разработчиками драйверов устройств. Это
отдельная тема, и мы ее рассматривать не будем.
Перед возвращением в основную программу необходимо восстановить указатель
стека. Это ОТНОСИТСЯ К директивам pascal, cdecl, stdcall И safecall.
Что касается применения тех или иных способов вызова внешних
процедур, то здесь не существует однозначных рецептов. Если вы работаете
с API функциями Windows, то для них стандартным способом вызова является
stdcaii или safecaii. Директиву cdecl лучше использовать для вызова
процедур и функций из программ, написанных в С + + .
Наиболее быстрым способом передачи параметров является регистровый
(register, или fastcaii). Директива register используется в большинстве
языков высокого уровня, но разработчики Microsoft решили назвать ее по-
другому, и в Visual С + + она определяется иначе — fastcaii. Стек в этом
случае не используется, поэтому мы получаем выигрыш по скорости выполнения
подпрограммы.
Директива pascal используется редко и только в целях обратной совместимости
(backward compatibility). Мы не будем использовать ее в наших примерах.
Все подпрограммы возвращают результат (значение или адрес) в регистре
ЕАХ.
Для иллюстрации вышесказанного разработаем небольшую демонстрационную
процедуру на ассемблере, которая будет находить сумму двух целых
чисел. Наша процедура будет работать с приложениями, написанными на
Delphi 7 и Visual С + + .NET. Программа на языке высокого уровня будет
передавать ей два целочисленных аргумента в качестве параметров, а в
качестве результата получать сумму этих чисел.
На этом простом примере я покажу, как работает интерфейс ассемблерных
процедур и программ на языках высокого уровня для разных вариантов передачи
параметров и с двумя несколько отличными друг от друга инструментами
разработки — Delphi и Visual С++. Для компиляции исходного
текста процедуры на ассемблере мы будем использовать как MASM 6.14, так
и TASM 5.0.
Каркас процедуры для варианта передачи параметров stdcaii приведен в
листинге 3.13.
Листинг 3.13. Процедура на ассемблере, выполняющая суммирование
двух чисел ;
.386
.model flat
public Addlnts
. data
. code
Addlnts proc
push EBP
mov
mov EBP, ESP
EAX, DWORD PTR [EBP+8]
add EAX, DWORD PTR [EBP+12]
pop EBP
ret 8
Addlnts endp
end
Процедура получает два целочисленных параметра через стек, а результат
возвращает в регистре ЕАХ.
Первые две строки — стандартное начало для 32-разрядных приложений.
Далее, поскольку процедура Addlnts должна быть доступна из внешних модулей,
необходимо объявить ее с директивой public. Первые две строки
тела процедуры:
push EBP
mov EBP, ESP
необходимы для доступа к параметрам в стеке с помощью регистра ЕВР. Сами
параметры находятся в стеке по адресам [ЕВР+8] И [ЕВР+12]. НО где из
них первый, а где второй? Чтобы ответить на этот вопрос, необходимо указать
в вызывающей программе порядок передачи аргументов.
<< Назад В начало Далее >> |
|