Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Флоренсов А.Н. УП Системное программное обеспечение.docx
Скачиваний:
46
Добавлен:
28.06.2021
Размер:
148.95 Кб
Скачать

6. Библиотеки объектных модулей

6.1. Использование библиотек объектных модулей в Linux

Когда объектных модулей, необходимых для компоновки программы, оказывается много, программисту становится неудобным перечислять их все при вызове компоновщика. Ситуация становится почти катастрофической, когда таких модулей многие десятки и даже сотни.

Выход был найден с помощью специализированных наборов объектных модулей, хранимых как отдельные файлы и называемых обычно библиотеками объектных модулей. В ОС Unix для аналогичных целей вначале использовался еще термин архив объектных модулей. Применение библиотек требует служебных утилит обслуживания, называемых обычно библиотекарями или архиваторами (последний термин характерен для Unix и, как уже объяснялось, несколько устарел).

Утилита обслуживания библиотек в Unix называется ar, и ее вызовы имеют в упрощенной форме общий вид

ar опции модификаторы имя_библиотеки объектные_файлы

где компонент объектные_файлы представляет собой перечисление имен файлов, разделяемых пробелами. Заметим, что данная утилита может применяться для сохранения в виде компактного набора не только объектных файлов, но и любых других файлов, но именно библиотеки объектных файлов являются мощным вспомогательным средством при разработке сложных программ.

Основными опциями данной утилиты, которые мы рассмотрим, являются опции -r, -d, -m, -t. Первая из них задает добавление нового объектного файла или файлов к библиотеке, вторая опция задает удаление указанных в перечне файлов из библиотеки, третья опция задает перемещение указанных в перечне файлов из библиотеки в текущий каталог, а опция -t приказывает выдать на стандартный вывод перечень файлов, содержащихся в библиотеке. Модификаторы призваны повысить эффективность использования и построения библиотек и записываются непосредственно за опцией. Модификатор, задаваемый буквой 'c', предназначен для указания, что библиотеку нужно создать. Стандартное расширение имени библиотек объектных модулей в Unix содержит единственную букву 'a' (строчную латинскую букву).

Следующий пример демонстрирует использование библиотеки объектных модулей. Сами модули формируются из исходных файлов с именами stwrite, stread, stexit, содержащих, соответственно, процедуры stdread, stdwrite, stdexit, и приведены в листингах 6.1.1, 6.1.2 и 6.1.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

Листинг 6.1.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

Листинг 6.1.2. Процедура stdwrite в файле stwrite.asm для библиотеки Linux

GLOBAL stdexit

SEGMENT.text

stdexit: mov eax,1

int 80h ; function=exit

ret

Листинг 6.1.3. Процедура stdexit в файле stexit.asm для библиотеки Linux

Формирование объектных файлов проще всего выполнить с помощью командного файла, имеющего для дальнейшего использования имя nasmc, содержимое которого приведено в листинге 6.1.4.

nasm –f elf$1.asm –l $1.lst

Листинг 6.1.4.Командный файл nasmc для раздельной трансляции

Далее с помощью командного вызова

ar –rcmyliba.astwrite.o stread.o stexit.o

нужно построить библиотеку с именем myliba.a. Использование библиотеки предполагает программа, приведенная в листинге 6.1.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 – адрес области для данных и ее длина

; число прочитанных байтов в регистре EAX

mov [len],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

Листинг 6.1.5. Программа prim5e.asm использования собственной библиотеки

Изготовление исполняемой программы из исходного текста в листинге 6.1.5 может осуществляться двумя командными вызовами, приведенными в следующих строках:

./nasmc prim5e

ld –o prime.exe prim5e.o myliba.a

Процесс изготовления исполняемой программы примера можно автоматизировать, применяя командный файл, текст которого дан в листинге 6.1.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

Листинг 6.1.6. Файл komfil построения и использования библиотеки

Заметим, что имена процедур в объектных модулях библиотеки никак не связаны (кроме возможных ассоциаций разработчика) с именами соответствующих объектных файлов. Более того, один библиотечный файл может содержать множество процедур и, в общем случае, любых внешних имен, используемых в дальнейшем из этой библиотеки. Установление связей между компонентами будущей исполняемой программы в процессе компоновки осуществляется исключительно по внешним именам в модулях, занесенных в библиотеку, а имена объектных модулей существенны только для приказов вставки или удаления объектных модулей в (из) библиотеки. В частности, процедуры stdread, stdwrite, stdexit целесообразно поместить в один исходный файл и, как следствие, в один объектный файл. В общем случае разнесение процедур по различным объектным модулям приводит к тому, что к машинным кодам компонуемой программы подключаются машинные коды только тех объектных модулей библиотеки, которые действительно необходимы, а остальные не подключаются.

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