Псевдо-инструкции не являются реальными
инструкциями х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.