Библиотеки

Последнее обновление: 03.07.2023

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

Директива 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
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850