- •Аппаратно-ориентированное программирование
- •Ббк 32.973.73
- •Удк 681.3 ббк 32.973.73ф 73
- •1. Основы программирования на ассемблере
- •1.1. Принципы построения ассемблерных программ
- •1.2. Понятие архитектуры компьютера
- •1.3. Регистры программиста в ia32
- •1.4. Описание сегментной структуры программы
- •2. Простейшие средства ассемблера
- •2.1. Средства описания данных
- •2.2. Обращения к функциям ос посредством прерываний
- •2.3. Средства преобразования в исполняемый файл
- •2.4. Управление строками при выводе и ввод данных
- •2.5. Простейшие способы адресации
- •3. Архитектурные элементы для построения программ
- •3.1. Организация условных переходов
- •3.2. Средства организации циклов
- •3.3. Особенности команд умножения и деления
- •3.4. Организация процедур
- •3.5. Неарифметические операции над кодами
- •4. Использование неэлементарных способов адресации
- •4.1. Косвенно-регистровая адресация
- •4.2. Использование индексной адресации данных
- •4.3. Базовая и индексно базовая адресации
- •4.4. Адресация с масштабированием
- •5. Взаимосвязи программных единиц
- •5.1. Многомодульная разработка программ
- •5.2. Использование библиотек объектных модулей
- •5.3. Организация стекового кадра подпрограммы
- •5.4. Программный доступ к системным функциям Win32
- •5.5. Особенности использования объектных файлов формата coff
- •5.6. Стандартный доступ к системным функциям Unix
- •6. Вспомогательные средства базовой архитектуры
- •6.1. Использование строковых команд пересылки
- •6.2. Применение строковых команд сравнения
- •7. Использование ассемблерных отладчиков
- •7.1. Особенности отладчика gdb для программ в Linux
- •7.2. Отладчики текстового режима для Windows
- •Библиографический список
- •Оглавление
5.2. Использование библиотек объектных модулей
Когда объектных модулей, необходимых для компоновки программы, оказывается много, программисту становится неудобным перечислять их все при вызове компоновщика. Ситуация становится почти катастрофической, когда таких модулей многие десятки и даже сотни.
Выход был найден с помощью специализированных наборов объектных модулей, хранимых как отдельные файлы и называемых обычно библиотеками объектных модулей. В ОС Unix для аналогичных целей вначале использовался еще термин архив объектных модулей, но к настоящему времени, в связи с широким использованием архивирования как метода сжатого сохранения любых файлов и каталогов файлов, последняя терминология оказывается несколько двусмысленной (по крайней мере, неоднозначной).
Применение библиотек требует использования служебных утилит обслуживания, называемых обычно библиотекарями или архиваторами (последний термин характерен для Unix и, как уже объяснялось, несколько устарел).
Утилита обслуживания библиотек в Unix называется ar и ее вызовы имеют в упрощенной форме общей вид
ar опции модификаторы имя_библиотеки объектные_файлы
где компонент объектные_файлы представляет собой перечисление имен файлов, разделяемых пробелами. Заметим, что данная утилита может применяться для сохранения в виде компактного набора не только объектных файлов, но и любых других файлов, но именно библиотеки объектных файлов являются мощным вспомогательным средством при разработке сложных программ.
Основными опциями данной утилиты, которые мы рассмотрим, являются опции -r, -d, -m, -t. Первая из них задает добавление нового объектного файла или файлов к библиотеке, вторая опция задает удаление указанных в перечне файлов из библиотеки, третья опция задает перемещение указанных в перечне файлов из библиотеки в текущий каталог, а опция -t приказывает выдать на стандартный вывод перечень файлов, содержащихся в библиотеке. Модификаторы призваны повысить эффективность использования и построения библиотек и записываются непосредственно за опцией. Модификатор, задаваемый буквой 'c', предназначен для указания, что библиотеку нужно создать. Стандартное расширение имени библиотек объектных модулей в Unix содержит единственную букву 'a' (строчную латинскую букву).
Следующий пример демонстрирует использование библиотеки объектных модулей. Сами модули формируются из исходных файлов с именами stwrite, stread, stexit, содержащих, соответственно, процедуры stdread, stdwrite, stdexit и приведенные в листингах 5.2.1, 5.2.2 и 5.2.3.
GLOBAL stdread
SEGMENT .text
stdread: ;<adress into ecx, max len into edx, actlen ->eax >
;--- read(1, buf, len) == <3>(ebx, ecx, edx)
push ebx
mov eax,3 ; N function=read
mov ebx,0 ; 0 handle=0 (stdin)
int 80h
pop ebx
ret
Листинг 5.2.1. Процедура stdread в файле stread.asm для библиотеки Linux
GLOBAL stdwrite
SEGMENT .text
stdwrite: ;<adress into ecx, max len into edx>
;--- write(1, buf, len) == <4>(ebx, ecx, edx)
push eax
push ebx
mov eax,4 ; N function=write
mov ebx,1 ; N handle=1 (stdout)
int 80h
pop ebx
pop eax
ret
Листинг 5.2.2. Процедура stdwrite в файле stwrite.asm для библиотеки Linux
GLOBAL stdexit
SEGMENT .text
stdexit:
mov eax,1
int 80h ; function=exit
ret
Листинг 5.2.3. Процедура stdexit в файле stexit.asm для библиотеки Linux
Формирование объектных файлов проще всего выполнить с помощью командного файла, содержимое которого приведено в листинге 5.2.4, и имеющего для дальнейшего использования имя nasmc.
nasm -f elf $1.asm -l $1.lst
Листинг 5.2.4 Командный файл nasmc для раздельной трансляции
Далее с помощью командного вызова
ar -rc myliba.a stwrite.o stread.o stexit.o
нужно построить библиотеку с именем myliba.a . Использование библиотеки предполагает программа, приведенная в листинге 5.2.5.
GLOBAL _start
EXTERN stdread, stdwrite, stdexit
SEGMENT .text
_start:
;--- stdread(buf, 80) == call stdread < ecx, edx >, result into eax
mov ecx, buf ; address of buf
mov edx,80 ; number of byte
call stdread ; arguments into ECX, EDX - адрес области для данных и ее длина
mov [len],eax ; число прочитанных байтов в регистре EAX
mov byte [buf+2],'!'
;--- stdwrite(buf, [len]) == call stdwrite < ecx, edx >
mov ecx, buf ; address of buf
mov edx,[len] ; number of byte
call stdwrite ; arguments into ECX, EDX - адрес области данных и их длина
call stdexit
SEGMENT .bss
buf resb 80
SEGMENT .data
len dd 0
Листинг 5.2.5. Пример prim5e.asm использования процедур
из собственной библиотеки
Изготовление исполняемой программы из исходного текста в листинге 5.2.5 может осуществляться двумя командными вызовами, приведенными в следующих строках
./nasmc prim5e
ld -o prime.exe prim5e.o myliba.a
Процесс изготовления исполняемой программы примера можно автоматизировать, применяя командный файл, текст которого дан в листинге 5.2.6
./nasmc stwrite
./nasmc stread
./nasmc stexit
ar -rc myliba.a stwrite.o stread.o stexit.o
ar -t myliba.a
./nasmc prim5e
ld -o prime.exe prim5e.o myliba.a
Листинг 5.2.6. Файл komfil построения и использования библиотеки
Заметим, что имена процедур в объектных модулях библиотеки никак не связаны (кроме возможных человеческих ассоциаций разработчика) с именами соответствующих объектных файлов. Более того, один библиотечный файл может содержать множество процедур и, в общем случае, любых внешних имен, используемых в дальнейшем из этой библиотеки. Установление связей между компонентами будущей исполняемой программы в процессе компоновки осуществляется исключительно по внешним именам в модулях, занесенных в библиотеку, а имена объектных модулей существенны только для приказов вставки или удаления объектных модулей в (из) библиотеки. В частности, процедуры stdread, stdwrite, stdexit целесообразно поместить в один исходный файл и, как следствие, в один объектный файл. В общем случае разнесение процедур по различным объектным модулям приводит к тому, что к машинным кодам компонуемой программы подключаются машинные коды только тех объектных модулей библиотеки, которые действительно необходимы, а остальные не подключаются.
При компоновки исполняемой программы при вызове компоновщика может быть указано столько библиотек, сколько необходимо. Для этого их следует просто включить в перечень обрабатываемых компоновщиком файлов, компоновщик сам определяет, что с ними делать, используя их внутренний формат.
При программировании для операционных систем типа MS (MS-DOS, OS/2, Windows) используются утилиты библиотекарей с типовым названием lib.exe. Первым дополнительным символом в имени такого библиотекаря могут быть символы фирменной идентификации утилиты. Так библиотекарь для MS-DOS и OS/2 фирмы Borland/Inprise имеет название TLIB.EXE. Синтаксис команд управления библиотекарем в указанных и ряде других современных ОС имеет в общем случае вид
имя_библиотекаря имя_библиотеки команда объектный файл
где последние два параметра могут повторяться. Элемент команда командного вызова представляется здесь одним или двумя служебными символами, причем для добавления объектного модуля к библиотеке используется символ '+', а для исключения из библиотеки используется символ '-' (дефис). В частности, действия, аналогичные рассмотренному примеру для Unix, для библиотекаря TLIB запишутся в виде команды
tlib myliba.lib +stwrite.obj +stread.obj +stexit.obj
Причем стандартным расширением библиотек в этих системах разработки является буквосочетание lib, а obj используется как стандартное расширение объектных файлов. Эти стандартные расширения могут опускаться при задании команд обработки для утилиты.
Для выдачи перечня объектных модулей, содержащихся в библиотеке, которая указана командой для него, используется дополнительный аргумент в последовательности из запятой и имени файла для записи такого перечня.