Псевдо-инструкции не являются реальными
инструкциями х86 процессора, но все равно
помещаются в поле инструкций, т.к. это наиболее
подходящее место для них. Текущими псевдо-инструкциями
являются DB, DW, DD, DQ, DT, DDQ и DO, их копии для работы с
неинициализированной памятью RESB, RESW, RESD, RESQ, REST, RESDDQ и RESO, команды INCBIN, EQU и префикс TIMES.
DB, DW, DD, DQ, DT, DDQ и DO
используются для объявления инициализированных
данных в выходном файле. Они могут
использоваться достаточно многими способами:
db 0x55 ; просто байт 0x55
db 0x55,0x56,0x57 ; последовательно 3 байта
db 'a',0x55 ; символьная константа
db 'hello',13,10,'$' ; это строковая константа
dw 0x1234 ; 0x34 0x12
dw 'a' ; 0x41 0x00 (это просто число)
dw 'ab' ; 0x41 0x42 (символьная константа)
dw 'abc' ; 0x41 0x42 0x43 0x00 (строка)
dd 0x12345678 ; 0x78 0x56 0x34 0x12
dq 0x1122334455667788 ;0x88 0x77 0x66 0x55 0x44 0x33 0x22 0x11
ddq 0x112233445566778899aabbccddeeff00
; 0x00 0xff 0xee 0xdd 0xcc 0xbb 0xaa 0x99
; 0x88 0x77 0x66 0x55 0x44 0x33 0x22 0x11
do 0x112233445566778899aabbccddeeff00 ;то же самое как предыдущий
dd 1.234567e20 ; константа с плавающей точкой
dq 1.234567e20 ; двойной точности
dt 1.234567e20 ; расширенной точности
DT не допускает в качестве операндов
числовые
константы, а DDQ - констант с плавающей запятой.
Любой размер больше чем DD не допускает строк
в качестве операндов.
RESB, RESW, RESD, RESQ, REST, RESDQ и RESO разработаны для
использования в BSS-секции модуля: они объявляют
неинициализированное
пространство для хранения данных. Каждая
принимает один операнд, являющийся числом
резервируемых байт, слов, двойных слов и т.д. NASM
не поддерживает синтаксис резервирования
неинициализированного пространства,
реализованный в MASM/TASM, где можно делать DW ? или подобные вещи: это заменено
полностью. Операнд псевдо-инструкций класса RESB является критическим выражением:
см. Раздел 2.8.
Например:
buffer: resb 64 ; резервирование 64 байт wordvar: resw 1 ; резервирование слова realarray resq 10 ; массив из 10 чисел с плавающей точкой
INCBIN
дословно включает бинарный файл в выходной файл.
Это может быть полезно (например) для включения картинок и музыки
непосредственно в исполняемый файл игрушки.
Однако, это рекомендуется делать только для
_небольших_ порции данных. Эта псевдо-инструкция
может быть вызвана тремя разными способами:
incbin "file.dat" ; включение файла целиком
incbin "file.dat",1024 ; пропуск первых 1024 байт
incbin "file.dat",1024,512 ; пропуск первых 1024 и
; включение следующих 512 байт
EQU определяет символ для указанного
константного значения: если используется EQU, в этой строке кода должна
присутствовать метка. Смысл `EQU`— связать имя
метки со значением ее (только) операнда. Данное
определение абсолютно и не может быть позднее
изменено. Например,
message db 'Привет, фуфел' msglen equ $-message
определяет msglen как константу 13.
msglen не может быть позднее
переопределено. Это не определение препроцессора: значение
msglen обрабатывается здесь только один раз при помощи
значения $ (что такое $ – см. Раздел 2.6) в месте определения,
вместо того, чтобы обрабатыватся везде, где на
это ссылаются, при помощи значения $ в месте ссылки. Имейте в виду, что
операнд EQU также является критическим
выражением (Раздел 2.8).
Префикс TIMES заставляет инструкцию
ассемблироваться несколько раз. Данная
псевдо-инструкция отчасти представляет
NASM-эквивалент синтаксиса DUP,
поддерживающегося MASM-совместимыми
ассемблерами. Вы можете написать, например
zerobuf: times 64 db 0
или что-то подобное; однако TIMES
более разносторонняя инструкция. Аргумент TIMES — не просто числовая константа,
а числовое выражение,
поэтому вы можете писать следующие вещи:
buffer: db 'Привет, фуфел'
times 64-$+buffer db ' '
При этом будет резервироваться строго
определенное пространство, чтобы сделать полную
длину buffer до 64 байт. Наконец, TIMES может использоваться в обычных
инструкциях, так что вы можете писать
тривиальные развернутые циклы:
times 100 movsb
Заметим, что нет никакой принципиальной
разницы между times 100 resb 1 и resb 100 за исключением того, что
последняя инструкция будет обрабатываться
примерно в 100 раз быстрее из-за внутренней
структуры ассемблера.
Операнд псевдо-инструкции TIMES,
подобно EQU, RESB и
ее друзьям, является критическим выражением (Раздел 2.8).
Имейте также в виду, что TIMES не
применима в макросах: причиной служит то, что TIMES обрабатывается после макро-фазы,
позволяющей аргументу TIMES
содержать выражение, подобное 64-$+buffer. Для повторения более одной
строки кода или в сложных макросах используйте
директиву препроцессора %rep.