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

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


Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для 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]. НО где из них первый, а где второй? Чтобы ответить на этот вопрос, необходимо указать в вызывающей программе порядок передачи аргументов.


 
 
 

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