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

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

Переход к сложным разработкам даже еще в немногопрограммных ОС потребовал разбиения программ на модули. Разработка программ из многих модулей для Windows на основе изложенного выше материала не вызывает никаких новых сложностей, поскольку компоновщик link.exe может использовать в строке вызова не один, а сколько угодно отдельных объектных файлов. Для базового примера можно упростить ближайшее применение функций стандартного ввода-вывода, построив отдельные программы и разместив их в отдельных исходных файлах. Введем в использование подпрограммы writestd, readstd, exitproc (листинги 6.2.1, 6.2.2, 6.2.3).

writestd: ; аргументы в регистрах: регистр EBX — адрес выводимых данных, ECX – их длина

push dword STD_OUTPUT_HANDLE

call _GetStdHandle@4

mov [hstdout],eax

;--- WriteFile(hstdout, prmpt, actlen, &actlen, NULL)

push dword 0

push dword actlen ; address of actual byte number

push ecx ; number of bytes (value !)

push ebx ; address of txt

push dword [hstdout]; N handle=hstdout

call _WriteFile@20

mov eax, [actlen]

ret

Листинг 6.2.1. Программа процедуры writestd в файле writestd.pasm

readstd: ; аргументы в регистрах: регистр EBX – адрес вводимых данных, ECX – ограничение на длину ввода

push dword STD_INPUT_HANDLE

call _GetStdHandle@4

mov [hstdin],eax

;--- ReadFile(hstdin, buf, 80, &actlen, NULL)

push dword 0

push dword actlen

push ecx ; number of bytes

push ebx; address of txt

push dword [hstdin] ; N handle=hstdout

call _ReadFile@20

mov eax, [actlen]

ret

Листинг 6.2.2. Программа процедуры readstd в файле readstd.pasm

exitproc: ; параметр кода ошибки в регистре ECX

push ecx

call _ExitProcess@4

ret

Листинг 6.2.3. Программа процедуры exitproc в файле exitproc.pasm

Эти процедуры можно включить в общий с главной частью программ командный текст, обеспечить описание данных с именами в области данных и главную часть построить в виде файла prog2.asm, приведенного в листинге 6.2.4.

GLOBAL _start

EXTERN _GetStdHandle@4, _WriteFile@20, _ExitProcess@4

EXTERN _ReadFile@20

segment .text

_start: mov ebx, prmpt

mov ecx, 20

call writestd

mov ebx, buf

mov ecx, 80

call readstd

mov byte [buf+1],'!'

mov ebx, buf

mov ecx, eax

call writestd

mov ecx, 0

call exitproc

%include “writestd.pasm”

%include “readstd.pasm”

%include “exitproc.pasm”

segment .data

buf times 80 db 0

prmpt db 'Input text, please: '

hstdin dd 0

hstdout dd 0

actlen dd 0

STD_INPUT_HANDLE equ –10

STD_OUTPUT_HANDLE equ –11

Листинг 6.2.4. Программа prog2.asm

Приведенные изменения позволяют отстраниться от деталей построения процедур writestd, readstd, exitstd, но желательно, чтобы в дальнейшем все эти детали просто не попадались на глаза при написании других программ, использующих эти процедуры. Для этого указанные процедуры целесообразно вынести в отдельные файлы, а далее применять только их объектные результаты – файлы которые назовем хотя бы stdwr.obj, stdrd.obj, stdex.obj.

С этой целью построим файлы stdwre.asm, stdrd.asm, stdex.asm, приведенные на следующих листингах 6.2.5, 6.2.6 и 6.2.7:

GLOBAL writestd

EXTERN _GetStdHandle@4, _WriteFile@20

segment .text

%include “writestd.pasm” ; вставка текста из листинга 6.2.1

segment .data

hstdout dd 0

actlen dd 0

STD_OUTPUT_HANDLE equ -11

Листинг 6.2.5. Программа stdwr.asm

GLOBAL readstd

EXTERN _GetStdHandle@4, _ReadFile@20

segment .text

%include “readstd.pasm” ; вставка текста из листинга 6.2.2

segment .data

hstdin dd 0

actlen dd 0

STD_INPUT_HANDLE equ –10

Листинг 6.2.6. Программа stdrd.asm

GLOBAL exitproc

EXTERN _ExitProcess@4

segment .text

%include “exitproc.pasm” ; вставка текста из листинга 6.2.3

Листинг 6.2.7. Листинг программы stdex.asm

Заметим, что все необходимое для изолированной трансляции последних файлов включено в них (области данных, данные hstdin, hstdout, actlen, нужные для содержания директив extern, и именованные константы).

Теперь, выполнив команды

nasm –fwin32 stdwr.asm

nasm –fwin32 stdrd.asm

nasm –fwin32 stdex.asm

получаем объектные файлы stdwr.obj, stdrd.obj, stdex.obj.

Главная программа, которую назовем prog3.asm, должна строиться с указанием доступа к другим модулям, используя соответствующие директивы extern (листинг 6.2.8).

GLOBAL _start

EXTERN writestd, readstd, exitproc

segment .text

_start: mov ebx, prmpt

mov ecx, 20

call writestd

mov ebx, buf

mov ecx, 80

call readstd

mov byte [buf+1],'!'

mov ebx, buf

mov ecx, eax

call writestd

mov ecx, 0

call exitproc

segment .data

buf times 80 db 0

prmpt db 'Input text, please: '

Листинг 6.2.8. Программа prog3.asm использования writestd, readstd, exitproc

Осуществив компиляцию файла prog3.asm и выполнив вызов компоновщика в виде

link /ENTRY:start /SUBSYSTEM:CONSOLE prog3.obj stdwr.obj stdrd.obj stdex.obj kernel32.lib

получим исполняемый файл prog2.exe, который решает поставленную задачу действий над информацией.

Непосредственно видно, что перечисление многих файлов в строке вызова link неудобно и утомительно, хочется сделать что-то покомпактней. Для решения такой задачи были придуманы библиотеки (наборы) объектных модулей.

В Microsoft для манипуляции с библиотеками объектных модулей служит утилита lib.exe, которая также требует доступного при выполнении файла mspdbномер0.DLL.

Для создания своей библиотеки объектных модулей используем вызов

lib.exe /out:mylib.libstdwr.obj stdrd.obj stdex.obj

В результате должна сформироваться библиотека mylib.lib.

Для ее использования с исходным текстом программы prog3.asm нужны командные вызовы

nasm –f win32 prog3.asm –o %1.obj –l %1.lst

link /ENTRY:start /SUBSYSTEM:CONSOLEprog3.obj mylib.lib kernel32.lib

Утилита библиотекаря Microsoft дает множество дополнительных возможностей, краткую справку по которым можно получить, вызвав ее без каких-либо параметров. Как уже показывалось, параметр /out служит для задания имени результирующего объекта – библиотеки объектных модулей. Заметим, что сложившийся в разработках Microsoft стиль параметров утилит требует (для командного режима) задания опций не с предшествующим дефисом, как в Unix и Linux, а с помощью символов слэш – «косая черта», использующегося в качестве синтаксического признака опции. Кроме того, опять же в отличие от классического стиля, значение опции отделяет от ключевого слова опции вспомогательный символ «двоеточие» (а не пробел).

Для выдачи пользователю информации о составе библиотеки, а именно того, какие объектные файлы входят в ее состав, применяется опция /LIST, которая при необходимости включает дополнительную информаци. об имени файла, где следует сохранить информацию о составе библиотеки (опция в виде /LIST:имя_файла).