Pseudo-instructions are things which, though not real x86 machine instructions, are
used in the instruction field anyway because that’s the most convenient place to put
them. The current pseudo-instructions are DB, DW, DD, DQ,
DT, DDQ, DO, their uninitialized counterparts RESB,
RESW, RESD, RESQ, REST, RESDDQ, and RESO, the INCBIN command, the EQU command, and the
TIMES prefix.
DB, DW, DD, DQ, DT,
DDQ, and DO are used to declare initialized data in
the output file. They can be invoked in a wide range of ways:
db 0x55 ; just the byte 0x55
db 0x55,0x56,0x57 ; three bytes in succession
db 'a',0x55 ; character constants are OK
db 'hello',13,10,'$' ; so are string constants
dw 0x1234 ; 0x34 0x12
dw 'a' ; 0x41 0x00 (it's just a number)
dw 'ab' ; 0x41 0x42 (character constant)
dw 'abc' ; 0x41 0x42 0x43 0x00 (string)
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 ; same as previous
dd 1.234567e20 ; floating-point constant
dq 1.234567e20 ; double-precision float
dt 1.234567e20 ; extended-precision float
DT does not accept numeric constants as operands, and DDQ does not accept float
constants as operands. Any size larger than DD does not accept strings as
operands.
RESB, RESW, RESD,
RESQ, REST, RESDQ, and RESO are
designed to be used in the BSS section of a module: they declare uninitialised storage space. Each takes a single operand,
which is the number of bytes, words, doublewords or whatever to reserve. NASM does not
support the MASM/TASM syntax of reserving uninitialised space by writing DW ? or similar things: this is what it does instead. The operand to a
RESB-type pseudo-instruction is a critical expression: see Section 3.8.
For example:
buffer: resb 64 ; reserve 64 bytes wordvar: resw 1 ; reserve a word realarray resq 10 ; array of ten reals
INCBIN includes a
binary file verbatim into the output file. This can be handy for (for example) including
graphics and sound data directly into a game
executable file. However, it is recommended to use this for only small pieces of data. It can be called in one of these three
ways:
incbin "file.dat" ; include the whole file
incbin "file.dat",1024 ; skip the first 1024 bytes
incbin "file.dat",1024,512 ; skip the first 1024, and
; actually include at most 512
EQU defines a symbol to a given constant value: when EQU is used, the source line must contain a label. The action of
EQU is to define the given label name to the value of its
(only) operand. This definition is absolute, and cannot change later. So, for
example,
message db 'hello, world' msglen equ $-message
defines msglen to be the constant 12. msglen may not then be redefined later. This is not a preprocessor definition either: the
value of msglen is evaluated once, using the value of $ (see
Section 3.6 for an
explanation of $) at the point of definition, rather than
being evaluated wherever it is referenced and using the value of $ at the point of reference. Note that the operand to an EQU is also a critical expression (Section 3.8).
The TIMES prefix causes
the instruction to be assembled multiple times. This is partly present as NASM’s
equivalent of the DUP syntax supported by MASM-compatible
assemblers, in that you can code
zerobuf: times 64 db 0
or similar things; but TIMES is more versatile than that.
The argument to TIMES is not just a numeric constant, but a
numeric expression, so you can do things like
buffer: db 'hello, world'
times 64-$+buffer db ' '
which will store exactly enough spaces to make the total length of buffer up to 64. Finally, TIMES can be
applied to ordinary instructions, so you can code trivial unrolled loops in it:
times 100 movsb
Note that there is no effective difference between times 100
resb 1 and resb 100, except that the latter will be
assembled about 100 times faster due to the internal structure of the assembler.
The operand to TIMES, like that of EQU and those of RESB and friends, is a
critical expression (Section 3.8).
Note also that TIMES can’t be applied to macros: the reason for this is that
TIMES is processed after the macro phase, which allows the
argument to TIMES to contain expressions such as
64-$+buffer as above. To repeat more than one line of code,
or a complex macro, use the preprocessor %rep directive.