Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Asm_lab-Rus.docx
Скачиваний:
12
Добавлен:
27.08.2019
Размер:
239 Кб
Скачать
        1. Искажение имен

При компоновке библиотеки на различных языках высокого уровня возникает искажение имен.

Компиляторы Microsoft С (а также многие компиляторы в UNIX) изменяют названия процедур, чтобы отразить используемый способ передачи параметров. Так, к названиям всех процедур, использующих С-конвенцию, приписывается символ подчеркивания. То есть, если в С-программе записано

some_proc();

то реально компилятор пишет

call _some_proc

и это означает, что, если эта процедура написана на ассемблере, она должна называться именно _some_proc (или использовать сложную форму записи директивы proc).

Названия процедур, использующих конвенцию STDCALL, искажаются компилятором еще более сложным образом: спереди к называнию процедуры добавляется символ подчеркивания, а сзади – символ @ и размер занимаемой параметрами области стека в байтах, (то есть в точности число, стоящее после команды ret в конце процедуры).

some_proc(a:word);

превращается в

push a

call _some_proc@4

При написании библиотек на языке ассемблер необходимо учитывать эти особенности. Для того чтобы ассемблер корректно определил количество байт передаваемых в подпрограмму параметров, необходимо их описать при объявлении подпрограммы, аналогично тому, как это осуществляется на языках высокого уровня. Например:

some_proc PROC EXPORT a:DWORD, b:DWORD

В основной программе, вызывающей эту подпрограмму из библиотеки, её необходимо описать с использованием ключевого слова EXTERN (если будет использовано неявное связывание).

EXTERN _some_proc@8:NEAR

Вызов подпрограммы должен быть осуществлен с использованием конвенции STDCALL.

push b

push a

call _some_proc@8

Библиотеки могут содержать не только подпрограммы, но и данные. Для того чтобы данные объявленные в библиотеке стали доступны всем процессам, использующим эту библиотеку необходимо скомпоновать её с указанием атрибутов Shared, Read, Write для сегмента данных. В компоновщике Link для этого предусмотрен параметр /section. В общем случае строка для компоновки выглядит следующим образом:

Link /SUBSYSTEM:WINDOWS /DLL /section.data,SRW dllname.obj

        1. Подключение библиотек

Обобщенный алгоритм загрузки DLL при явном связывании выглядит следующим образом:

  1. Загрузить DLL с помощью функции LoadLibrary. Данная функция принимает 1 параметр – имя динамической библиотеки и возвращает 0, если невозможно загрузить библиотеку, либо идентификатор библиотеки. Данный параметр должен быть сохранен в переменной для дальнейшего использования.

  2. Определить адрес функции, которую необходимо вызвать. Для этого служит функция GetProcAddress, принимающая 2 параметра. 1-й – идентификатор библиотеки, 2-й – имя подпрограммы. Возвращает 0 – в случае невозможности определить адрес подпрограммы, либо её адрес.

  3. Вызвать подпрограмму и получить результат.

  4. Выгрузить библиотеку из памяти с помощью функции FreeLibrary. Данная функция принимает 1 параметр – идентификатор библиотеки.

Если нет необходимости в явном связывании, то можно использовать неявное связывание. Для этого достаточно указать путь к библиотеке, точнее путь к её заголовочному файлу. Данный файл имеет тоже имя, что библиотека и расширение .lib. Данный файл формируется автоматически всеми компиляторами Microsoft C и MASM32.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]