7.4.2. Memory Models
--------------------
NASM contains no mechanism to support the various C memory models
directly; you have to keep track yourself of which one you are writing
for. This means you have to keep track of the following things:
* In models using a single code segment (tiny, small and compact),
functions are near. This means that function pointers, when stored
in data segments or pushed on the stack as function arguments, are
16 bits long and contain only an offset field (the `CS' register
never changes its value, and always gives the segment part of the
full function address), and that functions are called using
ordinary near `CALL' instructions and return using `RETN' (which,
in NASM, is synonymous with `RET' anyway). This means both that
you should write your own routines to return with `RETN', and that
you should call external C routines with near `CALL' instructions.
* In models using more than one code segment (medium, large and
huge), functions are far. This means that function pointers are 32
bits long (consisting of a 16-bit offset followed by a 16-bit
segment), and that functions are called using `CALL FAR' (or `CALL
seg:offset') and return using `RETF'. Again, you should therefore
write your own routines to return with `RETF' and use `CALL FAR'
to call external routines.
* In models using a single data segment (tiny, small and medium),
data pointers are 16 bits long, containing only an offset field
(the `DS' register doesn't change its value, and always gives the
segment part of the full data item address).
* In models using more than one data segment (compact, large and
huge), data pointers are 32 bits long, consisting of a 16-bit
offset followed by a 16- bit segment. You should still be careful
not to modify `DS' in your routines without restoring it
afterwards, but `ES' is free for you to use to access the contents
of 32-bit data pointers you are passed.
* The huge memory model allows single data items to exceed 64K in
size. In all other memory models, you can access the whole of a
data item just by doing arithmetic on the offset field of the
pointer you are given, whether a segment field is present or not;
in huge model, you have to be more careful of your pointer
arithmetic.
* In most memory models, there is a _default_ data segment, whose
segment address is kept in `DS' throughout the program. This data
segment is typically the same segment as the stack, kept in `SS',
so that functions' local variables (which are stored on the stack)
and global data items can both be accessed easily without changing
`DS'. Particularly large data items are typically stored in other
segments. However, some memory models (though not the standard
ones, usually) allow the assumption that `SS' and `DS' hold the
same value to be removed. Be careful about functions' local
variables in this latter case.
In models with a single code segment, the segment is called `_TEXT',
so your code segment must also go by this name in order to be linked
into the same place as the main code segment. In models with a single
data segment, or with a default data segment, it is called `_DATA'.