2.2. Псевдо-инструкции

Псевдо-инструкции не являются реальными инструкциями х86 процессора, но все равно помещаются в поле инструкций, т.к. это наиболее подходящее место для них. Текущими псевдо-инструкциями являются DB, DW, DD, DQ, DT, DDQ и DO, их копии для работы с неинициализированной памятью RESB, RESW, RESD, RESQ, REST, RESDDQ и RESO, команды INCBIN, EQU и префикс TIMES.

2.2.1. DB и ее друзья: Объявление инициализированных данных

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 не допускает строк в качестве операндов.

2.2.2. RESB и ее друзья: Объявление неинициализированных данных

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 чисел с плавающей точкой

2.2.3. INCBIN: Включение внешних бинарных файлов

INCBIN дословно включает бинарный файл в выходной файл. Это может быть полезно (например) для включения картинок и музыки непосредственно в исполняемый файл игрушки. Однако, это рекомендуется делать только для _небольших_ порции данных. Эта псевдо-инструкция может быть вызвана тремя разными способами:

        incbin "file.dat"        ; включение файла целиком
        incbin "file.dat",1024   ; пропуск первых 1024 байт
        incbin "file.dat",1024,512 ; пропуск первых 1024 и
                                 ; включение следующих 512 байт

2.2.4. EQU: Определение констант

EQU определяет символ для указанного константного значения: если используется EQU, в этой строке кода должна присутствовать метка. Смысл `EQU`— связать имя метки со значением ее (только) операнда. Данное определение абсолютно и не может быть позднее изменено. Например,

message db 'Привет, фуфел'
msglen  equ $-message

определяет msglen как константу 13. msglen не может быть позднее переопределено. Это не определение препроцессора: значение msglen обрабатывается здесь только один раз при помощи значения $ (что такое $ – см. Раздел 2.6) в месте определения, вместо того, чтобы обрабатыватся везде, где на это ссылаются, при помощи значения $ в месте ссылки. Имейте в виду, что операнд EQU также является критическим выражением (Раздел 2.8).

2.2.5. TIMES: Повторение инструкций или данных

Префикс 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.