Table of Contents
DEFAULT: Change the assembler defaults
ABSOLUTE: Defining Absolute Labels
EXTERN: Importing Symbols
GLOBAL: Exporting Symbols
COMMON: Defining Common Data Areas
CPU: Defining CPU Dependencies
NASM’s directives come in two types: user-level directives and primitive directives. Typically, each directive has a user-level form and a primitive form. In almost all cases, we recommend that users use the user-level forms of the directives, which are implemented as macros which call the primitive forms.
Primitive directives are enclosed in square brackets; user-level directives are not.
In addition to the universal directives described in this chapter, each object file format can optionally supply extra directives in order to control particular features of that file format. These format-specific directives are documented along with the formats that implement them, in Part IV.
In most cases, you should not need to use
formats, which are designed for use in 32-bit operating systems, all cause Yasm to select
32-bit mode by default. The
win64 object formats, which
are designed for use in 64-bit operating systems, both cause Yasm to select 64-bit mode
by default. The
xdf object format allows you to specify each
segment you define as
USE64, and Yasm will set its
operating mode accordingly, so the use of the
is once again unnecessary.
The most likely reason for using the
BITS directive is to
write 32-bit or 64-bit code in a flat binary file; this is because the
bin object format defaults to 16-bit mode in anticipation of it being
used most frequently to write DOS
.COM programs, DOS
.SYS device drivers and boot loader software.
You do not need to specify
BITS 32 merely in order to use 32-bit instructions in a 16-bit DOS
program; if you do, the assembler will generate incorrect code because it will be writing
code targeted at a 32-bit platform, to be run on a 16-bit one. However, it is necessary to specify
to use 64-bit instructions and registers; this is done to allow use of those instruction
and register names in 32-bit or 16-bit programs, although such use will generate a
When Yasm is in
BITS 16 mode, instructions which use
32-bit data are prefixed with an 0x66 byte, and those referring to 32-bit addresses have
an 0x67 prefix. In
BITS 32 mode, the reverse is true: 32-bit
instructions require no prefixes, whereas instructions using 16-bit data need an 0x66 and
those working in 16-bit addresses need an 0x67.
When Yasm is in
BITS 64 mode, 32-bit instructions usually
require no prefixes, and most uses of 64-bit registers or data size requires a REX
prefix. Yasm automatically inserts REX prefixes where necessary. There are also 8 more
general and SSE registers, and 16-bit addressing is no longer supported. The default
address size is 64 bits; 32-bit addressing can be selected with the 0x67 prefix. The
default operand size is still 32 bits, however, and the 0x66 prefix selects 16-bit
operand size. The REX prefix is used both to select 64-bit operand size, and to access
the new registers. A few instructions have a default 64-bit operand size.
When the REX prefix is used, the processor does not know how to address the
DH (high 8-bit legacy) registers.
Instead, it is possible to access the the low 8-bits of the
DI registers as
DIL, respectively; but only when the REX prefix is used.
BITS directive has an exactly equivalent primitive
[BITS 32], and
[BITS 64]. The user-level form is a macro which has no
function other than to call the primitive form.