Next Chapter | Previous Chapter | Contents | Index
NASM is a portable assembler, designed to be able to compile on any ANSI
C-supporting platform and produce output to run on a variety of Intel x86
operating systems. For this reason, it has a large number of available
output formats, selected using the option on
the NASM command line. Each of these formats, along with its extensions to
the base NASM syntax, is detailed in this chapter.
As stated in section 2.1.1,
NASM chooses a default name for your output file based on the input file
name and the chosen output format. This will be generated by removing the
extension (, , or
whatever you like to use) from the input file name, and substituting an
extension defined by the output format. The extensions are given with each
format below.
bin : Flat-Form Binary OutputThe format does not produce object files:
it generates nothing in the output file except the code you wrote. Such
`pure binary' files are used by MS-DOS:
executables and device drivers are pure
binary files. Pure binary output is also useful for operating system and
boot loader development.
The format supports multiple section
names. For details of how nasm handles sections in the
format, see section
6.1.3.
Using the format puts NASM by default into
16-bit mode (see section 5.1). In
order to use to write 32-bit code such as an
OS kernel, you need to explicitly issue the
directive.
has no default output file name extension:
instead, it leaves your file name as it is once the original extension has
been removed. Thus, the default is for NASM to assemble
into a binary file called
.
ORG : Binary File Program OriginThe format provides an additional
directive to the list given in chapter 5:
. The function of the
directive is to specify the origin address
which NASM will assume the program begins at when it is loaded into memory.
For example, the following code will generate the longword
:
org 0x100
dd label
label:
Unlike the directive provided by
MASM-compatible assemblers, which allows you to jump around in the object
file and overwrite code you have already generated, NASM's
does exactly what the directive says:
origin. Its sole function is to specify one offset which is added
to all internal address references within the section; it does not permit
any of the trickery that MASM's version does. See
section 10.1.3 for further
comments.
bin Extensions to the SECTION DirectiveThe output format extends the
(or )
directive to allow you to specify the alignment requirements of segments.
This is done by appending the qualifier to
the end of the section-definition line. For example,
section .data align=16
switches to the section and also
specifies that it must be aligned on a 16-byte boundary.
The parameter to specifies how many low
bits of the section start address must be forced to zero. The alignment
value given may be any power of two.
Multisection support for the BIN format.The format allows the use of multiple
sections, of arbitrary names, besides the "known"
, , and
names.
progbits or
nobits . Default is
progbits (except .bss ,
which defaults to nobits , of course).
align= , or at an arbitrary
byte-granular position with start= .
vstart= .
follows= <section>
or
vfollows= <section>
as an alternative to specifying an explicit start address.
org ,
start , vstart , and
align= are critical expressions. See
section 3.8. E.g.
align=(1 << ALIGN_SHIFT) -
ALIGN_SHIFT must be defined before it is used
here.
SECTION directive is directed by default into the
.text section.
ORG statement is not given,
ORG 0 is used by default.
.bss section will be placed after the
last progbits section, unless
start= , vstart= ,
follows= , or vfollows=
has been specified.
section.<secname>.start for each section,
which may be used in your code.
Map files can be generated in format by
means of the option. Map types of
(default), ,
, , or
may be specified. Output may be directed
to (default),
, or a specified file. E.g.
. No "user form" exists,
the square brackets must be used.
obj : Microsoft OMF Object FilesThe file format (NASM calls it
rather than for
historical reasons) is the one produced by MASM and TASM, which is
typically fed to 16-bit DOS linkers to produce
files. It is also the format used by OS/2.
provides a default output file-name
extension of .
is not exclusively a 16-bit format,
though: NASM has full support for the 32-bit extensions to the format. In
particular, 32-bit format files are used by
Borland's Win32 compilers, instead of using Microsoft's newer
object file format.
The format does not define any special
segment names: you can call your segments anything you like. Typical names
for segments in format files are
, and
.
If your source file contains code before specifying an explicit
directive, then NASM will invent its own
segment called for you.
When you define a segment in an file, NASM
defines the segment name as a symbol as well, so that you can access the
segment address of the segment. So, for example:
segment data
dvar: dw 1234
segment code
function:
mov ax,data ; get segment address of data
mov ds,ax ; and move it into DS
inc word [dvar] ; now this reference will work
ret
The format also enables the use of the
and operators,
so that you can write code which does things like
extern foo
mov ax,seg foo ; get preferred segment of foo
mov ds,ax
mov ax,data ; a different segment
mov es,ax
mov ax,[ds:foo] ; this accesses `foo'
mov [es:foo wrt data],bx ; so does this
obj Extensions to the SEGMENT DirectiveThe output format extends the
(or )
directive to allow you to specify various properties of the segment you are
defining. This is done by appending extra qualifiers to the end of the
segment-definition line. For example,
segment code private align=16
defines the segment , but also declares it
to be a private segment, and requires that the portion of it described in
this code module must be aligned on a 16-byte boundary.
The available qualifiers are:
PRIVATE , PUBLIC ,
COMMON and STACK
specify the combination characteristics of the segment.
PRIVATE segments do not get combined with any
others by the linker; PUBLIC and
STACK segments get concatenated together at link
time; and COMMON segments all get overlaid on top
of each other rather than stuck end-to-end.
ALIGN is used, as shown above, to specify how
many low bits of the segment start address must be forced to zero. The
alignment value given may be any power of two from 1 to 4096; in reality,
the only values supported are 1, 2, 4, 16, 256 and 4096, so if 8 is
specified it will be rounded up to 16, and 32, 64 and 128 will all be
rounded up to 256, and so on. Note that alignment to 4096-byte boundaries
is a PharLap extension to the format and may not be supported by all
linkers.
CLASS can be used to specify the segment
class; this feature indicates to the linker that segments of the same class
should be placed near each other in the output file. The class name can be
any word, e.g. CLASS=CODE .
OVERLAY , like
CLASS , is specified with an arbitrary word as an
argument, and provides overlay information to an overlay-capable linker.
USE16 or
USE32 , which has the effect of recording the
choice in the object file and also ensuring that NASM's default assembly
mode when assembling in that segment is 16-bit or 32-bit respectively.
FLAT , which causes the default segment base for
anything in the segment to be the special group
FLAT , and also defines the group if it is not
already defined.
obj file format also allows segments to
be declared as having a pre-defined absolute segment address, although no
linkers are currently known to make sensible use of this feature;
nevertheless, NASM allows you to declare a segment such as
SEGMENT SCREEN ABSOLUTE=0xB800 if you need to.
The ABSOLUTE and ALIGN
keywords are mutually exclusive.
NASM's default segment attributes are ,
, no class, no overlay, and
.
GROUP : Defining Groups of SegmentsThe format also allows segments to be
grouped, so that a single segment register can be used to refer to all the
segments in a group. NASM therefore supplies the
directive, whereby you can code
segment data
; some data
segment bss
; some uninitialised data
group dgroup data bss
which will define a group called to
contain the segments and
. Like ,
causes the group name to be defined as a
symbol, so that you can refer to a variable
in the segment as
or as
, depending on which segment value
is currently in your segment register.
If you just refer to , however, and
is declared in a segment which is part of a
group, then NASM will default to giving you the offset of
from the beginning of the group, not
the segment. Therefore , also,
will return the group base rather than the segment base.
NASM will allow a segment to be part of more than one group, but will generate a warning if you do this. Variables declared in a segment which is part of more than one group will default to being relative to the first group that was defined to contain the segment.
A group does not have to contain any segments; you can still make
references to a group which does not contain
the variable you are referring to. OS/2, for example, defines the special
group with no segments in it.
UPPERCASE : Disabling Case Sensitivity in OutputAlthough NASM itself is case sensitive, some OMF linkers are not;
therefore it can be useful for NASM to output single-case object files. The
format-specific directive causes all
segment, group and symbol names that are written to the object file to be
forced to upper case just before being written. Within a source file, NASM
is still case-sensitive; but the object file can be written entirely in
upper case if desired.
is used alone on a line; it requires
no parameters.
IMPORT : Importing DLL SymbolsThe format-specific directive defines a
symbol to be imported from a DLL, for use if you are writing a DLL's import
library in NASM. You still need to declare the symbol as
as well as using the
directive.
The directive takes two required
parameters, separated by white space, which are (respectively) the name of
the symbol you wish to import and the name of the library you wish to
import it from. For example:
import WSAStartup wsock32.dll
A third optional parameter gives the name by which the symbol is known in the library you are importing it from, in case this is not the same as the name you wish the symbol to be known by to your code once you have imported it. For example:
import asyncsel wsock32.dll WSAAsyncSelect
EXPORT : Exporting DLL SymbolsThe format-specific directive defines a
global symbol to be exported as a DLL symbol, for use if you are writing a
DLL in NASM. You still need to declare the symbol as
as well as using the
directive.
takes one required parameter, which is
the name of the symbol you wish to export, as it was defined in your source
file. An optional second parameter (separated by white space from the
first) gives the external name of the symbol: the name by which
you wish the symbol to be known to programs using the DLL. If this name is
the same as the internal name, you may leave the second parameter off.
Further parameters can be given to define attributes of the exported symbol. These parameters, like the second, are separated by white space. If further parameters are given, the external name must also be specified, even if it is the same as the internal name. The available attributes are:
resident indicates that the exported name is
to be kept resident by the system loader. This is an optimisation for
frequently used symbols imported by name.
nodata indicates that the exported symbol is
a function which does not make use of any initialised data.
parm=NNN , where NNN
is an integer, sets the number of parameter words for the case in which the
symbol is a call gate between 32-bit and 16-bit segments.
For example:
export myfunc
export myfunc TheRealMoreFormalLookingFunctionName
export myfunc myfunc 1234 ; export by ordinal
export myfunc myfunc resident parm=23 nodata
..start : Defining the Program Entry Point linkers require exactly one of the object
files being linked to define the program entry point, where execution will
begin when the program is run. If the object file that defines the entry
point is assembled using NASM, you specify the entry point by declaring the
special symbol at the point where you
wish execution to begin.
obj Extensions to the EXTERN DirectiveIf you declare an external symbol with the directive
extern foo
then references such as will give
you the offset of from its preferred segment
base (as specified in whichever module is
actually defined in). So to access the contents of
you will usually need to do something like
mov ax,seg foo ; get preferred segment base
mov es,ax ; move it into ES
mov ax,[es:foo] ; and use offset `foo' from it
This is a little unwieldy, particularly if you know that an external is
going to be accessible from a given segment or group, say
. So if
already contained , you could simply code
mov ax,[foo wrt dgroup]
However, having to type this every time you want to access
can be a pain; so NASM allows you to declare
in the alternative form
extern foo:wrt dgroup
This form causes NASM to pretend that the preferred segment base of
is in fact ;
so the expression will now return
, and the expression
is equivalent to
.
This default- mechanism can be used to make
externals appear to be relative to any group or segment in your program. It
can also be applied to common variables: see
section 6.2.8.
obj Extensions to the COMMON DirectiveThe format allows common variables to be
either near or far; NASM allows you to specify which your variables should
be by the use of the syntax
common nearvar 2:near ; `nearvar' is a near common common farvar 10:far ; and `farvar' is far
Far common variables may be greater in size than 64Kb, and so the OMF specification says that they are declared as a number of elements of a given size. So a 10-byte far common variable could be declared as ten one-byte elements, five two-byte elements, two five-byte elements or one ten-byte element.
Some linkers require the element size, as
well as the variable size, to match when resolving common variables
declared in more than one module. Therefore NASM must allow you to specify
the element size on your far common variables. This is done by the
following syntax:
common c_5by2 10:far 5 ; two five-byte elements common c_2by5 10:far 2 ; five two-byte elements
If no element size is specified, the default is 1. Also, the
keyword is not required when an element size
is specified, since only far commons may have element sizes at all. So the
above declarations could equivalently be
common c_5by2 10:5 ; two five-byte elements common c_2by5 10:2 ; five two-byte elements
In addition to these extensions, the
directive in also supports
default- specification like
does (explained in
section 6.2.7). So you can also declare things
like
common foo 10:wrt dgroup common bar 16:far 2:wrt data common baz 24:wrt data:6
win32 : Microsoft Win32 Object FilesThe output format generates Microsoft
Win32 object files, suitable for passing to Microsoft linkers such as
Visual C++. Note that Borland Win32 compilers do not use this format, but
use instead (see
section 6.2).
provides a default output file-name
extension of .
Note that although Microsoft say that Win32 object files follow the
(Common Object File Format) standard, the
object files produced by Microsoft Win32 compilers are not compatible with
COFF linkers such as DJGPP's, and vice versa. This is due to a difference
of opinion over the precise semantics of PC-relative relocations. To
produce COFF files suitable for DJGPP, use NASM's
output format; conversely, the
format does not produce object files that
Win32 linkers can generate correct output from.
win32 Extensions to the SECTION DirectiveLike the format,
allows you to specify additional
information on the directive line, to
control the type and properties of sections you declare. Section types and
properties are generated automatically by NASM for the standard section
names , and
, but may still be overridden by these
qualifiers.
The available qualifiers are:
code , or equivalently
text , defines the section to be a code section.
This marks the section as readable and executable, but not writable, and
also indicates to the linker that the type of the section is code.
data and bss define
the section to be a data section, analogously to
code . Data sections are marked as readable and
writable, but not executable. data declares an
initialised data section, whereas bss declares an
uninitialised data section.
rdata declares an initialised data section
that is readable but not writable. Microsoft compilers use this section to
place constants in it.
info defines the section to be an
informational section, which is not included in the executable file by the
linker, but may (for example) pass information to the
obj Extensions to the SEGMENT DirectiveThe output format extends the
(or )
directive to allow you to specify various properties of the segment you are
defining. This is done by appending extra qualifiers to the end of the
segment-definition line. For example,
segment code private align=16
defines the segment , but also declares it
to be a private segment, and requires that the portion of it described in
this code module must be aligned on a 16-byte boundary.
The available qualifiers are:
PRIVATE , PUBLIC ,
COMMON and STACK
specify the combination characteristics of the segment.
PRIVATE segments do not get combined with any
others by the linker; PUBLIC and
STACK segments get concatenated together at link
time; and COMMON segments all get overlaid on top
of each other rather than stuck end-to-end.
ALIGN is used, as shown above, to specify how
many low bits of the segment start address must be forced to zero. The
alignment value given may be any power of two from 1 to 4096; in reality,
the only values supported are 1, 2, 4, 16, 256 and 4096, so if 8 is
specified it will be rounded up to 16, and 32, 64 and 128 will all be
rounded up to 256, and so on. Note that alignment to 4096-byte boundaries
is a PharLap extension to the format and may not be supported by all
linkers.
CLASS can be used to specify the segment
class; this feature indicates to the linker that segments of the same class
should be placed near each other in the output file. The class name can be
any word, e.g. CLASS=CODE .
OVERLAY , like
CLASS , is specified with an arbitrary word as an
argument, and provides overlay information to an overlay-capable linker.
USE16 or
USE32 , which has the effect of recording the
choice in the object file and also ensuring that NASM's default assembly
mode when assembling in that segment is 16-bit or 32-bit respectively.
FLAT , which causes the default segment base for
anything in the segment to be the special group
FLAT , and also defines the group if it is not
already defined.
obj file format also allows segments to
be declared as having a pre-defined absolute segment address, although no
linkers are currently known to make sensible use of this feature;
nevertheless, NASM allows you to declare a segment such as
SEGMENT SCREEN ABSOLUTE=0xB800 if you need to.
The ABSOLUTE and ALIGN
keywords are mutually exclusive.
NASM's default segment attributes are ,
, no class, no overlay, and
.
GROUP : Defining Groups of SegmentsThe format also allows segments to be
grouped, so that a single segment register can be used to refer to all the
segments in a group. NASM therefore supplies the
directive, whereby you can code
segment data
; some data
segment bss
; some uninitialised data
group dgroup data bss
which will define a group called to
contain the segments and
. Like ,
causes the group name to be defined as a
symbol, so that you can refer to a variable
in the segment as
or as
, depending on which segment value
is currently in your segment register.
If you just refer to , however, and
is declared in a segment which is part of a
group, then NASM will default to giving you the offset of
from the beginning of the group, not
the segment. Therefore , also,
will return the group base rather than the segment base.
NASM will allow a segment to be part of more than one group, but will generate a warning if you do this. Variables declared in a segment which is part of more than one group will default to being relative to the first group that was defined to contain the segment.
A group does not have to contain any segments; you can still make
references to a group which does not contain
the variable you are referring to. OS/2, for example, defines the special
group with no segments in it.
UPPERCASE : Disabling Case Sensitivity in OutputAlthough NASM itself is case sensitive, some OMF linkers are not;
therefore it can be useful for NASM to output single-case object files. The
format-specific directive causes all
segment, group and symbol names that are written to the object file to be
forced to upper case just before being written. Within a source file, NASM
is still case-sensitive; but the object file can be written entirely in
upper case if desired.
is used alone on a line; it requires
no parameters.
IMPORT : Importing DLL SymbolsThe format-specific directive defines a
symbol to be imported from a DLL, for use if you are writing a DLL's import
library in NASM. You still need to declare the symbol as
as well as using the
directive.
The directive takes two required
parameters, separated by white space, which are (respectively) the name of
the symbol you wish to import and the name of the library you wish to
import it from. For example:
import WSAStartup wsock32.dll
A third optional parameter gives the name by which the symbol is known in the library you are importing it from, in case this is not the same as the name you wish the symbol to be known by to your code once you have imported it. For example:
import asyncsel wsock32.dll WSAAsyncSelect
EXPORT : Exporting DLL SymbolsThe format-specific directive defines a
global symbol to be exported as a DLL symbol, for use if you are writing a
DLL in NASM. You still need to declare the symbol as
as well as using the
directive.
takes one required parameter, which is
the name of the symbol you wish to export, as it was defined in your source
file. An optional second parameter (separated by white space from the
first) gives the external name of the symbol: the name by which
you wish the symbol to be known to programs using the DLL. If this name is
the same as the internal name, you may leave the second parameter off.
Further parameters can be given to define attributes of the exported symbol. These parameters, like the second, are separated by white space. If further parameters are given, the external name must also be specified, even if it is the same as the internal name. The available attributes are:
resident indicates that the exported name is
to be kept resident by the system loader. This is an optimisation for
frequently used symbols imported by name.
nodata indicates that the exported symbol is
a function which does not make use of any initialised data.
parm=NNN , where NNN
is an integer, sets the number of parameter words for the case in which the
symbol is a call gate between 32-bit and 16-bit segments.
For example:
export myfunc
export myfunc TheRealMoreFormalLookingFunctionName
export myfunc myfunc 1234 ; export by ordinal
export myfunc myfunc resident parm=23 nodata
..start : Defining the Program Entry Point linkers require exactly one of the object
files being linked to define the program entry point, where execution will
begin when the program is run. If the object file that defines the entry
point is assembled using NASM, you specify the entry point by declaring the
special symbol at the point where you
wish execution to begin.
obj Extensions to the EXTERN DirectiveIf you declare an external symbol with the directive
extern foo
then references such as will give
you the offset of from its preferred segment
base (as specified in whichever module is
actually defined in). So to access the contents of
you will usually need to do something like
mov ax,seg foo ; get preferred segment base
mov es,ax ; move it into ES
mov ax,[es:foo] ; and use offset `foo' from it
This is a little unwieldy, particularly if you know that an external is
going to be accessible from a given segment or group, say
. So if
already contained , you could simply code
mov ax,[foo wrt dgroup]
However, having to type this every time you want to access
can be a pain; so NASM allows you to declare
in the alternative form
extern foo:wrt dgroup
This form causes NASM to pretend that the preferred segment base of
is in fact ;
so the expression will now return
, and the expression
is equivalent to
.
This default- mechanism can be used to make
externals appear to be relative to any group or segment in your program. It
can also be applied to common variables: see
section 6.2.8.
obj Extensions to the COMMON DirectiveThe format allows common variables to be
either near or far; NASM allows you to specify which your variables should
be by the use of the syntax
common nearvar 2:near ; `nearvar' is a near common common farvar 10:far ; and `farvar' is far
Far common variables may be greater in size than 64Kb, and so the OMF specification says that they are declared as a number of elements of a given size. So a 10-byte far common variable could be declared as ten one-byte elements, five two-byte elements, two five-byte elements or one ten-byte element.
Some linkers require the element size, as
well as the variable size, to match when resolving common variables
declared in more than one module. Therefore NASM must allow you to specify
the element size on your far common variables. This is done by the
following syntax:
common c_5by2 10:far 5 ; two five-byte elements common c_2by5 10:far 2 ; five two-byte elements
If no element size is specified, the default is 1. Also, the
keyword is not required when an element size
is specified, since only far commons may have element sizes at all. So the
above declarations could equivalently be
common c_5by2 10:5 ; two five-byte elements common c_2by5 10:2 ; five two-byte elements
In addition to these extensions, the
directive in also supports
default- specification like
does (explained in
section 6.2.7). So you can also declare things
like
common foo 10:wrt dgroup common bar 16:far 2:wrt data common baz 24:wrt data:6
win32 : Microsoft Win32 Object FilesThe output format generates Microsoft
Win32 object files, suitable for passing to Microsoft linkers such as
Visual C++. Note that Borland Win32 compilers do not use this format, but
use instead (see
section 6.2).
provides a default output file-name
extension of .
Note that although Microsoft say that Win32 object files follow the
(Common Object File Format) standard, the
object files produced by Microsoft Win32 compilers are not compatible with
COFF linkers such as DJGPP's, and vice versa. This is due to a difference
of opinion over the precise semantics of PC-relative relocations. To
produce COFF files suitable for DJGPP, use NASM's
output format; conversely, the
format does not produce object files that
Win32 linkers can generate correct output from.
win32 Extensions to the SECTION DirectiveLike the format,
allows you to specify additional
information on the directive line, to
control the type and properties of sections you declare. Section types and
properties are generated automatically by NASM for the standard section
names , and
, but may still be overridden by these
qualifiers.
The available qualifiers are:
code , or equivalently
text , defines the section to be a code section.
This marks the section as readable and executable, but not writable, and
also indicates to the linker that the type of the section is code.
data and bss define
the section to be a data section, analogously to
code . Data sections are marked as readable and
writable, but not executable. data declares an
initialised data section, whereas bss declares an
uninitialised data section.
rdata declares an initialised data section
that is readable but not writable. Microsoft compilers use this section to
place constants in it.
info defines the section to be an
informational section, which is not included in the executable file by the
linker, but may (for example) pass information to the
obj Extensions to the SEGMENT DirectiveThe output format extends the
(or )
directive to allow you to specify various properties of the segment you are
defining. This is done by appending extra qualifiers to the end of the
segment-definition line. For example,
segment code private align=16
defines the segment , but also declares it
to be a private segment, and requires that the portion of it described in
this code module must be aligned on a 16-byte boundary.
The available qualifiers are:
PRIVATE , PUBLIC ,
COMMON and STACK
specify the combination characteristics of the segment.
PRIVATE segments do not get combined with any
others by the linker; PUBLIC and
STACK segments get concatenated together at link
time; and COMMON segments all get overlaid on top
of each other rather than stuck end-to-end.
ALIGN is used, as shown above, to specify how
many low bits of the segment start address must be forced to zero. The
alignment value given may be any power of two from 1 to 4096; in reality,
the only values supported are 1, 2, 4, 16, 256 and 4096, so if 8 is
specified it will be rounded up to 16, and 32, 64 and 128 will all be
rounded up to 256, and so on. Note that alignment to 4096-byte boundaries
is a PharLap extension to the format and may not be supported by all
linkers.
CLASS can be used to specify the segment
class; this feature indicates to the linker that segments of the same class
should be placed near each other in the output file. The class name can be
any word, e.g. CLASS=CODE .
OVERLAY , like
CLASS , is specified with an arbitrary word as an
argument, and provides overlay information to an overlay-capable linker.
USE16 or
USE32 , which has the effect of recording the
choice in the object file and also ensuring that NASM's default assembly
mode when assembling in that segment is 16-bit or 32-bit respectively.
FLAT , which causes the default segment base for
anything in the segment to be the special group
FLAT , and also defines the group if it is not
already defined.
obj file format also allows segments to
be declared as having a pre-defined absolute segment address, although no
linkers are currently known to make sensible use of this feature;
nevertheless, NASM allows you to declare a segment such as
SEGMENT SCREEN ABSOLUTE=0xB800 if you need to.
The ABSOLUTE and ALIGN
keywords are mutually exclusive.
NASM's default segment attributes are ,
, no class, no overlay, and
.
GROUP : Defining Groups of SegmentsThe format also allows segments to be
grouped, so that a single segment register can be used to refer to all the
segments in a group. NASM therefore supplies the
directive, whereby you can code
segment data
; some data
segment bss
; some uninitialised data
group dgroup data bss
which will define a group called to
contain the segments and
. Like ,
causes the group name to be defined as a
symbol, so that you can refer to a variable
in the segment as
or as
, depending on which segment value
is currently in your segment register.
If you just refer to , however, and
is declared in a segment which is part of a
group, then NASM will default to giving you the offset of