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