При сборке программы, если она использует множество объектных файлов, то код всех этих файлов добавляется его в выходной исполняемый файл. То есть есть объектный файл содержит 100 процедур, но в программе используется только одна из них, то все равно код всех 100 процедур будет добавляться в итоговый исполняемый файл. В качестве варианта можно создать определить каждую процедуру в отдельном файле и по отдельности скомпилировать. В итоге для 100 процедур получится 100 объектных файлов. И эти файлы при необходимости подключать при сборке программы. Однако управлять таким количеством файлов не очень удобно. И MASM предоставляет другое более удобное решение в виде библиотек.
Библиотека по сути представляет хранилище объектых файлов. Обычно библиотека представляет файл с расширением .lib, который можно использовать при компоновке программы также, как и обычные объектные файлы. Когда компоновщик обрабатывает файл библиотеки, он выберет единственный объектный файл с процедурой, которую использует программа, и включит только этот объектный файл в окончательный исполняемый файл. Как правило, это намного эффективнее, чем компоновка одного объектного файла со 100 процедурами.
Для компиляции библиотеки в MASM применяется программа Microsoft Library Manager - lib.exe, которому передается команда
lib /out:имя_файла.lib список_объектных_файлов
Допустим, мы хотим создать библиотеку для работы с 128-разрядными числами. Пусть у нас будет файл sum128.asm, в котором определена процедура сложения двух 128-разрядных чисел:
.code ; в RAX:RDX -первое число ; в RBX:RCX - второе число ; через RAX:RDX возвращается результат sum128 proc add rax, rbx adc rdx, rcx ret sum128 endp end
Здесь через регистры RAX и RBX передаются младшие 64 бита двух чисел. После их сложения складываются старшие 64 бита двух чисел, которые передаются через регистры RDX и RCX, плюс знак переноса. Результат сложения - младшие 64 бит в регистре RAX, а старшие 64 бит в регистре RDX.
Также определим файл sub128.asm, который будет содержать процедуру для вычитания 128-разрядных чисел:
.code ; в RAX:RDX -первое число ; в RBX:RCX - второе число ; через RAX:RDX возвращается результат sub128 proc sub rax, rbx sbb rdx, rcx ret sub128 endp end
Для создания библиотеки перейдем в консоли к папке с файлами и выполним команду:
ml64 /c sum128.asm sub128.asm
Эта команда скомпилирует объектные файлы sum128.obj и sub128.obj.
Далее сформируем из этих файлов библиотеку и для этого выполним команду:
lib /out:math128.lib sum128.obj sub128.obj
После выполнения этой команды в текущей папке появится файл math128.lib - собственной файл библиотеки.
Теперь подключим выше созданную библиотеку. Допустим, главный файл программы называется main.asm, и он использует процедуру sum128
для сложения двух 128-разрядных чисел:
externdef sum128:proc ; подключаем внешнюю процедуру sum128 .data num1 qword 0ffffffffffffffffh, ; младшие 64 байт 00000000000000002h ; старшие 64 байт num2 qword 00000000000000007h, ; младшие 64 байт 0h ; старшие 64 байт .code main proc mov rax, num1 mov rdx, num1[64] mov rbx, num2 mov rcx, num2[64] call sum128 ret main endp end
Код в данном файле использует внешнюю процедуру sum128 для сложения двух 128-разрядных чисел num1 и num2. Для компиляции и сборки этой программы с использованием библиотеки выполним следующую команду:
ml64 main.asm math128.lib /link /entry:main
После этого будет сгенерирован файл main.exe, который будет использовать функционал из объектного файла sum128.obj.
Директива includelib позволяет подключить функционал библиотеки непосредственно в файле кода на ассемблере. Например, изменим файл main.asm следующим образом:
includelib math128.lib ; подключаем библиотеку math128.lib externdef sum128:proc ; подключаем внешнюю процедуру sum128 .data num1 qword 0ffffffffffffffffh, ; младшие 64 байт 00000000000000002h ; старшие 64 байт num2 qword 00000000000000006h, ; младшие 64 байт 0h ; старшие 64 байт .code main proc mov rax, num1 mov rdx, num1[64] mov rbx, num2 mov rcx, num2[64] call sum128 ret main endp end
Первой строкой подключается библиотека math128.lib. В этом случае при компиляции и компоновке программы можно не указывать библиотеку:
ml64 main.asm /link /entry:main