doc: break the documentation into chapters
Make the source code for the documentation a little easier to deal with by breaking it into individual chapter files. Add support to rdsrc.pl for auto-generating dependencies. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
parent
7c47273c45
commit
6ad3bab7fe
25 changed files with 9632 additions and 9540 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -68,7 +68,7 @@ TAGS
|
|||
/doc/Makefile
|
||||
/doc/html
|
||||
/doc/info
|
||||
/doc/inslist.src
|
||||
/doc/insns.src
|
||||
/doc/version.src
|
||||
/doc/warnings.src
|
||||
/doc/perlbreq.src
|
||||
|
|
839
doc/16bit.src
Normal file
839
doc/16bit.src
Normal file
|
@ -0,0 +1,839 @@
|
|||
\C{16bit} Writing 16-bit Code (DOS, Windows 3/3.1)
|
||||
|
||||
This chapter attempts to cover some of the common issues encountered
|
||||
when writing 16-bit code to run under \c{MS-DOS} or \c{Windows 3.x}. It
|
||||
covers how to link programs to produce \c{.EXE} or \c{.COM} files,
|
||||
how to write \c{.SYS} device drivers, and how to interface assembly
|
||||
language code with 16-bit C compilers and with Borland Pascal.
|
||||
|
||||
|
||||
\H{exefiles} Producing \i\c{.EXE} Files
|
||||
|
||||
Any large program written under DOS needs to be built as a \c{.EXE}
|
||||
file: only \c{.EXE} files have the necessary internal structure
|
||||
required to span more than one 64K segment. \i{Windows} programs,
|
||||
also, have to be built as \c{.EXE} files, since Windows does not
|
||||
support the \c{.COM} format.
|
||||
|
||||
In general, you generate \c{.EXE} files by using the \c{obj} output
|
||||
format to produce one or more \i\c{.obj} files, and then linking
|
||||
them together using a linker. However, NASM also supports the direct
|
||||
generation of simple DOS \c{.EXE} files using the \c{bin} output
|
||||
format (by using \c{DB} and \c{DW} to construct the \c{.EXE} file
|
||||
header), and a macro package is supplied to do this. Thanks to
|
||||
Yann Guidon for contributing the code for this.
|
||||
|
||||
NASM may also support \c{.EXE} natively as another output format in
|
||||
future releases.
|
||||
|
||||
|
||||
\S{objexe} Using the \c{obj} Format To Generate \c{.EXE} Files
|
||||
|
||||
This section describes the usual method of generating \c{.EXE} files
|
||||
by linking \c{.OBJ} files together.
|
||||
|
||||
Most 16-bit programming language packages come with a suitable
|
||||
linker; if you have none of these, there is a free linker called
|
||||
\i{VAL}\I{linker, free}, available in \c{LZH} archive format from
|
||||
\W{ftp://x2ftp.oulu.fi/pub/msdos/programming/lang/}\i\c{x2ftp.oulu.fi}.
|
||||
An LZH archiver can be found at
|
||||
\W{ftp://ftp.simtel.net/pub/simtelnet/msdos/arcers}\i\c{ftp.simtel.net}.
|
||||
There is another `free' linker (though this one doesn't come with
|
||||
sources) called \i{FREELINK}, available from
|
||||
\W{http://www.pcorner.com/tpc/old/3-101.html}\i\c{www.pcorner.com}.
|
||||
A third, \i\c{djlink}, written by DJ Delorie, is available at
|
||||
\W{http://www.delorie.com/djgpp/16bit/djlink/}\i\c{www.delorie.com}.
|
||||
A fourth linker, \i\c{ALINK}, written by Anthony A.J. Williams, is
|
||||
available at \W{http://alink.sourceforge.net}\i\c{alink.sourceforge.net}.
|
||||
|
||||
When linking several \c{.OBJ} files into a \c{.EXE} file, you should
|
||||
ensure that exactly one of them has a start point defined (using the
|
||||
\I{program entry point}\i\c{..start} special symbol defined by the
|
||||
\c{obj} format: see \k{dotdotstart}). If no module defines a start
|
||||
point, the linker will not know what value to give the entry-point
|
||||
field in the output file header; if more than one defines a start
|
||||
point, the linker will not know \e{which} value to use.
|
||||
|
||||
An example of a NASM source file which can be assembled to a
|
||||
\c{.OBJ} file and linked on its own to a \c{.EXE} is given here. It
|
||||
demonstrates the basic principles of defining a stack, initialising
|
||||
the segment registers, and declaring a start point. This file is
|
||||
also provided in the \I{test subdirectory}\c{test} subdirectory of
|
||||
the NASM archives, under the name \c{objexe.asm}.
|
||||
|
||||
\c segment code
|
||||
\c
|
||||
\c ..start:
|
||||
\c mov ax,data
|
||||
\c mov ds,ax
|
||||
\c mov ax,stack
|
||||
\c mov ss,ax
|
||||
\c mov sp,stacktop
|
||||
|
||||
This initial piece of code sets up \c{DS} to point to the data
|
||||
segment, and initializes \c{SS} and \c{SP} to point to the top of
|
||||
the provided stack. Notice that interrupts are implicitly disabled
|
||||
for one instruction after a move into \c{SS}, precisely for this
|
||||
situation, so that there's no chance of an interrupt occurring
|
||||
between the loads of \c{SS} and \c{SP} and not having a stack to
|
||||
execute on.
|
||||
|
||||
Note also that the special symbol \c{..start} is defined at the
|
||||
beginning of this code, which means that will be the entry point
|
||||
into the resulting executable file.
|
||||
|
||||
\c mov dx,hello
|
||||
\c mov ah,9
|
||||
\c int 0x21
|
||||
|
||||
The above is the main program: load \c{DS:DX} with a pointer to the
|
||||
greeting message (\c{hello} is implicitly relative to the segment
|
||||
\c{data}, which was loaded into \c{DS} in the setup code, so the
|
||||
full pointer is valid), and call the DOS print-string function.
|
||||
|
||||
\c mov ax,0x4c00
|
||||
\c int 0x21
|
||||
|
||||
This terminates the program using another DOS system call.
|
||||
|
||||
\c segment data
|
||||
\c
|
||||
\c hello: db 'hello, world', 13, 10, '$'
|
||||
|
||||
The data segment contains the string we want to display.
|
||||
|
||||
\c segment stack stack
|
||||
\c resb 64
|
||||
\c stacktop:
|
||||
|
||||
The above code declares a stack segment containing 64 bytes of
|
||||
uninitialized stack space, and points \c{stacktop} at the top of it.
|
||||
The directive \c{segment stack stack} defines a segment \e{called}
|
||||
\c{stack}, and also of \e{type} \c{STACK}. The latter is not
|
||||
necessary to the correct running of the program, but linkers are
|
||||
likely to issue warnings or errors if your program has no segment of
|
||||
type \c{STACK}.
|
||||
|
||||
The above file, when assembled into a \c{.OBJ} file, will link on
|
||||
its own to a valid \c{.EXE} file, which when run will print `hello,
|
||||
world' and then exit.
|
||||
|
||||
|
||||
\S{binexe} Using the \c{bin} Format To Generate \c{.EXE} Files
|
||||
|
||||
The \c{.EXE} file format is simple enough that it's possible to
|
||||
build a \c{.EXE} file by writing a pure-binary program and sticking
|
||||
a 32-byte header on the front. This header is simple enough that it
|
||||
can be generated using \c{DB} and \c{DW} commands by NASM itself, so
|
||||
that you can use the \c{bin} output format to directly generate
|
||||
\c{.EXE} files.
|
||||
|
||||
Included in the NASM archives, in the \I{misc subdirectory}\c{misc}
|
||||
subdirectory, is a file \i\c{exebin.mac} of macros. It defines three
|
||||
macros: \i\c{EXE_begin}, \i\c{EXE_stack} and \i\c{EXE_end}.
|
||||
|
||||
To produce a \c{.EXE} file using this method, you should start by
|
||||
using \c{%include} to load the \c{exebin.mac} macro package into
|
||||
your source file. You should then issue the \c{EXE_begin} macro call
|
||||
(which takes no arguments) to generate the file header data. Then
|
||||
write code as normal for the \c{bin} format - you can use all three
|
||||
standard sections \c{.text}, \c{.data} and \c{.bss}. At the end of
|
||||
the file you should call the \c{EXE_end} macro (again, no arguments),
|
||||
which defines some symbols to mark section sizes, and these symbols
|
||||
are referred to in the header code generated by \c{EXE_begin}.
|
||||
|
||||
In this model, the code you end up writing starts at \c{0x100}, just
|
||||
like a \c{.COM} file - in fact, if you strip off the 32-byte header
|
||||
from the resulting \c{.EXE} file, you will have a valid \c{.COM}
|
||||
program. All the segment bases are the same, so you are limited to a
|
||||
64K program, again just like a \c{.COM} file. Note that an \c{ORG}
|
||||
directive is issued by the \c{EXE_begin} macro, so you should not
|
||||
explicitly issue one of your own.
|
||||
|
||||
You can't directly refer to your segment base value, unfortunately,
|
||||
since this would require a relocation in the header, and things
|
||||
would get a lot more complicated. So you should get your segment
|
||||
base by copying it out of \c{CS} instead.
|
||||
|
||||
On entry to your \c{.EXE} file, \c{SS:SP} are already set up to
|
||||
point to the top of a 2Kb stack. You can adjust the default stack
|
||||
size of 2Kb by calling the \c{EXE_stack} macro. For example, to
|
||||
change the stack size of your program to 64 bytes, you would call
|
||||
\c{EXE_stack 64}.
|
||||
|
||||
A sample program which generates a \c{.EXE} file in this way is
|
||||
given in the \c{test} subdirectory of the NASM archive, as
|
||||
\c{binexe.asm}.
|
||||
|
||||
|
||||
\H{comfiles} Producing \i\c{.COM} Files
|
||||
|
||||
While large DOS programs must be written as \c{.EXE} files, small
|
||||
ones are often better written as \c{.COM} files. \c{.COM} files are
|
||||
pure binary, and therefore most easily produced using the \c{bin}
|
||||
output format.
|
||||
|
||||
|
||||
\S{combinfmt} Using the \c{bin} Format To Generate \c{.COM} Files
|
||||
|
||||
\c{.COM} files expect to be loaded at offset \c{100h} into their
|
||||
segment (though the segment may change). Execution then begins at
|
||||
\I\c{ORG}\c{100h}, i.e. right at the start of the program. So to
|
||||
write a \c{.COM} program, you would create a source file looking
|
||||
like
|
||||
|
||||
\c org 100h
|
||||
\c
|
||||
\c section .text
|
||||
\c
|
||||
\c start:
|
||||
\c ; put your code here
|
||||
\c
|
||||
\c section .data
|
||||
\c
|
||||
\c ; put data items here
|
||||
\c
|
||||
\c section .bss
|
||||
\c
|
||||
\c ; put uninitialized data here
|
||||
|
||||
The \c{bin} format puts the \c{.text} section first in the file, so
|
||||
you can declare data or BSS items before beginning to write code if
|
||||
you want to and the code will still end up at the front of the file
|
||||
where it belongs.
|
||||
|
||||
The BSS (uninitialized data) section does not take up space in the
|
||||
\c{.COM} file itself: instead, addresses of BSS items are resolved
|
||||
to point at space beyond the end of the file, on the grounds that
|
||||
this will be free memory when the program is run. Therefore you
|
||||
should not rely on your BSS being initialized to all zeros when you
|
||||
run.
|
||||
|
||||
To assemble the above program, you should use a command line like
|
||||
|
||||
\c nasm myprog.asm -fbin -o myprog.com
|
||||
|
||||
The \c{bin} format would produce a file called \c{myprog} if no
|
||||
explicit output file name were specified, so you have to override it
|
||||
and give the desired file name.
|
||||
|
||||
|
||||
\S{comobjfmt} Using the \c{obj} Format To Generate \c{.COM} Files
|
||||
|
||||
If you are writing a \c{.COM} program as more than one module, you
|
||||
may wish to assemble several \c{.OBJ} files and link them together
|
||||
into a \c{.COM} program. You can do this, provided you have a linker
|
||||
capable of outputting \c{.COM} files directly (\i{TLINK} does this),
|
||||
or alternatively a converter program such as \i\c{EXE2BIN} to
|
||||
transform the \c{.EXE} file output from the linker into a \c{.COM}
|
||||
file.
|
||||
|
||||
If you do this, you need to take care of several things:
|
||||
|
||||
\b The first object file containing code should start its code
|
||||
segment with a line like \c{RESB 100h}. This is to ensure that the
|
||||
code begins at offset \c{100h} relative to the beginning of the code
|
||||
segment, so that the linker or converter program does not have to
|
||||
adjust address references within the file when generating the
|
||||
\c{.COM} file. Other assemblers use an \i\c{ORG} directive for this
|
||||
purpose, but \c{ORG} in NASM is a format-specific directive to the
|
||||
\c{bin} output format, and does not mean the same thing as it does
|
||||
in MASM-compatible assemblers.
|
||||
|
||||
\b You don't need to define a stack segment.
|
||||
|
||||
\b All your segments should be in the same group, so that every time
|
||||
your code or data references a symbol offset, all offsets are
|
||||
relative to the same segment base. This is because, when a \c{.COM}
|
||||
file is loaded, all the segment registers contain the same value.
|
||||
|
||||
|
||||
\H{sysfiles} Producing \i\c{.SYS} Files
|
||||
|
||||
\i{MS-DOS device drivers} - \c{.SYS} files - are pure binary files,
|
||||
similar to \c{.COM} files, except that they start at origin zero
|
||||
rather than \c{100h}. Therefore, if you are writing a device driver
|
||||
using the \c{bin} format, you do not need the \c{ORG} directive,
|
||||
since the default origin for \c{bin} is zero. Similarly, if you are
|
||||
using \c{obj}, you do not need the \c{RESB 100h} at the start of
|
||||
your code segment.
|
||||
|
||||
\c{.SYS} files start with a header structure, containing pointers to
|
||||
the various routines inside the driver which do the work. This
|
||||
structure should be defined at the start of the code segment, even
|
||||
though it is not actually code.
|
||||
|
||||
For more information on the format of \c{.SYS} files, and the data
|
||||
which has to go in the header structure, a list of books is given in
|
||||
the Frequently Asked Questions list for the newsgroup
|
||||
\W{news:comp.os.msdos.programmer}\i\c{comp.os.msdos.programmer}.
|
||||
|
||||
|
||||
\H{16c} Interfacing to 16-bit C Programs
|
||||
|
||||
This section covers the basics of writing assembly routines that
|
||||
call, or are called from, C programs. To do this, you would
|
||||
typically write an assembly module as a \c{.OBJ} file, and link it
|
||||
with your C modules to produce a \i{mixed-language program}.
|
||||
|
||||
|
||||
\S{16cunder} External Symbol Names
|
||||
|
||||
\I{C symbol names}\I{underscore, in C symbols}C compilers have the
|
||||
convention that the names of all global symbols (functions or data)
|
||||
they define are formed by prefixing an underscore to the name as it
|
||||
appears in the C program. So, for example, the function a C
|
||||
programmer thinks of as \c{printf} appears to an assembly language
|
||||
programmer as \c{_printf}. This means that in your assembly
|
||||
programs, you can define symbols without a leading underscore, and
|
||||
not have to worry about name clashes with C symbols.
|
||||
|
||||
If you find the underscores inconvenient, you can define macros to
|
||||
replace the \c{GLOBAL} and \c{EXTERN} directives as follows:
|
||||
|
||||
\c %macro cglobal 1
|
||||
\c
|
||||
\c global _%1
|
||||
\c %define %1 _%1
|
||||
\c
|
||||
\c %endmacro
|
||||
\c
|
||||
\c %macro cextern 1
|
||||
\c
|
||||
\c extern _%1
|
||||
\c %define %1 _%1
|
||||
\c
|
||||
\c %endmacro
|
||||
|
||||
(These forms of the macros only take one argument at a time; a
|
||||
\c{%rep} construct could solve this.)
|
||||
|
||||
If you then declare an external like this:
|
||||
|
||||
\c cextern printf
|
||||
|
||||
then the macro will expand it as
|
||||
|
||||
\c extern _printf
|
||||
\c %define printf _printf
|
||||
|
||||
Thereafter, you can reference \c{printf} as if it was a symbol, and
|
||||
the preprocessor will put the leading underscore on where necessary.
|
||||
|
||||
The \c{cglobal} macro works similarly. You must use \c{cglobal}
|
||||
before defining the symbol in question, but you would have had to do
|
||||
that anyway if you used \c{GLOBAL}.
|
||||
|
||||
Also see \k{opt-pfix}.
|
||||
|
||||
\S{16cmodels} \i{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:
|
||||
|
||||
\b 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 \c{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 \c{CALL} instructions and return using \c{RETN} (which, in
|
||||
NASM, is synonymous with \c{RET} anyway). This means both that you
|
||||
should write your own routines to return with \c{RETN}, and that you
|
||||
should call external C routines with near \c{CALL} instructions.
|
||||
|
||||
\b 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 \c{CALL FAR} (or
|
||||
\c{CALL seg:offset}) and return using \c{RETF}. Again, you should
|
||||
therefore write your own routines to return with \c{RETF} and use
|
||||
\c{CALL FAR} to call external routines.
|
||||
|
||||
\b In models using a single data segment (tiny, small and medium),
|
||||
data pointers are 16 bits long, containing only an offset field (the
|
||||
\c{DS} register doesn't change its value, and always gives the
|
||||
segment part of the full data item address).
|
||||
|
||||
\b 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 \c{DS} in your routines without restoring it afterwards, but
|
||||
\c{ES} is free for you to use to access the contents of 32-bit data
|
||||
pointers you are passed.
|
||||
|
||||
\b 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.
|
||||
|
||||
\b In most memory models, there is a \e{default} data segment, whose
|
||||
segment address is kept in \c{DS} throughout the program. This data
|
||||
segment is typically the same segment as the stack, kept in \c{SS},
|
||||
so that functions' local variables (which are stored on the stack)
|
||||
and global data items can both be accessed easily without changing
|
||||
\c{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 \c{SS} and \c{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
|
||||
\i\c{_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 \i\c{_DATA}.
|
||||
|
||||
|
||||
\S{16cfunc} Function Definitions and Function Calls
|
||||
|
||||
\I{functions, C calling convention}The \i{C calling convention} in
|
||||
16-bit programs is as follows. In the following description, the
|
||||
words \e{caller} and \e{callee} are used to denote the function
|
||||
doing the calling and the function which gets called.
|
||||
|
||||
\b The caller pushes the function's parameters on the stack, one
|
||||
after another, in reverse order (right to left, so that the first
|
||||
argument specified to the function is pushed last).
|
||||
|
||||
\b The caller then executes a \c{CALL} instruction to pass control
|
||||
to the callee. This \c{CALL} is either near or far depending on the
|
||||
memory model.
|
||||
|
||||
\b The callee receives control, and typically (although this is not
|
||||
actually necessary, in functions which do not need to access their
|
||||
parameters) starts by saving the value of \c{SP} in \c{BP} so as to
|
||||
be able to use \c{BP} as a base pointer to find its parameters on
|
||||
the stack. However, the caller was probably doing this too, so part
|
||||
of the calling convention states that \c{BP} must be preserved by
|
||||
any C function. Hence the callee, if it is going to set up \c{BP} as
|
||||
a \i\e{frame pointer}, must push the previous value first.
|
||||
|
||||
\b The callee may then access its parameters relative to \c{BP}.
|
||||
The word at \c{[BP]} holds the previous value of \c{BP} as it was
|
||||
pushed; the next word, at \c{[BP+2]}, holds the offset part of the
|
||||
return address, pushed implicitly by \c{CALL}. In a small-model
|
||||
(near) function, the parameters start after that, at \c{[BP+4]}; in
|
||||
a large-model (far) function, the segment part of the return address
|
||||
lives at \c{[BP+4]}, and the parameters begin at \c{[BP+6]}. The
|
||||
leftmost parameter of the function, since it was pushed last, is
|
||||
accessible at this offset from \c{BP}; the others follow, at
|
||||
successively greater offsets. Thus, in a function such as \c{printf}
|
||||
which takes a variable number of parameters, the pushing of the
|
||||
parameters in reverse order means that the function knows where to
|
||||
find its first parameter, which tells it the number and type of the
|
||||
remaining ones.
|
||||
|
||||
\b The callee may also wish to decrease \c{SP} further, so as to
|
||||
allocate space on the stack for local variables, which will then be
|
||||
accessible at negative offsets from \c{BP}.
|
||||
|
||||
\b The callee, if it wishes to return a value to the caller, should
|
||||
leave the value in \c{AL}, \c{AX} or \c{DX:AX} depending on the size
|
||||
of the value. Floating-point results are sometimes (depending on the
|
||||
compiler) returned in \c{ST0}.
|
||||
|
||||
\b Once the callee has finished processing, it restores \c{SP} from
|
||||
\c{BP} if it had allocated local stack space, then pops the previous
|
||||
value of \c{BP}, and returns via \c{RETN} or \c{RETF} depending on
|
||||
memory model.
|
||||
|
||||
\b When the caller regains control from the callee, the function
|
||||
parameters are still on the stack, so it typically adds an immediate
|
||||
constant to \c{SP} to remove them (instead of executing a number of
|
||||
slow \c{POP} instructions). Thus, if a function is accidentally
|
||||
called with the wrong number of parameters due to a prototype
|
||||
mismatch, the stack will still be returned to a sensible state since
|
||||
the caller, which \e{knows} how many parameters it pushed, does the
|
||||
removing.
|
||||
|
||||
It is instructive to compare this calling convention with that for
|
||||
Pascal programs (described in \k{16bpfunc}). Pascal has a simpler
|
||||
convention, since no functions have variable numbers of parameters.
|
||||
Therefore the callee knows how many parameters it should have been
|
||||
passed, and is able to deallocate them from the stack itself by
|
||||
passing an immediate argument to the \c{RET} or \c{RETF}
|
||||
instruction, so the caller does not have to do it. Also, the
|
||||
parameters are pushed in left-to-right order, not right-to-left,
|
||||
which means that a compiler can give better guarantees about
|
||||
sequence points without performance suffering.
|
||||
|
||||
Thus, you would define a function in C style in the following way.
|
||||
The following example is for small model:
|
||||
|
||||
\c global _myfunc
|
||||
\c
|
||||
\c _myfunc:
|
||||
\c push bp
|
||||
\c mov bp,sp
|
||||
\c sub sp,0x40 ; 64 bytes of local stack space
|
||||
\c mov bx,[bp+4] ; first parameter to function
|
||||
\c
|
||||
\c ; some more code
|
||||
\c
|
||||
\c mov sp,bp ; undo "sub sp,0x40" above
|
||||
\c pop bp
|
||||
\c ret
|
||||
|
||||
For a large-model function, you would replace \c{RET} by \c{RETF},
|
||||
and look for the first parameter at \c{[BP+6]} instead of
|
||||
\c{[BP+4]}. Of course, if one of the parameters is a pointer, then
|
||||
the offsets of \e{subsequent} parameters will change depending on
|
||||
the memory model as well: far pointers take up four bytes on the
|
||||
stack when passed as a parameter, whereas near pointers take up two.
|
||||
|
||||
At the other end of the process, to call a C function from your
|
||||
assembly code, you would do something like this:
|
||||
|
||||
\c extern _printf
|
||||
\c
|
||||
\c ; and then, further down...
|
||||
\c
|
||||
\c push word [myint] ; one of my integer variables
|
||||
\c push word mystring ; pointer into my data segment
|
||||
\c call _printf
|
||||
\c add sp,byte 4 ; `byte' saves space
|
||||
\c
|
||||
\c ; then those data items...
|
||||
\c
|
||||
\c segment _DATA
|
||||
\c
|
||||
\c myint dw 1234
|
||||
\c mystring db 'This number -> %d <- should be 1234',10,0
|
||||
|
||||
This piece of code is the small-model assembly equivalent of the C
|
||||
code
|
||||
|
||||
\c int myint = 1234;
|
||||
\c printf("This number -> %d <- should be 1234\n", myint);
|
||||
|
||||
In large model, the function-call code might look more like this. In
|
||||
this example, it is assumed that \c{DS} already holds the segment
|
||||
base of the segment \c{_DATA}. If not, you would have to initialize
|
||||
it first.
|
||||
|
||||
\c push word [myint]
|
||||
\c push word seg mystring ; Now push the segment, and...
|
||||
\c push word mystring ; ... offset of "mystring"
|
||||
\c call far _printf
|
||||
\c add sp,byte 6
|
||||
|
||||
The integer value still takes up one word on the stack, since large
|
||||
model does not affect the size of the \c{int} data type. The first
|
||||
argument (pushed last) to \c{printf}, however, is a data pointer,
|
||||
and therefore has to contain a segment and offset part. The segment
|
||||
should be stored second in memory, and therefore must be pushed
|
||||
first. (Of course, \c{PUSH DS} would have been a shorter instruction
|
||||
than \c{PUSH WORD SEG mystring}, if \c{DS} was set up as the above
|
||||
example assumed.) Then the actual call becomes a far call, since
|
||||
functions expect far calls in large model; and \c{SP} has to be
|
||||
increased by 6 rather than 4 afterwards to make up for the extra
|
||||
word of parameters.
|
||||
|
||||
|
||||
\S{16cdata} Accessing Data Items
|
||||
|
||||
To get at the contents of C variables, or to declare variables which
|
||||
C can access, you need only declare the names as \c{GLOBAL} or
|
||||
\c{EXTERN}. (Again, the names require leading underscores, as stated
|
||||
in \k{16cunder}.) Thus, a C variable declared as \c{int i} can be
|
||||
accessed from assembler as
|
||||
|
||||
\c extern _i
|
||||
\c
|
||||
\c mov ax,[_i]
|
||||
|
||||
And to declare your own integer variable which C programs can access
|
||||
as \c{extern int j}, you do this (making sure you are assembling in
|
||||
the \c{_DATA} segment, if necessary):
|
||||
|
||||
\c global _j
|
||||
\c
|
||||
\c _j dw 0
|
||||
|
||||
To access a C array, you need to know the size of the components of
|
||||
the array. For example, \c{int} variables are two bytes long, so if
|
||||
a C program declares an array as \c{int a[10]}, you can access
|
||||
\c{a[3]} by coding \c{mov ax,[_a+6]}. (The byte offset 6 is obtained
|
||||
by multiplying the desired array index, 3, by the size of the array
|
||||
element, 2.) The sizes of the C base types in 16-bit compilers are:
|
||||
1 for \c{char}, 2 for \c{short} and \c{int}, 4 for \c{long} and
|
||||
\c{float}, and 8 for \c{double}.
|
||||
|
||||
To access a C \i{data structure}, you need to know the offset from
|
||||
the base of the structure to the field you are interested in. You
|
||||
can either do this by converting the C structure definition into a
|
||||
NASM structure definition (using \i\c{STRUC}), or by calculating the
|
||||
one offset and using just that.
|
||||
|
||||
To do either of these, you should read your C compiler's manual to
|
||||
find out how it organizes data structures. NASM gives no special
|
||||
alignment to structure members in its own \c{STRUC} macro, so you
|
||||
have to specify alignment yourself if the C compiler generates it.
|
||||
Typically, you might find that a structure like
|
||||
|
||||
\c struct {
|
||||
\c char c;
|
||||
\c int i;
|
||||
\c } foo;
|
||||
|
||||
might be four bytes long rather than three, since the \c{int} field
|
||||
would be aligned to a two-byte boundary. However, this sort of
|
||||
feature tends to be a configurable option in the C compiler, either
|
||||
using command-line options or \c{#pragma} lines, so you have to find
|
||||
out how your own compiler does it.
|
||||
|
||||
|
||||
\S{16cmacro} \i\c{c16.mac}: Helper Macros for the 16-bit C Interface
|
||||
|
||||
Included in the NASM archives, in the \I{misc subdirectory}\c{misc}
|
||||
directory, is a file \c{c16.mac} of macros. It defines three macros:
|
||||
\i\c{proc}, \i\c{arg} and \i\c{endproc}. These are intended to be
|
||||
used for C-style procedure definitions, and they automate a lot of
|
||||
the work involved in keeping track of the calling convention.
|
||||
|
||||
(An alternative, TASM compatible form of \c{arg} is also now built
|
||||
into NASM's preprocessor. See \k{stackrel} for details.)
|
||||
|
||||
An example of an assembly function using the macro set is given
|
||||
here:
|
||||
|
||||
\c proc _nearproc
|
||||
\c
|
||||
\c %$i arg
|
||||
\c %$j arg
|
||||
\c mov ax,[bp + %$i]
|
||||
\c mov bx,[bp + %$j]
|
||||
\c add ax,[bx]
|
||||
\c
|
||||
\c endproc
|
||||
|
||||
This defines \c{_nearproc} to be a procedure taking two arguments,
|
||||
the first (\c{i}) an integer and the second (\c{j}) a pointer to an
|
||||
integer. It returns \c{i + *j}.
|
||||
|
||||
Note that the \c{arg} macro has an \c{EQU} as the first line of its
|
||||
expansion, and since the label before the macro call gets prepended
|
||||
to the first line of the expanded macro, the \c{EQU} works, defining
|
||||
\c{%$i} to be an offset from \c{BP}. A context-local variable is
|
||||
used, local to the context pushed by the \c{proc} macro and popped
|
||||
by the \c{endproc} macro, so that the same argument name can be used
|
||||
in later procedures. Of course, you don't \e{have} to do that.
|
||||
|
||||
The macro set produces code for near functions (tiny, small and
|
||||
compact-model code) by default. You can have it generate far
|
||||
functions (medium, large and huge-model code) by means of coding
|
||||
\I\c{FARCODE}\c{%define FARCODE}. This changes the kind of return
|
||||
instruction generated by \c{endproc}, and also changes the starting
|
||||
point for the argument offsets. The macro set contains no intrinsic
|
||||
dependency on whether data pointers are far or not.
|
||||
|
||||
\c{arg} can take an optional parameter, giving the size of the
|
||||
argument. If no size is given, 2 is assumed, since it is likely that
|
||||
many function parameters will be of type \c{int}.
|
||||
|
||||
The large-model equivalent of the above function would look like this:
|
||||
|
||||
\c %define FARCODE
|
||||
\c
|
||||
\c proc _farproc
|
||||
\c
|
||||
\c %$i arg
|
||||
\c %$j arg 4
|
||||
\c mov ax,[bp + %$i]
|
||||
\c mov bx,[bp + %$j]
|
||||
\c mov es,[bp + %$j + 2]
|
||||
\c add ax,[bx]
|
||||
\c
|
||||
\c endproc
|
||||
|
||||
This makes use of the argument to the \c{arg} macro to define a
|
||||
parameter of size 4, because \c{j} is now a far pointer. When we
|
||||
load from \c{j}, we must load a segment and an offset.
|
||||
|
||||
|
||||
\H{16bp} Interfacing to \i{Borland Pascal} Programs
|
||||
|
||||
Interfacing to Borland Pascal programs is similar in concept to
|
||||
interfacing to 16-bit C programs. The differences are:
|
||||
|
||||
\b The leading underscore required for interfacing to C programs is
|
||||
not required for Pascal.
|
||||
|
||||
\b The memory model is always large: functions are far, data
|
||||
pointers are far, and no data item can be more than 64K long.
|
||||
(Actually, some functions are near, but only those functions that
|
||||
are local to a Pascal unit and never called from outside it. All
|
||||
assembly functions that Pascal calls, and all Pascal functions that
|
||||
assembly routines are able to call, are far.) However, all static
|
||||
data declared in a Pascal program goes into the default data
|
||||
segment, which is the one whose segment address will be in \c{DS}
|
||||
when control is passed to your assembly code. The only things that
|
||||
do not live in the default data segment are local variables (they
|
||||
live in the stack segment) and dynamically allocated variables. All
|
||||
data \e{pointers}, however, are far.
|
||||
|
||||
\b The function calling convention is different - described below.
|
||||
|
||||
\b Some data types, such as strings, are stored differently.
|
||||
|
||||
\b There are restrictions on the segment names you are allowed to
|
||||
use - Borland Pascal will ignore code or data declared in a segment
|
||||
it doesn't like the name of. The restrictions are described below.
|
||||
|
||||
|
||||
\S{16bpfunc} The Pascal Calling Convention
|
||||
|
||||
\I{functions, Pascal calling convention}\I{Pascal calling
|
||||
convention}The 16-bit Pascal calling convention is as follows. In
|
||||
the following description, the words \e{caller} and \e{callee} are
|
||||
used to denote the function doing the calling and the function which
|
||||
gets called.
|
||||
|
||||
\b The caller pushes the function's parameters on the stack, one
|
||||
after another, in normal order (left to right, so that the first
|
||||
argument specified to the function is pushed first).
|
||||
|
||||
\b The caller then executes a far \c{CALL} instruction to pass
|
||||
control to the callee.
|
||||
|
||||
\b The callee receives control, and typically (although this is not
|
||||
actually necessary, in functions which do not need to access their
|
||||
parameters) starts by saving the value of \c{SP} in \c{BP} so as to
|
||||
be able to use \c{BP} as a base pointer to find its parameters on
|
||||
the stack. However, the caller was probably doing this too, so part
|
||||
of the calling convention states that \c{BP} must be preserved by
|
||||
any function. Hence the callee, if it is going to set up \c{BP} as a
|
||||
\i{frame pointer}, must push the previous value first.
|
||||
|
||||
\b The callee may then access its parameters relative to \c{BP}.
|
||||
The word at \c{[BP]} holds the previous value of \c{BP} as it was
|
||||
pushed. The next word, at \c{[BP+2]}, holds the offset part of the
|
||||
return address, and the next one at \c{[BP+4]} the segment part. The
|
||||
parameters begin at \c{[BP+6]}. The rightmost parameter of the
|
||||
function, since it was pushed last, is accessible at this offset
|
||||
from \c{BP}; the others follow, at successively greater offsets.
|
||||
|
||||
\b The callee may also wish to decrease \c{SP} further, so as to
|
||||
allocate space on the stack for local variables, which will then be
|
||||
accessible at negative offsets from \c{BP}.
|
||||
|
||||
\b The callee, if it wishes to return a value to the caller, should
|
||||
leave the value in \c{AL}, \c{AX} or \c{DX:AX} depending on the size
|
||||
of the value. Floating-point results are returned in \c{ST0}.
|
||||
Results of type \c{Real} (Borland's own custom floating-point data
|
||||
type, not handled directly by the FPU) are returned in \c{DX:BX:AX}.
|
||||
To return a result of type \c{String}, the caller pushes a pointer
|
||||
to a temporary string before pushing the parameters, and the callee
|
||||
places the returned string value at that location. The pointer is
|
||||
not a parameter, and should not be removed from the stack by the
|
||||
\c{RETF} instruction.
|
||||
|
||||
\b Once the callee has finished processing, it restores \c{SP} from
|
||||
\c{BP} if it had allocated local stack space, then pops the previous
|
||||
value of \c{BP}, and returns via \c{RETF}. It uses the form of
|
||||
\c{RETF} with an immediate parameter, giving the number of bytes
|
||||
taken up by the parameters on the stack. This causes the parameters
|
||||
to be removed from the stack as a side effect of the return
|
||||
instruction.
|
||||
|
||||
\b When the caller regains control from the callee, the function
|
||||
parameters have already been removed from the stack, so it needs to
|
||||
do nothing further.
|
||||
|
||||
Thus, you would define a function in Pascal style, taking two
|
||||
\c{Integer}-type parameters, in the following way:
|
||||
|
||||
\c global myfunc
|
||||
\c
|
||||
\c myfunc: push bp
|
||||
\c mov bp,sp
|
||||
\c sub sp,0x40 ; 64 bytes of local stack space
|
||||
\c mov bx,[bp+8] ; first parameter to function
|
||||
\c mov bx,[bp+6] ; second parameter to function
|
||||
\c
|
||||
\c ; some more code
|
||||
\c
|
||||
\c mov sp,bp ; undo "sub sp,0x40" above
|
||||
\c pop bp
|
||||
\c retf 4 ; total size of params is 4
|
||||
|
||||
At the other end of the process, to call a Pascal function from your
|
||||
assembly code, you would do something like this:
|
||||
|
||||
\c extern SomeFunc
|
||||
\c
|
||||
\c ; and then, further down...
|
||||
\c
|
||||
\c push word seg mystring ; Now push the segment, and...
|
||||
\c push word mystring ; ... offset of "mystring"
|
||||
\c push word [myint] ; one of my variables
|
||||
\c call far SomeFunc
|
||||
|
||||
This is equivalent to the Pascal code
|
||||
|
||||
\c procedure SomeFunc(String: PChar; Int: Integer);
|
||||
\c SomeFunc(@mystring, myint);
|
||||
|
||||
|
||||
\S{16bpseg} Borland Pascal \I{segment names, Borland Pascal}Segment
|
||||
Name Restrictions
|
||||
|
||||
Since Borland Pascal's internal unit file format is completely
|
||||
different from \c{OBJ}, it only makes a very sketchy job of actually
|
||||
reading and understanding the various information contained in a
|
||||
real \c{OBJ} file when it links that in. Therefore an object file
|
||||
intended to be linked to a Pascal program must obey a number of
|
||||
restrictions:
|
||||
|
||||
\b Procedures and functions must be in a segment whose name is
|
||||
either \c{CODE}, \c{CSEG}, or something ending in \c{_TEXT}.
|
||||
|
||||
\b initialized data must be in a segment whose name is either
|
||||
\c{CONST} or something ending in \c{_DATA}.
|
||||
|
||||
\b Uninitialized data must be in a segment whose name is either
|
||||
\c{DATA}, \c{DSEG}, or something ending in \c{_BSS}.
|
||||
|
||||
\b Any other segments in the object file are completely ignored.
|
||||
\c{GROUP} directives and segment attributes are also ignored.
|
||||
|
||||
|
||||
\S{16bpmacro} Using \i\c{c16.mac} With Pascal Programs
|
||||
|
||||
The \c{c16.mac} macro package, described in \k{16cmacro}, can also
|
||||
be used to simplify writing functions to be called from Pascal
|
||||
programs, if you code \I\c{PASCAL}\c{%define PASCAL}. This
|
||||
definition ensures that functions are far (it implies
|
||||
\i\c{FARCODE}), and also causes procedure return instructions to be
|
||||
generated with an operand.
|
||||
|
||||
Defining \c{PASCAL} does not change the code which calculates the
|
||||
argument offsets; you must declare your function's arguments in
|
||||
reverse order. For example:
|
||||
|
||||
\c %define PASCAL
|
||||
\c
|
||||
\c proc _pascalproc
|
||||
\c
|
||||
\c %$j arg 4
|
||||
\c %$i arg
|
||||
\c mov ax,[bp + %$i]
|
||||
\c mov bx,[bp + %$j]
|
||||
\c mov es,[bp + %$j + 2]
|
||||
\c add ax,[bx]
|
||||
\c
|
||||
\c endproc
|
||||
|
||||
This defines the same routine, conceptually, as the example in
|
||||
\k{16cmacro}: it defines a function taking two arguments, an integer
|
||||
and a pointer to an integer, which returns the sum of the integer
|
||||
and the contents of the pointer. The only difference between this
|
||||
code and the large-model C version is that \c{PASCAL} is defined
|
||||
instead of \c{FARCODE}, and that the arguments are declared in
|
||||
reverse order.
|
||||
|
||||
|
504
doc/32bit.src
Normal file
504
doc/32bit.src
Normal file
|
@ -0,0 +1,504 @@
|
|||
\C{32bit} Writing 32-bit Code (Unix, Win32, DJGPP)
|
||||
|
||||
This chapter attempts to cover some of the common issues involved
|
||||
when writing 32-bit code, to run under \i{Win32} or Unix, or to be
|
||||
linked with C code generated by a Unix-style C compiler such as
|
||||
\i{DJGPP}. It covers how to write assembly code to interface with
|
||||
32-bit C routines, and how to write position-independent code for
|
||||
shared libraries.
|
||||
|
||||
Almost all 32-bit code, and in particular all code running under
|
||||
\c{Win32}, \c{DJGPP} or any of the PC Unix variants, runs in \I{flat
|
||||
memory model}\e{flat} memory model. This means that the segment registers
|
||||
and paging have already been set up to give you the same 32-bit 4Gb
|
||||
address space no matter what segment you work relative to, and that
|
||||
you should ignore all segment registers completely. When writing
|
||||
flat-model application code, you never need to use a segment
|
||||
override or modify any segment register, and the code-section
|
||||
addresses you pass to \c{CALL} and \c{JMP} live in the same address
|
||||
space as the data-section addresses you access your variables by and
|
||||
the stack-section addresses you access local variables and procedure
|
||||
parameters by. Every address is 32 bits long and contains only an
|
||||
offset part.
|
||||
|
||||
|
||||
\H{32c} Interfacing to 32-bit C Programs
|
||||
|
||||
A lot of the discussion in \k{16c}, about interfacing to 16-bit C
|
||||
programs, still applies when working in 32 bits. The absence of
|
||||
memory models or segmentation worries simplifies things a lot.
|
||||
|
||||
|
||||
\S{32cunder} External Symbol Names
|
||||
|
||||
Most 32-bit C compilers share the convention used by 16-bit
|
||||
compilers, that the names of all global symbols (functions or data)
|
||||
they define are formed by prefixing an underscore to the name as it
|
||||
appears in the C program. However, not all of them do: the \c{ELF}
|
||||
specification states that C symbols do \e{not} have a leading
|
||||
underscore on their assembly-language names.
|
||||
|
||||
The older Linux \c{a.out} C compiler, all \c{Win32} compilers,
|
||||
\c{DJGPP}, and \c{NetBSD} and \c{FreeBSD}, all use the leading
|
||||
underscore; for these compilers, the macros \c{cextern} and
|
||||
\c{cglobal}, as given in \k{16cunder}, will still work. For \c{ELF},
|
||||
though, the leading underscore should not be used.
|
||||
|
||||
See also \k{opt-pfix}.
|
||||
|
||||
\S{32cfunc} Function Definitions and Function Calls
|
||||
|
||||
\I{functions, C calling convention}The \i{C calling convention}
|
||||
in 32-bit programs is as follows. In the following description,
|
||||
the words \e{caller} and \e{callee} are used to denote
|
||||
the function doing the calling and the function which gets called.
|
||||
|
||||
\b The caller pushes the function's parameters on the stack, one
|
||||
after another, in reverse order (right to left, so that the first
|
||||
argument specified to the function is pushed last).
|
||||
|
||||
\b The caller then executes a near \c{CALL} instruction to pass
|
||||
control to the callee.
|
||||
|
||||
\b The callee receives control, and typically (although this is not
|
||||
actually necessary, in functions which do not need to access their
|
||||
parameters) starts by saving the value of \c{ESP} in \c{EBP} so as
|
||||
to be able to use \c{EBP} as a base pointer to find its parameters
|
||||
on the stack. However, the caller was probably doing this too, so
|
||||
part of the calling convention states that \c{EBP} must be preserved
|
||||
by any C function. Hence the callee, if it is going to set up
|
||||
\c{EBP} as a \i{frame pointer}, must push the previous value first.
|
||||
|
||||
\b The callee may then access its parameters relative to \c{EBP}.
|
||||
The doubleword at \c{[EBP]} holds the previous value of \c{EBP} as
|
||||
it was pushed; the next doubleword, at \c{[EBP+4]}, holds the return
|
||||
address, pushed implicitly by \c{CALL}. The parameters start after
|
||||
that, at \c{[EBP+8]}. The leftmost parameter of the function, since
|
||||
it was pushed last, is accessible at this offset from \c{EBP}; the
|
||||
others follow, at successively greater offsets. Thus, in a function
|
||||
such as \c{printf} which takes a variable number of parameters, the
|
||||
pushing of the parameters in reverse order means that the function
|
||||
knows where to find its first parameter, which tells it the number
|
||||
and type of the remaining ones.
|
||||
|
||||
\b The callee may also wish to decrease \c{ESP} further, so as to
|
||||
allocate space on the stack for local variables, which will then be
|
||||
accessible at negative offsets from \c{EBP}.
|
||||
|
||||
\b The callee, if it wishes to return a value to the caller, should
|
||||
leave the value in \c{AL}, \c{AX} or \c{EAX} depending on the size
|
||||
of the value. Floating-point results are typically returned in
|
||||
\c{ST0}.
|
||||
|
||||
\b Once the callee has finished processing, it restores \c{ESP} from
|
||||
\c{EBP} if it had allocated local stack space, then pops the previous
|
||||
value of \c{EBP}, and returns via \c{RET} (equivalently, \c{RETN}).
|
||||
|
||||
\b When the caller regains control from the callee, the function
|
||||
parameters are still on the stack, so it typically adds an immediate
|
||||
constant to \c{ESP} to remove them (instead of executing a number of
|
||||
slow \c{POP} instructions). Thus, if a function is accidentally
|
||||
called with the wrong number of parameters due to a prototype
|
||||
mismatch, the stack will still be returned to a sensible state since
|
||||
the caller, which \e{knows} how many parameters it pushed, does the
|
||||
removing.
|
||||
|
||||
There is an alternative calling convention used by Win32 programs
|
||||
for Windows API calls, and also for functions called \e{by} the
|
||||
Windows API such as window procedures: they follow what Microsoft
|
||||
calls the \c{__stdcall} convention. This is slightly closer to the
|
||||
Pascal convention, in that the callee clears the stack by passing a
|
||||
parameter to the \c{RET} instruction. However, the parameters are
|
||||
still pushed in right-to-left order.
|
||||
|
||||
Thus, you would define a function in C style in the following way:
|
||||
|
||||
\c global _myfunc
|
||||
\c
|
||||
\c _myfunc:
|
||||
\c push ebp
|
||||
\c mov ebp,esp
|
||||
\c sub esp,0x40 ; 64 bytes of local stack space
|
||||
\c mov ebx,[ebp+8] ; first parameter to function
|
||||
\c
|
||||
\c ; some more code
|
||||
\c
|
||||
\c leave ; mov esp,ebp / pop ebp
|
||||
\c ret
|
||||
|
||||
At the other end of the process, to call a C function from your
|
||||
assembly code, you would do something like this:
|
||||
|
||||
\c extern _printf
|
||||
\c
|
||||
\c ; and then, further down...
|
||||
\c
|
||||
\c push dword [myint] ; one of my integer variables
|
||||
\c push dword mystring ; pointer into my data segment
|
||||
\c call _printf
|
||||
\c add esp,byte 8 ; `byte' saves space
|
||||
\c
|
||||
\c ; then those data items...
|
||||
\c
|
||||
\c segment _DATA
|
||||
\c
|
||||
\c myint dd 1234
|
||||
\c mystring db 'This number -> %d <- should be 1234',10,0
|
||||
|
||||
This piece of code is the assembly equivalent of the C code
|
||||
|
||||
\c int myint = 1234;
|
||||
\c printf("This number -> %d <- should be 1234\n", myint);
|
||||
|
||||
|
||||
\S{32cdata} Accessing Data Items
|
||||
|
||||
To get at the contents of C variables, or to declare variables which
|
||||
C can access, you need only declare the names as \c{GLOBAL} or
|
||||
\c{EXTERN}. (Again, the names require leading underscores, as stated
|
||||
in \k{32cunder}.) Thus, a C variable declared as \c{int i} can be
|
||||
accessed from assembler as
|
||||
|
||||
\c extern _i
|
||||
\c mov eax,[_i]
|
||||
|
||||
And to declare your own integer variable which C programs can access
|
||||
as \c{extern int j}, you do this (making sure you are assembling in
|
||||
the \c{_DATA} segment, if necessary):
|
||||
|
||||
\c global _j
|
||||
\c _j dd 0
|
||||
|
||||
To access a C array, you need to know the size of the components of
|
||||
the array. For example, \c{int} variables are four bytes long, so if
|
||||
a C program declares an array as \c{int a[10]}, you can access
|
||||
\c{a[3]} by coding \c{mov ax,[_a+12]}. (The byte offset 12 is obtained
|
||||
by multiplying the desired array index, 3, by the size of the array
|
||||
element, 4.) The sizes of the C base types in 32-bit compilers are:
|
||||
1 for \c{char}, 2 for \c{short}, 4 for \c{int}, \c{long} and
|
||||
\c{float}, and 8 for \c{double}. Pointers, being 32-bit addresses,
|
||||
are also 4 bytes long.
|
||||
|
||||
To access a C \i{data structure}, you need to know the offset from
|
||||
the base of the structure to the field you are interested in. You
|
||||
can either do this by converting the C structure definition into a
|
||||
NASM structure definition (using \c{STRUC}), or by calculating the
|
||||
one offset and using just that.
|
||||
|
||||
To do either of these, you should read your C compiler's manual to
|
||||
find out how it organizes data structures. NASM gives no special
|
||||
alignment to structure members in its own \i\c{STRUC} macro, so you
|
||||
have to specify alignment yourself if the C compiler generates it.
|
||||
Typically, you might find that a structure like
|
||||
|
||||
\c struct {
|
||||
\c char c;
|
||||
\c int i;
|
||||
\c } foo;
|
||||
|
||||
might be eight bytes long rather than five, since the \c{int} field
|
||||
would be aligned to a four-byte boundary. However, this sort of
|
||||
feature is sometimes a configurable option in the C compiler, either
|
||||
using command-line options or \c{#pragma} lines, so you have to find
|
||||
out how your own compiler does it.
|
||||
|
||||
|
||||
\S{32cmacro} \i\c{c32.mac}: Helper Macros for the 32-bit C Interface
|
||||
|
||||
Included in the NASM archives, in the \I{misc directory}\c{misc}
|
||||
directory, is a file \c{c32.mac} of macros. It defines three macros:
|
||||
\i\c{proc}, \i\c{arg} and \i\c{endproc}. These are intended to be
|
||||
used for C-style procedure definitions, and they automate a lot of
|
||||
the work involved in keeping track of the calling convention.
|
||||
|
||||
An example of an assembly function using the macro set is given
|
||||
here:
|
||||
|
||||
\c proc _proc32
|
||||
\c
|
||||
\c %$i arg
|
||||
\c %$j arg
|
||||
\c mov eax,[ebp + %$i]
|
||||
\c mov ebx,[ebp + %$j]
|
||||
\c add eax,[ebx]
|
||||
\c
|
||||
\c endproc
|
||||
|
||||
This defines \c{_proc32} to be a procedure taking two arguments, the
|
||||
first (\c{i}) an integer and the second (\c{j}) a pointer to an
|
||||
integer. It returns \c{i + *j}.
|
||||
|
||||
Note that the \c{arg} macro has an \c{EQU} as the first line of its
|
||||
expansion, and since the label before the macro call gets prepended
|
||||
to the first line of the expanded macro, the \c{EQU} works, defining
|
||||
\c{%$i} to be an offset from \c{BP}. A context-local variable is
|
||||
used, local to the context pushed by the \c{proc} macro and popped
|
||||
by the \c{endproc} macro, so that the same argument name can be used
|
||||
in later procedures. Of course, you don't \e{have} to do that.
|
||||
|
||||
\c{arg} can take an optional parameter, giving the size of the
|
||||
argument. If no size is given, 4 is assumed, since it is likely that
|
||||
many function parameters will be of type \c{int} or pointers.
|
||||
|
||||
|
||||
\H{picdll} Writing NetBSD/FreeBSD/OpenBSD and Linux/ELF \i{Shared
|
||||
Libraries}
|
||||
|
||||
\c{ELF} replaced the older \c{a.out} object file format under Linux
|
||||
because it contains support for \i{position-independent code}
|
||||
(\i{PIC}), which makes writing shared libraries much easier. NASM
|
||||
supports the \c{ELF} position-independent code features, so you can
|
||||
write Linux \c{ELF} shared libraries in NASM.
|
||||
|
||||
\i{NetBSD}, and its close cousins \i{FreeBSD} and \i{OpenBSD}, take
|
||||
a different approach by hacking PIC support into the \c{a.out}
|
||||
format. NASM supports this as the \i\c{aoutb} output format, so you
|
||||
can write \i{BSD} shared libraries in NASM too.
|
||||
|
||||
The operating system loads a PIC shared library by memory-mapping
|
||||
the library file at an arbitrarily chosen point in the address space
|
||||
of the running process. The contents of the library's code section
|
||||
must therefore not depend on where it is loaded in memory.
|
||||
|
||||
Therefore, you cannot get at your variables by writing code like
|
||||
this:
|
||||
|
||||
\c mov eax,[myvar] ; WRONG
|
||||
|
||||
Instead, the linker provides an area of memory called the
|
||||
\i\e{global offset table}, or \i{GOT}; the GOT is situated at a
|
||||
constant distance from your library's code, so if you can find out
|
||||
where your library is loaded (which is typically done using a
|
||||
\c{CALL} and \c{POP} combination), you can obtain the address of the
|
||||
GOT, and you can then load the addresses of your variables out of
|
||||
linker-generated entries in the GOT.
|
||||
|
||||
The \e{data} section of a PIC shared library does not have these
|
||||
restrictions: since the data section is writable, it has to be
|
||||
copied into memory anyway rather than just paged in from the library
|
||||
file, so as long as it's being copied it can be relocated too. So
|
||||
you can put ordinary types of relocation in the data section without
|
||||
too much worry (but see \k{picglobal} for a caveat).
|
||||
|
||||
|
||||
\S{picgot} Obtaining the Address of the GOT
|
||||
|
||||
Each code module in your shared library should define the GOT as an
|
||||
external symbol:
|
||||
|
||||
\c extern _GLOBAL_OFFSET_TABLE_ ; in ELF
|
||||
\c extern __GLOBAL_OFFSET_TABLE_ ; in BSD a.out
|
||||
|
||||
At the beginning of any function in your shared library which plans
|
||||
to access your data or BSS sections, you must first calculate the
|
||||
address of the GOT. This is typically done by writing the function
|
||||
in this form:
|
||||
|
||||
\c func: push ebp
|
||||
\c mov ebp,esp
|
||||
\c push ebx
|
||||
\c call .get_GOT
|
||||
\c .get_GOT:
|
||||
\c pop ebx
|
||||
\c add ebx,_GLOBAL_OFFSET_TABLE_+$$-.get_GOT wrt ..gotpc
|
||||
\c
|
||||
\c ; the function body comes here
|
||||
\c
|
||||
\c mov ebx,[ebp-4]
|
||||
\c mov esp,ebp
|
||||
\c pop ebp
|
||||
\c ret
|
||||
|
||||
(For BSD, again, the symbol \c{_GLOBAL_OFFSET_TABLE} requires a
|
||||
second leading underscore.)
|
||||
|
||||
The first two lines of this function are simply the standard C
|
||||
prologue to set up a stack frame, and the last three lines are
|
||||
standard C function epilogue. The third line, and the fourth to last
|
||||
line, save and restore the \c{EBX} register, because PIC shared
|
||||
libraries use this register to store the address of the GOT.
|
||||
|
||||
The interesting bit is the \c{CALL} instruction and the following
|
||||
two lines. The \c{CALL} and \c{POP} combination obtains the address
|
||||
of the label \c{.get_GOT}, without having to know in advance where
|
||||
the program was loaded (since the \c{CALL} instruction is encoded
|
||||
relative to the current position). The \c{ADD} instruction makes use
|
||||
of one of the special PIC relocation types: \i{GOTPC relocation}.
|
||||
With the \i\c{WRT ..gotpc} qualifier specified, the symbol
|
||||
referenced (here \c{_GLOBAL_OFFSET_TABLE_}, the special symbol
|
||||
assigned to the GOT) is given as an offset from the beginning of the
|
||||
section. (Actually, \c{ELF} encodes it as the offset from the operand
|
||||
field of the \c{ADD} instruction, but NASM simplifies this
|
||||
deliberately, so you do things the same way for both \c{ELF} and
|
||||
\c{BSD}.) So the instruction then \e{adds} the beginning of the section,
|
||||
to get the real address of the GOT, and subtracts the value of
|
||||
\c{.get_GOT} which it knows is in \c{EBX}. Therefore, by the time
|
||||
that instruction has finished, \c{EBX} contains the address of the GOT.
|
||||
|
||||
If you didn't follow that, don't worry: it's never necessary to
|
||||
obtain the address of the GOT by any other means, so you can put
|
||||
those three instructions into a macro and safely ignore them:
|
||||
|
||||
\c %macro get_GOT 0
|
||||
\c
|
||||
\c call %%getgot
|
||||
\c %%getgot:
|
||||
\c pop ebx
|
||||
\c add ebx,_GLOBAL_OFFSET_TABLE_+$$-%%getgot wrt ..gotpc
|
||||
\c
|
||||
\c %endmacro
|
||||
|
||||
\S{piclocal} Finding Your Local Data Items
|
||||
|
||||
Having got the GOT, you can then use it to obtain the addresses of
|
||||
your data items. Most variables will reside in the sections you have
|
||||
declared; they can be accessed using the \I{GOTOFF
|
||||
relocation}\c{..gotoff} special \I\c{WRT ..gotoff}\c{WRT} type. The
|
||||
way this works is like this:
|
||||
|
||||
\c lea eax,[ebx+myvar wrt ..gotoff]
|
||||
|
||||
The expression \c{myvar wrt ..gotoff} is calculated, when the shared
|
||||
library is linked, to be the offset to the local variable \c{myvar}
|
||||
from the beginning of the GOT. Therefore, adding it to \c{EBX} as
|
||||
above will place the real address of \c{myvar} in \c{EAX}.
|
||||
|
||||
If you declare variables as \c{GLOBAL} without specifying a size for
|
||||
them, they are shared between code modules in the library, but do
|
||||
not get exported from the library to the program that loaded it.
|
||||
They will still be in your ordinary data and BSS sections, so you
|
||||
can access them in the same way as local variables, using the above
|
||||
\c{..gotoff} mechanism.
|
||||
|
||||
Note that due to a peculiarity of the way BSD \c{a.out} format
|
||||
handles this relocation type, there must be at least one non-local
|
||||
symbol in the same section as the address you're trying to access.
|
||||
|
||||
|
||||
\S{picextern} Finding External and Common Data Items
|
||||
|
||||
If your library needs to get at an external variable (external to
|
||||
the \e{library}, not just to one of the modules within it), you must
|
||||
use the \I{GOT relocations}\I\c{WRT ..got}\c{..got} type to get at
|
||||
it. The \c{..got} type, instead of giving you the offset from the
|
||||
GOT base to the variable, gives you the offset from the GOT base to
|
||||
a GOT \e{entry} containing the address of the variable. The linker
|
||||
will set up this GOT entry when it builds the library, and the
|
||||
dynamic linker will place the correct address in it at load time. So
|
||||
to obtain the address of an external variable \c{extvar} in \c{EAX},
|
||||
you would code
|
||||
|
||||
\c mov eax,[ebx+extvar wrt ..got]
|
||||
|
||||
This loads the address of \c{extvar} out of an entry in the GOT. The
|
||||
linker, when it builds the shared library, collects together every
|
||||
relocation of type \c{..got}, and builds the GOT so as to ensure it
|
||||
has every necessary entry present.
|
||||
|
||||
Common variables must also be accessed in this way.
|
||||
|
||||
|
||||
\S{picglobal} Exporting Symbols to the Library User
|
||||
|
||||
If you want to export symbols to the user of the library, you have
|
||||
to declare whether they are functions or data, and if they are data,
|
||||
you have to give the size of the data item. This is because the
|
||||
dynamic linker has to build \I{PLT}\i{procedure linkage table}
|
||||
entries for any exported functions, and also moves exported data
|
||||
items away from the library's data section in which they were
|
||||
declared.
|
||||
|
||||
So to export a function to users of the library, you must use
|
||||
|
||||
\c global func:function ; declare it as a function
|
||||
\c
|
||||
\c func: push ebp
|
||||
\c
|
||||
\c ; etc.
|
||||
|
||||
And to export a data item such as an array, you would have to code
|
||||
|
||||
\c global array:data array.end-array ; give the size too
|
||||
\c
|
||||
\c array: resd 128
|
||||
\c .end:
|
||||
|
||||
Be careful: If you export a variable to the library user, by
|
||||
declaring it as \c{GLOBAL} and supplying a size, the variable will
|
||||
end up living in the data section of the main program, rather than
|
||||
in your library's data section, where you declared it. So you will
|
||||
have to access your own global variable with the \c{..got} mechanism
|
||||
rather than \c{..gotoff}, as if it were external (which,
|
||||
effectively, it has become).
|
||||
|
||||
Equally, if you need to store the address of an exported global in
|
||||
one of your data sections, you can't do it by means of the standard
|
||||
sort of code:
|
||||
|
||||
\c dataptr: dd global_data_item ; WRONG
|
||||
|
||||
NASM will interpret this code as an ordinary relocation, in which
|
||||
\c{global_data_item} is merely an offset from the beginning of the
|
||||
\c{.data} section (or whatever); so this reference will end up
|
||||
pointing at your data section instead of at the exported global
|
||||
which resides elsewhere.
|
||||
|
||||
Instead of the above code, then, you must write
|
||||
|
||||
\c dataptr: dd global_data_item wrt ..sym
|
||||
|
||||
which makes use of the special \c{WRT} type \I\c{WRT ..sym}\c{..sym}
|
||||
to instruct NASM to search the symbol table for a particular symbol
|
||||
at that address, rather than just relocating by section base.
|
||||
|
||||
Either method will work for functions: referring to one of your
|
||||
functions by means of
|
||||
|
||||
\c funcptr: dd my_function
|
||||
|
||||
will give the user the address of the code you wrote, whereas
|
||||
|
||||
\c funcptr: dd my_function wrt ..sym
|
||||
|
||||
will give the address of the procedure linkage table for the
|
||||
function, which is where the calling program will \e{believe} the
|
||||
function lives. Either address is a valid way to call the function.
|
||||
|
||||
|
||||
\S{picproc} Calling Procedures Outside the Library
|
||||
|
||||
Calling procedures outside your shared library has to be done by
|
||||
means of a \i\e{procedure linkage table}, or \i{PLT}. The PLT is
|
||||
placed at a known offset from where the library is loaded, so the
|
||||
library code can make calls to the PLT in a position-independent
|
||||
way. Within the PLT there is code to jump to offsets contained in
|
||||
the GOT, so function calls to other shared libraries or to routines
|
||||
in the main program can be transparently passed off to their real
|
||||
destinations.
|
||||
|
||||
To call an external routine, you must use another special PIC
|
||||
relocation type, \I{PLT relocations}\i\c{WRT ..plt}. This is much
|
||||
easier than the GOT-based ones: you simply replace calls such as
|
||||
\c{CALL printf} with the PLT-relative version \c{CALL printf WRT
|
||||
..plt}.
|
||||
|
||||
|
||||
\S{link} Generating the Library File
|
||||
|
||||
Having written some code modules and assembled them to \c{.o} files,
|
||||
you then generate your shared library with a command such as
|
||||
|
||||
\c ld -shared -o library.so module1.o module2.o # for ELF
|
||||
\c ld -Bshareable -o library.so module1.o module2.o # for BSD
|
||||
|
||||
For ELF, if your shared library is going to reside in system
|
||||
directories such as \c{/usr/lib} or \c{/lib}, it is usually worth
|
||||
using the \i\c{-soname} flag to the linker, to store the final
|
||||
library file name, with a version number, into the library:
|
||||
|
||||
\c ld -shared -soname library.so.1 -o library.so.1.2 *.o
|
||||
|
||||
You would then copy \c{library.so.1.2} into the library directory,
|
||||
and create \c{library.so.1} as a symbolic link to it.
|
||||
|
||||
|
183
doc/64bit.src
Normal file
183
doc/64bit.src
Normal file
|
@ -0,0 +1,183 @@
|
|||
\C{64bit} Writing 64-bit Code (Unix, Win64)
|
||||
|
||||
This chapter attempts to cover some of the common issues involved when
|
||||
writing 64-bit code, to run under \i{Win64} or Unix. It covers how to
|
||||
write assembly code to interface with 64-bit C routines, and how to
|
||||
write position-independent code for shared libraries.
|
||||
|
||||
All 64-bit code uses a flat memory model, since segmentation is not
|
||||
available in 64-bit mode. The one exception is the \c{FS} and \c{GS}
|
||||
registers, which still add their bases.
|
||||
|
||||
Position independence in 64-bit mode is significantly simpler, since
|
||||
the processor supports \c{RIP}-relative addressing directly; see the
|
||||
\c{REL} keyword (\k{effaddr}). On most 64-bit platforms, it is
|
||||
probably desirable to make that the default, using the directive
|
||||
\c{DEFAULT REL} (\k{default}).
|
||||
|
||||
64-bit programming is relatively similar to 32-bit programming, but
|
||||
of course pointers are 64 bits long; additionally, all existing
|
||||
platforms pass arguments in registers rather than on the stack.
|
||||
Furthermore, 64-bit platforms use SSE2 by default for floating point.
|
||||
Please see the ABI documentation for your platform.
|
||||
|
||||
64-bit platforms differ in the sizes of the C/C++ fundamental
|
||||
datatypes, not just from 32-bit platforms but from each other. If a
|
||||
specific size data type is desired, it is probably best to use the
|
||||
types defined in the standard C header \c{<inttypes.h>}.
|
||||
|
||||
All known 64-bit platforms except some embedded platforms require that
|
||||
the stack is 16-byte aligned at the entry to a function. In order to
|
||||
enforce that, the stack pointer (\c{RSP}) needs to be aligned on an
|
||||
\c{odd} multiple of 8 bytes before the \c{CALL} instruction.
|
||||
|
||||
In 64-bit mode, the default instruction size is still 32 bits. When
|
||||
loading a value into a 32-bit register (but not an 8- or 16-bit
|
||||
register), the upper 32 bits of the corresponding 64-bit register are
|
||||
set to zero.
|
||||
|
||||
\H{reg64} Register Names in 64-bit Mode
|
||||
|
||||
NASM uses the following names for general-purpose registers in 64-bit
|
||||
mode, for 8-, 16-, 32- and 64-bit references, respectively:
|
||||
|
||||
\c AL/AH, CL/CH, DL/DH, BL/BH, SPL, BPL, SIL, DIL, R8B-R15B
|
||||
\c AX, CX, DX, BX, SP, BP, SI, DI, R8W-R15W
|
||||
\c EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, R8D-R15D
|
||||
\c RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8-R15
|
||||
|
||||
This is consistent with the AMD documentation and most other
|
||||
assemblers. The Intel documentation, however, uses the names
|
||||
\c{R8L-R15L} for 8-bit references to the higher registers. It is
|
||||
possible to use those names by definiting them as macros; similarly,
|
||||
if one wants to use numeric names for the low 8 registers, define them
|
||||
as macros. The standard macro package \c{altreg} (see \k{pkg_altreg})
|
||||
can be used for this purpose.
|
||||
|
||||
\H{id64} Immediates and Displacements in 64-bit Mode
|
||||
|
||||
In 64-bit mode, immediates and displacements are generally only 32
|
||||
bits wide. NASM will therefore truncate most displacements and
|
||||
immediates to 32 bits.
|
||||
|
||||
The only instruction which takes a full \i{64-bit immediate} is:
|
||||
|
||||
\c MOV reg64,imm64
|
||||
|
||||
NASM will produce this instruction whenever the programmer uses
|
||||
\c{MOV} with an immediate into a 64-bit register. If this is not
|
||||
desirable, simply specify the equivalent 32-bit register, which will
|
||||
be automatically zero-extended by the processor, or specify the
|
||||
immediate as \c{DWORD}:
|
||||
|
||||
\c mov rax,foo ; 64-bit immediate
|
||||
\c mov rax,qword foo ; (identical)
|
||||
\c mov eax,foo ; 32-bit immediate, zero-extended
|
||||
\c mov rax,dword foo ; 32-bit immediate, sign-extended
|
||||
|
||||
The length of these instructions are 10, 5 and 7 bytes, respectively.
|
||||
|
||||
If optimization is enabled and NASM can determine at assembly time
|
||||
that a shorter instruction will suffice, the shorter instruction will
|
||||
be emitted unless of course \c{STRICT QWORD} or \c{STRICT DWORD} is
|
||||
specified (see \k{strict}):
|
||||
|
||||
\c mov rax,1 ; Assembles as "mov eax,1" (5 bytes)
|
||||
\c mov rax,strict qword 1 ; Full 10-byte instruction
|
||||
\c mov rax,strict dword 1 ; 7-byte instruction
|
||||
\c mov rax,symbol ; 10 bytes, not known at assembly time
|
||||
\c lea rax,[rel symbol] ; 7 bytes, usually preferred by the ABI
|
||||
|
||||
Note that \c{lea rax,[rel symbol]} is position-independent, whereas
|
||||
\c{mov rax,symbol} is not. Most ABIs prefer or even require
|
||||
position-independent code in 64-bit mode. However, the \c{MOV}
|
||||
instruction is able to reference a symbol anywhere in the 64-bit
|
||||
address space, whereas \c{LEA} is only able to access a symbol within
|
||||
within 2 GB of the instruction itself (see below.)
|
||||
|
||||
The only instructions which take a full \I{64-bit displacement}64-bit
|
||||
\e{displacement} is loading or storing, using \c{MOV}, \c{AL}, \c{AX},
|
||||
\c{EAX} or \c{RAX} (but no other registers) to an absolute 64-bit address.
|
||||
Since this is a relatively rarely used instruction (64-bit code generally uses
|
||||
relative addressing), the programmer has to explicitly declare the
|
||||
displacement size as \c{ABS QWORD}:
|
||||
|
||||
\c default abs
|
||||
\c
|
||||
\c mov eax,[foo] ; 32-bit absolute disp, sign-extended
|
||||
\c mov eax,[a32 foo] ; 32-bit absolute disp, zero-extended
|
||||
\c mov eax,[qword foo] ; 64-bit absolute disp
|
||||
\c
|
||||
\c default rel
|
||||
\c
|
||||
\c mov eax,[foo] ; 32-bit relative disp
|
||||
\c mov eax,[a32 foo] ; d:o, address truncated to 32 bits(!)
|
||||
\c mov eax,[qword foo] ; error
|
||||
\c mov eax,[abs qword foo] ; 64-bit absolute disp
|
||||
|
||||
A sign-extended absolute displacement can access from -2 GB to +2 GB;
|
||||
a zero-extended absolute displacement can access from 0 to 4 GB.
|
||||
|
||||
\H{unix64} Interfacing to 64-bit C Programs (Unix)
|
||||
|
||||
On Unix, the 64-bit ABI as well as the x32 ABI (32-bit ABI with the
|
||||
CPU in 64-bit mode) is defined by the documents at:
|
||||
|
||||
\W{https://www.nasm.us/abi/unix64}\c{https://www.nasm.us/abi/unix64}
|
||||
|
||||
Although written for AT&T-syntax assembly, the concepts apply equally
|
||||
well for NASM-style assembly. What follows is a simplified summary.
|
||||
|
||||
The first six integer arguments (from the left) are passed in \c{RDI},
|
||||
\c{RSI}, \c{RDX}, \c{RCX}, \c{R8}, and \c{R9}, in that order.
|
||||
Additional integer arguments are passed on the stack. These
|
||||
registers, plus \c{RAX}, \c{R10} and \c{R11} are destroyed by function
|
||||
calls, and thus are available for use by the function without saving.
|
||||
|
||||
Integer return values are passed in \c{RAX} and \c{RDX}, in that order.
|
||||
|
||||
Floating point is done using SSE registers, except for \c{long
|
||||
double}, which is 80 bits (\c{TWORD}) on most platforms (Android is
|
||||
one exception; there \c{long double} is 64 bits and treated the same
|
||||
as \c{double}.) Floating-point arguments are passed in \c{XMM0} to
|
||||
\c{XMM7}; return is \c{XMM0} and \c{XMM1}. \c{long double} are passed
|
||||
on the stack, and returned in \c{ST0} and \c{ST1}.
|
||||
|
||||
All SSE and x87 registers are destroyed by function calls.
|
||||
|
||||
On 64-bit Unix, \c{long} is 64 bits.
|
||||
|
||||
Integer and SSE register arguments are counted separately, so for the case of
|
||||
|
||||
\c void foo(long a, double b, int c)
|
||||
|
||||
\c{a} is passed in \c{RDI}, \c{b} in \c{XMM0}, and \c{c} in \c{ESI}.
|
||||
|
||||
\H{win64} Interfacing to 64-bit C Programs (Win64)
|
||||
|
||||
The Win64 ABI is described by the document at:
|
||||
|
||||
\W{https://www.nasm.us/abi/win64}\c{https://www.nasm.us/abi/win64}
|
||||
|
||||
What follows is a simplified summary.
|
||||
|
||||
The first four integer arguments are passed in \c{RCX}, \c{RDX},
|
||||
\c{R8} and \c{R9}, in that order. Additional integer arguments are
|
||||
passed on the stack. These registers, plus \c{RAX}, \c{R10} and
|
||||
\c{R11} are destroyed by function calls, and thus are available for
|
||||
use by the function without saving.
|
||||
|
||||
Integer return values are passed in \c{RAX} only.
|
||||
|
||||
Floating point is done using SSE registers, except for \c{long
|
||||
double}. Floating-point arguments are passed in \c{XMM0} to \c{XMM3};
|
||||
return is \c{XMM0} only.
|
||||
|
||||
On Win64, \c{long} is 32 bits; \c{long long} or \c{_int64} is 64 bits.
|
||||
|
||||
Integer and SSE register arguments are counted together, so for the case of
|
||||
|
||||
\c void foo(long long a, double b, int c)
|
||||
|
||||
\c{a} is passed in \c{RCX}, \c{b} in \c{XMM1}, and \c{c} in \c{R8D}.
|
||||
|
|
@ -40,8 +40,15 @@ XZFILES = @XZFILES@
|
|||
# Auxiliary files referenced by the HTML files
|
||||
HTMLAUX = nasmdoc.css local.css nasmlogw.png
|
||||
|
||||
SRCS = nasmdoc.src inslist.src changes.src \
|
||||
warnings.src version.src perlbreq.src
|
||||
# Generated input files
|
||||
GENSRC = insns.src version.src perlbreq.src
|
||||
|
||||
# Top-level input file
|
||||
SRCS = nasmdoc.src
|
||||
|
||||
# All input files (except auto-dependencies)
|
||||
ALLSRCS = $(SRCS) $(GENSRC)
|
||||
|
||||
OUT = html nasmdoc.txt nasmdoc.pdf $(XZFILES)
|
||||
XZOUT = nasmdoc.pdf.xz
|
||||
|
||||
|
@ -60,25 +67,25 @@ all: $(OUT)
|
|||
|
||||
xzfiles: $(XZOUT)
|
||||
|
||||
inslist.src: inslist.pl ../x86/insns.dat
|
||||
$(RUNPERL) $^
|
||||
insns.src: inslist.pl ../x86/insns.dat
|
||||
$(RUNPERL) $^ $@
|
||||
|
||||
html: $(HTMLAUX)
|
||||
$(MKDIR_P) html
|
||||
for f in $(HTMLAUX); do $(CP_UF) "$(srcdir)/$$f" html/; done
|
||||
$(MAKE) html/nasmdoc0.html
|
||||
|
||||
RDSRC = $(RUNPERL) $(srcdir)/rdsrc.pl -I$(srcdir)/
|
||||
RDSRC = $(RUNPERL) $(srcdir)/rdsrc.pl -I$(srcdir) -M$(@F).dep
|
||||
|
||||
html/nasmdoc0.html: $(SRCS) rdsrc.pl
|
||||
html/nasmdoc0.html: $(ALLSRCS) rdsrc.pl
|
||||
$(RM_F) html/*.html
|
||||
$(RDSRC) -ohtml html nasmdoc.src
|
||||
$(RDSRC) -ohtml html $<
|
||||
|
||||
nasmdoc.dip: $(SRCS) rdsrc.pl
|
||||
$(RDSRC) dip nasmdoc.src
|
||||
nasmdoc.dip: $(ALLSRCS) rdsrc.pl
|
||||
$(RDSRC) dip $<
|
||||
|
||||
nasmdoc.txt: $(SRCS) rdsrc.pl
|
||||
$(RDSRC) txt nasmdoc.src
|
||||
nasmdoc.txt: $(ALLSRCS) rdsrc.pl
|
||||
$(RDSRC) txt $<
|
||||
|
||||
version.src: $(top_srcdir)/version.pl $(top_srcdir)/version
|
||||
$(RUNPERL) $(top_srcdir)/version.pl docsrc \
|
||||
|
@ -113,7 +120,7 @@ nasmdoc.pdf.xz: nasmdoc-raw.pdf
|
|||
clean:
|
||||
-$(RM_F) *.rtf *.hpj *.texi *.gid *.ipf *.dip
|
||||
-$(RM_F) *.aux *.cp *.fn *.ky *.pg *.log *.toc *.tp *.vr
|
||||
-$(RM_F) inslist.src version.src perlbreq.src fontpath Fontmap
|
||||
-$(RM_F) $(GENSRC)fontpath Fontmap
|
||||
-$(RM_F) nasmdoc*.ps nasmdoc-raw.pdf
|
||||
|
||||
spotless: clean
|
||||
|
@ -133,3 +140,6 @@ install: all
|
|||
.SECONDARY:
|
||||
|
||||
.DELETE_ON_ERROR:
|
||||
|
||||
# Generated dependencies
|
||||
-include *.dep
|
||||
|
|
4
doc/changelog.src
Normal file
4
doc/changelog.src
Normal file
|
@ -0,0 +1,4 @@
|
|||
\A{changelog} \i{NASM Version History}
|
||||
|
||||
\& changes.src
|
||||
|
108
doc/contact.src
Normal file
108
doc/contact.src
Normal file
|
@ -0,0 +1,108 @@
|
|||
\A{contact} Contact Information
|
||||
|
||||
\H{website} Website
|
||||
|
||||
NASM has a \i{website} at
|
||||
\w{https://www.nasm.us/}.
|
||||
|
||||
\i{New releases}, \i{release candidates}, and \I{snapshots, daily
|
||||
development}\i{daily development snapshots} of NASM are available from
|
||||
the official web site in source form as well as binaries for a number
|
||||
of common platforms.
|
||||
|
||||
\S{forums} User Forums
|
||||
|
||||
Users of NASM may find the Forums on the website useful. These are,
|
||||
however, not frequented much by the developers of NASM, so they are
|
||||
not suitable for reporting bugs.
|
||||
|
||||
\S{develcom} Development Community
|
||||
|
||||
The development of NASM is coordinated primarily though the
|
||||
\i\c{nasm-devel} mailing list. If you wish to participate in
|
||||
development of NASM, please join this mailing list. Subscription
|
||||
links and archives of past posts are available on the website.
|
||||
|
||||
\H{bugs} \i{Reporting Bugs}\I{bugs}
|
||||
|
||||
To report bugs in NASM, please use the \i{bug tracker} at
|
||||
\w{https://www.nasm.us/} (click on "Bug
|
||||
Tracker"), or if that fails then through one of the contacts in
|
||||
\k{website}.
|
||||
|
||||
Please read \k{qstart} first, and don't report the bug if it's
|
||||
listed in there as a deliberate feature. (If you think the feature
|
||||
is badly thought out, feel free to send us reasons why you think it
|
||||
should be changed, but don't just send us mail saying `This is a
|
||||
bug' if the documentation says we did it on purpose.) Then read
|
||||
\k{problems}, and don't bother reporting the bug if it's listed
|
||||
there.
|
||||
|
||||
If you do report a bug, \e{please} make sure your bug report includes
|
||||
the following information:
|
||||
|
||||
\b What operating system you're running NASM under. Linux,
|
||||
FreeBSD, NetBSD, MacOS X, Win16, Win32, Win64, MS-DOS, OS/2, VMS,
|
||||
whatever.
|
||||
|
||||
\b If you compiled your own executable from a source archive, compiled
|
||||
your own executable from \c{git}, used the standard distribution
|
||||
binaries from the website, or got an executable from somewhere else
|
||||
(e.g. a Linux distribution.) If you were using a locally built
|
||||
executable, try to reproduce the problem using one of the standard
|
||||
binaries, as this will make it easier for us to reproduce your problem
|
||||
prior to fixing it.
|
||||
|
||||
\b Which version of NASM you're using, and exactly how you invoked
|
||||
it. Give us the precise command line, and the contents of the
|
||||
\c{NASMENV} environment variable if any.
|
||||
|
||||
\b Which versions of any supplementary programs you're using, and
|
||||
how you invoked them. If the problem only becomes visible at link
|
||||
time, tell us what linker you're using, what version of it you've
|
||||
got, and the exact linker command line. If the problem involves
|
||||
linking against object files generated by a compiler, tell us what
|
||||
compiler, what version, and what command line or options you used.
|
||||
(If you're compiling in an IDE, please try to reproduce the problem
|
||||
with the command-line version of the compiler.)
|
||||
|
||||
\b If at all possible, send us a NASM source file which exhibits the
|
||||
problem. If this causes copyright problems (e.g. you can only
|
||||
reproduce the bug in restricted-distribution code) then bear in mind
|
||||
the following two points: firstly, we guarantee that any source code
|
||||
sent to us for the purposes of debugging NASM will be used \e{only}
|
||||
for the purposes of debugging NASM, and that we will delete all our
|
||||
copies of it as soon as we have found and fixed the bug or bugs in
|
||||
question; and secondly, we would prefer \e{not} to be mailed large
|
||||
chunks of code anyway. The smaller the file, the better. A
|
||||
three-line sample file that does nothing useful \e{except}
|
||||
demonstrate the problem is much easier to work with than a
|
||||
fully fledged ten-thousand-line program. (Of course, some errors
|
||||
\e{do} only crop up in large files, so this may not be possible.)
|
||||
|
||||
\b A description of what the problem actually \e{is}. `It doesn't
|
||||
work' is \e{not} a helpful description! Please describe exactly what
|
||||
is happening that shouldn't be, or what isn't happening that should.
|
||||
Examples might be: `NASM generates an error message saying Line 3
|
||||
for an error that's actually on Line 5'; `NASM generates an error
|
||||
message that I believe it shouldn't be generating at all'; `NASM
|
||||
fails to generate an error message that I believe it \e{should} be
|
||||
generating'; `the object file produced from this source code crashes
|
||||
my linker'; `the ninth byte of the output file is 66 and I think it
|
||||
should be 77 instead'.
|
||||
|
||||
\b If you believe the output file from NASM to be faulty, send it to
|
||||
us. That allows us to determine whether our own copy of NASM
|
||||
generates the same file, or whether the problem is related to
|
||||
portability issues between our development platforms and yours. We
|
||||
can handle binary files mailed to us as MIME attachments, uuencoded,
|
||||
and even BinHex. Alternatively, we may be able to provide an FTP
|
||||
site you can upload the suspect files to; but mailing them is easier
|
||||
for us.
|
||||
|
||||
\b Any other information or data files that might be helpful. If,
|
||||
for example, the problem involves NASM failing to generate an object
|
||||
file while TASM can generate an equivalent file without trouble,
|
||||
then send us \e{both} object files, so we can see what TASM is doing
|
||||
differently from us.
|
||||
|
563
doc/directiv.src
Normal file
563
doc/directiv.src
Normal file
|
@ -0,0 +1,563 @@
|
|||
\C{directive} \i{Assembler Directives}
|
||||
|
||||
NASM, though it attempts to avoid the bureaucracy of assemblers like
|
||||
MASM and TASM, is nevertheless forced to support a \e{few}
|
||||
directives. These are described in this chapter.
|
||||
|
||||
NASM's directives come in two types: \I{user-level
|
||||
directives}\e{user-level} directives and \I{primitive
|
||||
directives}\e{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
|
||||
\I{format-specific directives}\e{format-specific} directives are
|
||||
documented along with the formats that implement them, in \k{outfmt}.
|
||||
|
||||
|
||||
\H{bits} \i\c{BITS}: Target \i{Processor Mode}
|
||||
|
||||
The \c{BITS} directive specifies whether NASM should generate code
|
||||
\I{16-bit mode, versus 32-bit mode}designed to run on a processor
|
||||
operating in 16-bit mode, 32-bit mode or 64-bit mode. The syntax is
|
||||
\c{BITS XX}, where XX is 16, 32 or 64.
|
||||
|
||||
In most cases, you should not need to use \c{BITS} explicitly. The
|
||||
\c{aout}, \c{coff}, \c{elf*}, \c{macho}, \c{win32} and \c{win64}
|
||||
object formats, which are designed for use in 32-bit or 64-bit
|
||||
operating systems, all cause NASM to select 32-bit or 64-bit mode,
|
||||
respectively, by default. The \c{obj} object format allows you
|
||||
to specify each segment you define as either \c{USE16} or \c{USE32},
|
||||
and NASM will set its operating mode accordingly, so the use of the
|
||||
\c{BITS} directive is once again unnecessary.
|
||||
|
||||
The most likely reason for using the \c{BITS} directive is to write
|
||||
32-bit or 64-bit code in a flat binary file; this is because the \c{bin}
|
||||
output format defaults to 16-bit mode in anticipation of it being
|
||||
used most frequently to write DOS \c{.COM} programs, DOS \c{.SYS}
|
||||
device drivers and boot loader software.
|
||||
|
||||
The \c{BITS} directive can also be used to generate code for a
|
||||
different mode than the standard one for the output format.
|
||||
|
||||
You do \e{not} need to specify \c{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.
|
||||
|
||||
When NASM is in \c{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 \c{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 on 16-bit addresses
|
||||
need an 0x67.
|
||||
|
||||
When NASM is in \c{BITS 64} mode, most instructions operate the same
|
||||
as they do for \c{BITS 32} mode. However, there are 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 \c{REX}
|
||||
prefix is used both to select 64-bit operand size, and to access the
|
||||
new registers. NASM automatically inserts REX prefixes when
|
||||
necessary.
|
||||
|
||||
When the \c{REX} prefix is used, the processor does not know how to
|
||||
address the AH, BH, CH or DH (high 8-bit legacy) registers. Instead,
|
||||
it is possible to access the the low 8-bits of the SP, BP SI and DI
|
||||
registers as SPL, BPL, SIL and DIL, respectively; but only when the
|
||||
REX prefix is used.
|
||||
|
||||
The \c{BITS} directive has an exactly equivalent primitive form,
|
||||
\c{[BITS 16]}, \c{[BITS 32]} and \c{[BITS 64]}. The user-level form is
|
||||
a macro which has no function other than to call the primitive form.
|
||||
|
||||
Note that the space is necessary, e.g. \c{BITS32} will \e{not} work!
|
||||
|
||||
\S{USE16 & USE32} \i\c{USE16} & \i\c{USE32}: Aliases for BITS
|
||||
|
||||
The `\c{USE16}' and `\c{USE32}' directives can be used in place of
|
||||
`\c{BITS 16}' and `\c{BITS 32}', for compatibility with other assemblers.
|
||||
|
||||
|
||||
\H{default} \i\c{DEFAULT}: Change the assembler defaults
|
||||
|
||||
The \c{DEFAULT} directive changes the assembler defaults. Normally,
|
||||
NASM defaults to a mode where the programmer is expected to explicitly
|
||||
specify most features directly. However, this is occasionally
|
||||
obnoxious, as the explicit form is pretty much the only one one wishes
|
||||
to use.
|
||||
|
||||
Currently, \c{DEFAULT} can set \c{REL} & \c{ABS} and \c{BND} & \c{NOBND}.
|
||||
|
||||
\S{REL & ABS} \i\c{REL} & \i\c{ABS}: RIP-relative addressing
|
||||
|
||||
This sets whether registerless instructions in 64-bit mode are \c{RIP}-relative
|
||||
or not. By default, they are absolute unless overridden with the \i\c{REL}
|
||||
specifier (see \k{effaddr}). However, if \c{DEFAULT REL} is
|
||||
specified, \c{REL} is default, unless overridden with the \c{ABS}
|
||||
specifier, \e{except when used with an FS or GS segment override}.
|
||||
|
||||
The special handling of \c{FS} and \c{GS} overrides are due to the
|
||||
fact that these registers are generally used as thread pointers or
|
||||
other special functions in 64-bit mode, and generating
|
||||
\c{RIP}-relative addresses would be extremely confusing.
|
||||
|
||||
\c{DEFAULT REL} is disabled with \c{DEFAULT ABS}.
|
||||
|
||||
\S{BND & NOBND} \i\c{BND} & \i\c{NOBND}: \c{BND} prefix
|
||||
|
||||
If \c{DEFAULT BND} is set, all bnd-prefix available instructions following
|
||||
this directive are prefixed with bnd. To override it, \c{NOBND} prefix can
|
||||
be used.
|
||||
|
||||
\c DEFAULT BND
|
||||
\c call foo ; BND will be prefixed
|
||||
\c nobnd call foo ; BND will NOT be prefixed
|
||||
|
||||
\c{DEFAULT NOBND} can disable \c{DEFAULT BND} and then \c{BND} prefix will be
|
||||
added only when explicitly specified in code.
|
||||
|
||||
\c{DEFAULT BND} is expected to be the normal configuration for writing
|
||||
MPX-enabled code.
|
||||
|
||||
\H{section} \i\c{SECTION} or \i\c{SEGMENT}: Changing and \i{Defining
|
||||
Sections}
|
||||
|
||||
\I{changing sections}\I{switching between sections}The \c{SECTION}
|
||||
directive (\c{SEGMENT} is an exactly equivalent synonym) changes
|
||||
which section of the output file the code you write will be
|
||||
assembled into. In some object file formats, the number and names of
|
||||
sections are fixed; in others, the user may make up as many as they
|
||||
wish. Hence \c{SECTION} may sometimes give an error message, or may
|
||||
define a new section, if you try to switch to a section that does
|
||||
not (yet) exist.
|
||||
|
||||
The Unix object formats, and the \c{bin} object format (but see
|
||||
\k{multisec}), all support
|
||||
the \i{standardized section names} \c{.text}, \c{.data} and \c{.bss}
|
||||
for the code, data and uninitialized-data sections. The \c{obj}
|
||||
format, by contrast, does not recognize these section names as being
|
||||
special, and indeed will strip off the leading period of any section
|
||||
name that has one.
|
||||
|
||||
|
||||
\S{sectmac} The \i\c{__?SECT?__} Macro
|
||||
|
||||
The \c{SECTION} directive is unusual in that its user-level form
|
||||
functions differently from its primitive form. The primitive form,
|
||||
\c{[SECTION xyz]}, simply switches the current target section to the
|
||||
one given. The user-level form, \c{SECTION xyz}, however, first
|
||||
defines the single-line macro \c{__?SECT?__} to be the primitive
|
||||
\c{[SECTION]} directive which it is about to issue, and then issues
|
||||
it. So the user-level directive
|
||||
|
||||
\c SECTION .text
|
||||
|
||||
expands to the two lines
|
||||
|
||||
\c %define __?SECT?__ [SECTION .text]
|
||||
\c [SECTION .text]
|
||||
|
||||
Users may find it useful to make use of this in their own macros.
|
||||
For example, the \c{writefile} macro defined in \k{mlmacgre} can be
|
||||
usefully rewritten in the following more sophisticated form:
|
||||
|
||||
\c %macro writefile 2+
|
||||
\c
|
||||
\c [section .data]
|
||||
\c
|
||||
\c %%str: db %2
|
||||
\c %%endstr:
|
||||
\c
|
||||
\c __?SECT?__
|
||||
\c
|
||||
\c mov dx,%%str
|
||||
\c mov cx,%%endstr-%%str
|
||||
\c mov bx,%1
|
||||
\c mov ah,0x40
|
||||
\c int 0x21
|
||||
\c
|
||||
\c %endmacro
|
||||
|
||||
This form of the macro, once passed a string to output, first
|
||||
switches temporarily to the data section of the file, using the
|
||||
primitive form of the \c{SECTION} directive so as not to modify
|
||||
\c{__?SECT?__}. It then declares its string in the data section, and
|
||||
then invokes \c{__?SECT?__} to switch back to \e{whichever} section
|
||||
the user was previously working in. It thus avoids the need, in the
|
||||
previous version of the macro, to include a \c{JMP} instruction to
|
||||
jump over the data, and also does not fail if, in a complicated
|
||||
\c{OBJ} format module, the user could potentially be assembling the
|
||||
code in any of several separate code sections.
|
||||
|
||||
|
||||
\H{absolute} \i\c{ABSOLUTE}: Defining Absolute Labels
|
||||
|
||||
The \c{ABSOLUTE} directive can be thought of as an alternative form
|
||||
of \c{SECTION}: it causes the subsequent code to be directed at no
|
||||
physical section, but at the hypothetical section starting at the
|
||||
given absolute address. The only instructions you can use in this
|
||||
mode are the \c{RESB} family.
|
||||
|
||||
\c{ABSOLUTE} is used as follows:
|
||||
|
||||
\c absolute 0x1A
|
||||
\c
|
||||
\c kbuf_chr resw 1
|
||||
\c kbuf_free resw 1
|
||||
\c kbuf resw 16
|
||||
|
||||
This example describes a section of the PC BIOS data area, at
|
||||
segment address 0x40: the above code defines \c{kbuf_chr} to be
|
||||
0x1A, \c{kbuf_free} to be 0x1C, and \c{kbuf} to be 0x1E.
|
||||
|
||||
The user-level form of \c{ABSOLUTE}, like that of \c{SECTION},
|
||||
redefines the \i\c{__?SECT?__} macro when it is invoked.
|
||||
|
||||
\i\c{STRUC} and \i\c{ENDSTRUC} are defined as macros which use
|
||||
\c{ABSOLUTE} (and also \c{__?SECT?__}).
|
||||
|
||||
\c{ABSOLUTE} doesn't have to take an absolute constant as an
|
||||
argument: it can take an expression (actually, a \i{critical
|
||||
expression}: see \k{crit}) and it can be a value in a segment. For
|
||||
example, a TSR can re-use its setup code as run-time BSS like this:
|
||||
|
||||
\c org 100h ; it's a .COM program
|
||||
\c
|
||||
\c jmp setup ; setup code comes last
|
||||
\c
|
||||
\c ; the resident part of the TSR goes here
|
||||
\c setup:
|
||||
\c ; now write the code that installs the TSR here
|
||||
\c
|
||||
\c absolute setup
|
||||
\c
|
||||
\c runtimevar1 resw 1
|
||||
\c runtimevar2 resd 20
|
||||
\c
|
||||
\c tsr_end:
|
||||
|
||||
This defines some variables `on top of' the setup code, so that
|
||||
after the setup has finished running, the space it took up can be
|
||||
re-used as data storage for the running TSR. The symbol `tsr_end'
|
||||
can be used to calculate the total size of the part of the TSR that
|
||||
needs to be made resident.
|
||||
|
||||
|
||||
\H{extern} \i\c{EXTERN}: \i{Importing Symbols} from Other Modules
|
||||
|
||||
\c{EXTERN} is similar to the MASM directive \c{EXTRN} and the C
|
||||
keyword \c{extern}: it is used to declare a symbol which is not
|
||||
defined anywhere in the module being assembled, but is assumed to be
|
||||
defined in some other module and needs to be referred to by this
|
||||
one. Not every object-file format can support external variables:
|
||||
the \c{bin} format cannot.
|
||||
|
||||
The \c{EXTERN} directive takes as many arguments as you like. Each
|
||||
argument is the name of a symbol:
|
||||
|
||||
\c extern _printf
|
||||
\c extern _sscanf,_fscanf
|
||||
|
||||
Some object-file formats provide extra features to the \c{EXTERN}
|
||||
directive. In all cases, the extra features are used by suffixing a
|
||||
colon to the symbol name followed by object-format specific text.
|
||||
For example, the \c{obj} format allows you to declare that the
|
||||
default segment base of an external should be the group \c{dgroup}
|
||||
by means of the directive
|
||||
|
||||
\c extern _variable:wrt dgroup
|
||||
|
||||
The primitive form of \c{EXTERN} differs from the user-level form
|
||||
only in that it can take only one argument at a time: the support
|
||||
for multiple arguments is implemented at the preprocessor level.
|
||||
|
||||
You can declare the same variable as \c{EXTERN} more than once: NASM
|
||||
will quietly ignore the second and later redeclarations.
|
||||
|
||||
If a variable is declared both \c{GLOBAL} and \c{EXTERN}, or if it is
|
||||
declared as \c{EXTERN} and then defined, it will be treated as
|
||||
\c{GLOBAL}. If a variable is declared both as \c{COMMON} and
|
||||
\c{EXTERN}, it will be treated as \c{COMMON}.
|
||||
|
||||
|
||||
\H{required} \i\c{REQUIRED}: \i{Unconditionally Importing Symbols} from Other Modules
|
||||
|
||||
The \c{REQUIRED} keyword is similar to \c{EXTERN} one. The difference
|
||||
is that the \c{EXTERN} keyword as of version 2.15 does not generate
|
||||
unknown symbols as that prevents using common header files, as it
|
||||
might cause the linker to pull in a bunch of unnecessary modules.
|
||||
|
||||
If the old behavior is required, use \c{REQUIRED} keyword instead.
|
||||
|
||||
|
||||
\H{global} \i\c{GLOBAL}: \i{Exporting Symbols} to Other Modules
|
||||
|
||||
\c{GLOBAL} is the other end of \c{EXTERN}: if one module declares a
|
||||
symbol as \c{EXTERN} and refers to it, then in order to prevent
|
||||
linker errors, some other module must actually \e{define} the
|
||||
symbol and declare it as \c{GLOBAL}. Some assemblers use the name
|
||||
\i\c{PUBLIC} for this purpose.
|
||||
|
||||
\c{GLOBAL} uses the same syntax as \c{EXTERN}, except that it must
|
||||
refer to symbols which \e{are} defined in the same module as the
|
||||
\c{GLOBAL} directive. For example:
|
||||
|
||||
\c global _main
|
||||
\c _main:
|
||||
\c ; some code
|
||||
|
||||
\c{GLOBAL}, like \c{EXTERN}, allows object formats to define private
|
||||
extensions by means of a colon. The ELF object format, for example,
|
||||
lets you specify whether global data items are functions or data:
|
||||
|
||||
\c global hashlookup:function, hashtable:data
|
||||
|
||||
Like \c{EXTERN}, the primitive form of \c{GLOBAL} differs from the
|
||||
user-level form only in that it can take only one argument at a
|
||||
time.
|
||||
|
||||
|
||||
\H{common} \i\c{COMMON}: Defining Common Data Areas
|
||||
|
||||
The \c{COMMON} directive is used to declare \i\e{common variables}.
|
||||
A common variable is much like a global variable declared in the
|
||||
uninitialized data section, so that
|
||||
|
||||
\c common intvar 4
|
||||
|
||||
is similar in function to
|
||||
|
||||
\c global intvar
|
||||
\c section .bss
|
||||
\c
|
||||
\c intvar resd 1
|
||||
|
||||
The difference is that if more than one module defines the same
|
||||
common variable, then at link time those variables will be
|
||||
\e{merged}, and references to \c{intvar} in all modules will point
|
||||
at the same piece of memory.
|
||||
|
||||
Like \c{GLOBAL} and \c{EXTERN}, \c{COMMON} supports object-format
|
||||
specific extensions. For example, the \c{obj} format allows common
|
||||
variables to be NEAR or FAR, and the ELF format allows you to specify
|
||||
the alignment requirements of a common variable:
|
||||
|
||||
\c common commvar 4:near ; works in OBJ
|
||||
\c common intarray 100:4 ; works in ELF: 4 byte aligned
|
||||
|
||||
Once again, like \c{EXTERN} and \c{GLOBAL}, the primitive form of
|
||||
\c{COMMON} differs from the user-level form only in that it can take
|
||||
only one argument at a time.
|
||||
|
||||
\H{static} \i\c{STATIC}: Local Symbols within Modules
|
||||
|
||||
Opposite to \c{EXTERN} and \c{GLOBAL}, \c{STATIC} is local symbol, but
|
||||
should be named according to the global mangling rules (named by
|
||||
analogy with the C keyword \c{static} as applied to functions or
|
||||
global variables).
|
||||
|
||||
\c static foo
|
||||
\c foo:
|
||||
\c ; codes
|
||||
|
||||
Unlike \c{GLOBAL}, \c{STATIC} does not allow object formats to accept
|
||||
private extensions mentioned in \k{global}.
|
||||
|
||||
\H{mangling} \i\c{(G|L)PREFIX}, \i\c{(G|L)POSTFIX}: Mangling Symbols
|
||||
|
||||
\c{PREFIX}, \c{GPREFIX}, \c{LPREFIX}, \c{POSTFIX}, \c{GPOSTFIX}, and
|
||||
\c{LPOSTFIX} directives can prepend or append a string to a certain
|
||||
type of symbols, normally to fit specific ABI conventions
|
||||
|
||||
\b\c{PREFIX}|\c{GPREFIX}: Prepend the argument to all \c{EXTERN},
|
||||
\c{COMMON}, \c{STATIC}, and \c{GLOBAL} symbols.
|
||||
|
||||
\b\c{LPREFIX}: Prepend the argument to all other symbols
|
||||
such as local labels and backend defined symbols.
|
||||
|
||||
\b\c{POSTFIX}|\c{GPOSTFIX}: Append the argument to all \c{EXTERN},
|
||||
\c{COMMON}, \c{STATIC}, and \c{GLOBAL} symbols.
|
||||
|
||||
\b\c{LPOSTFIX}: Append the argument to all other symbols
|
||||
such as local labels and backend defined symbols.
|
||||
|
||||
These are macros implemented as pragmas, and using \c{%pragma} syntax
|
||||
can be restricted to specific backends (see \k{pragma}):
|
||||
|
||||
\c %pragma macho lprefix L_
|
||||
|
||||
Command line options are also available. See also \k{opt-pfix}.
|
||||
|
||||
One example which supports many ABIs:
|
||||
|
||||
\c ; The most common conventions
|
||||
\c %pragma output gprefix _
|
||||
\c %pragma output lprefix L_
|
||||
\c ; ELF uses a different convention
|
||||
\c %pragma elf gprefix ; empty
|
||||
\c %pragma elf lprefix .L
|
||||
|
||||
Some toolchains is aware of a particular prefix for its own
|
||||
optimization options, such as dead code elimination. For instance, the
|
||||
Mach-O binary format has a linker convention that uses a simplistic
|
||||
naming scheme to chunk up sections into smaller subsections, each of
|
||||
which may be eliminated. When the \c{subsections_via_symbols}
|
||||
directive (\k{macho-ssvs}) is declared, each symbol is the start of a
|
||||
separate block. The subsection is, then, defined to include sections
|
||||
before the one that starts with a 'L'. \c{LPREFIX} is useful here to
|
||||
mark all local symbols with the 'L' prefix to be excluded to the meta
|
||||
section. It converts local symbols compatible with the particular
|
||||
toolchain. Note that local symbols declared with \c{STATIC}
|
||||
(\k{static}) are excluded from the symbol mangling and also not marked
|
||||
as global.
|
||||
|
||||
|
||||
\H{CPU} \i\c{CPU}: Defining CPU Dependencies
|
||||
|
||||
The \i\c{CPU} directive restricts assembly to those instructions which
|
||||
are available on the specified CPU. At the moment, it is primarily
|
||||
used to enforce unavailable \e{encodings} of instructions, such as
|
||||
5-byte jumps on the 8080.
|
||||
|
||||
(If someone would volunteer to work through the database and add
|
||||
proper annotations to each instruction, this could be greatly
|
||||
improved. Please contact the developers to volunteer, see \k{contact}.)
|
||||
|
||||
Current CPU keywords are:
|
||||
|
||||
\b\c{CPU 8086} - Assemble only 8086 instruction set
|
||||
|
||||
\b\c{CPU 186} - Assemble instructions up to the 80186 instruction set
|
||||
|
||||
\b\c{CPU 286} - Assemble instructions up to the 286 instruction set
|
||||
|
||||
\b\c{CPU 386} - Assemble instructions up to the 386 instruction set
|
||||
|
||||
\b\c{CPU 486} - 486 instruction set
|
||||
|
||||
\b\c{CPU 586} - Pentium instruction set
|
||||
|
||||
\b\c{CPU PENTIUM} - Same as 586
|
||||
|
||||
\b\c{CPU 686} - P6 instruction set
|
||||
|
||||
\b\c{CPU PPRO} - Same as 686
|
||||
|
||||
\b\c{CPU P2} - Same as 686
|
||||
|
||||
\b\c{CPU P3} - Pentium III (Katmai) instruction sets
|
||||
|
||||
\b\c{CPU KATMAI} - Same as P3
|
||||
|
||||
\b\c{CPU P4} - Pentium 4 (Willamette) instruction set
|
||||
|
||||
\b\c{CPU WILLAMETTE} - Same as P4
|
||||
|
||||
\b\c{CPU PRESCOTT} - Prescott instruction set
|
||||
|
||||
\b\c{CPU X64} - x86-64 (x64/AMD64/Intel 64) instruction set
|
||||
|
||||
\b\c{CPU IA64} - IA64 CPU (in x86 mode) instruction set
|
||||
|
||||
\b\c{CPU DEFAULT} - All available instructions
|
||||
|
||||
\b\c{CPU ALL} - All available instructions \e{and flags}
|
||||
|
||||
All options are case insensitive.
|
||||
|
||||
In addition, optional flags can be specified to modify the instruction
|
||||
selections. These can be combined with a CPU declaration or specified
|
||||
alone. They can be prefixed by \c{+} (add flag, default), \c{-}
|
||||
(remove flag) or \c{*} (set flag to default); these prefixes are
|
||||
"sticky", so:
|
||||
|
||||
\c cpu -foo,bar
|
||||
|
||||
means remove both the \c{foo} and \c{bar} options.
|
||||
|
||||
If prefixed with \c{no}, it inverts the meaning of the flag, but this
|
||||
is not sticky, so:
|
||||
|
||||
\c cpu nofoo,bar
|
||||
|
||||
means remove the \c{foo} flag but add the \c{bar} flag.
|
||||
|
||||
Currently available flags are:
|
||||
|
||||
\b\c{EVEX} - Enable generation of EVEX (AVX-512) encoded instructions
|
||||
without an explicit \c{\{evex\}} prefix. Default on.
|
||||
|
||||
\b\c\{VEX} - Enable generation of VEX (AVX) or XOP encoded
|
||||
instructions without an explict \c{\{vex\}} prefix. Default on.
|
||||
|
||||
\b\c{LATEVEX} - Enable generation of VEX (AVX) encoding of
|
||||
instructions where the VEX instructions forms were introduced
|
||||
\e{after} the corresponding EVEX (AVX-512) instruction forms without
|
||||
requiring an explicit \c{\{vex\}} prefix. This is implicit if the
|
||||
\c{EVEX} flag is disabled and the \c{VEX} flag is enabled. Default
|
||||
off.
|
||||
|
||||
|
||||
\H{FLOAT} \i\c{FLOAT}: Handling of \I{floating-point, constants}floating-point constants
|
||||
|
||||
By default, floating-point constants are rounded to nearest, and IEEE
|
||||
denormals are supported. The following options can be set to alter
|
||||
this behaviour:
|
||||
|
||||
\b\c{FLOAT DAZ} - Flush denormals to zero
|
||||
|
||||
\b\c{FLOAT NODAZ} - Do not flush denormals to zero (default)
|
||||
|
||||
\b\c{FLOAT NEAR} - Round to nearest (default)
|
||||
|
||||
\b\c{FLOAT UP} - Round up (toward +Infinity)
|
||||
|
||||
\b\c{FLOAT DOWN} - Round down (toward -Infinity)
|
||||
|
||||
\b\c{FLOAT ZERO} - Round toward zero
|
||||
|
||||
\b\c{FLOAT DEFAULT} - Restore default settings
|
||||
|
||||
The standard macros \i\c{__?FLOAT_DAZ?__}, \i\c{__?FLOAT_ROUND?__}, and
|
||||
\i\c{__?FLOAT?__} contain the current state, as long as the programmer
|
||||
has avoided the use of the brackeded primitive form, (\c{[FLOAT]}).
|
||||
|
||||
\c{__?FLOAT?__} contains the full set of floating-point settings; this
|
||||
value can be saved away and invoked later to restore the setting.
|
||||
|
||||
|
||||
\H{asmdir-warning} \i\c{[WARNING]}: Enable or disable warnings
|
||||
|
||||
The \c{[WARNING]} directive can be used to enable or disable classes
|
||||
of warnings in the same way as the \c{-w} option, see \k{warnings} for
|
||||
more details about warning classes.
|
||||
|
||||
\b \c{[warning +}\e{warning-class}\c{]} enables warnings for
|
||||
\e{warning-class}.
|
||||
|
||||
\b \c{[warning -}\e{warning-class}\c{]} disables warnings for
|
||||
\e{warning-class}.
|
||||
|
||||
\b \c{[warning *}\e{warning-class}\c{]} restores \e{warning-class} to
|
||||
the original value, either the default value or as specified on the
|
||||
command line.
|
||||
|
||||
\b \c{[warning push]} saves the current warning state on a stack.
|
||||
|
||||
\b \c{[warning pop]} restores the current warning state from the stack.
|
||||
|
||||
The \c{[WARNING]} directive also accepts the \c{all}, \c{error} and
|
||||
\c{error=}\e{warning-class} specifiers, see \k{opt-w}.
|
||||
|
||||
No "user form" (without the brackets) currently exists.
|
||||
|
||||
|
258
doc/index.src
Normal file
258
doc/index.src
Normal file
|
@ -0,0 +1,258 @@
|
|||
\IR{-D} \c{-D} option
|
||||
\IR{-E} \c{-E} option
|
||||
\IR{-F} \c{-F} option
|
||||
\IR{-I} \c{-I} option
|
||||
\IR{-L} \c{-L} option
|
||||
\IR{-M} \c{-M} option
|
||||
\IR{-MD} \c{-MD} option
|
||||
\IR{-MF} \c{-MF} option
|
||||
\IR{-MG} \c{-MG} option
|
||||
\IR{-MP} \c{-MP} option
|
||||
\IR{-MQ} \c{-MQ} option
|
||||
\IR{-MT} \c{-MT} option
|
||||
\IR{-MW} \c{-MW} option
|
||||
\IR{-O} \c{-O} option
|
||||
\IR{-P} \c{-P} option
|
||||
\IR{-U} \c{-U} option
|
||||
\IR{-X} \c{-X} option
|
||||
\IR{-a} \c{-a} option
|
||||
\IR{-d} \c{-d} option
|
||||
\IR{-e} \c{-e} option
|
||||
\IR{-f} \c{-f} option
|
||||
\IR{-g} \c{-g} option
|
||||
\IR{-i} \c{-i} option
|
||||
\IR{-l} \c{-l} option
|
||||
\IR{-o} \c{-o} option
|
||||
\IR{-p} \c{-p} option
|
||||
\IR{-s} \c{-s} option
|
||||
\IR{-u} \c{-u} option
|
||||
\IR{-v} \c{-v} option
|
||||
\IR{-W} \c{-W} option
|
||||
\IR{-Werror} \c{-Werror} option
|
||||
\IR{-Wno-error} \c{-Wno-error} option
|
||||
\IR{-w} \c{-w} option
|
||||
\IR{-Z} \c{-Z} option
|
||||
\IR{!=} \c{!=} operator
|
||||
\IR{$, here} \c{$}, current address
|
||||
\IR{$, here} here token
|
||||
\IR{$, prefix} \c{$}, prefix
|
||||
\IR{$$} \c{$$} token
|
||||
\IR{%} \c{%} operator
|
||||
\IR{%db} \c{%} prefix to \c{DB} lists
|
||||
\IR{%%} \c{%%} operator
|
||||
\IR{%+1} \c{%+1} and \c{%-1} syntax
|
||||
\IA{%-1}{%+1}
|
||||
\IR{%0} \c{%0} parameter count
|
||||
\IR{&} \c{&} operator
|
||||
\IR{&&} \c{&&} operator
|
||||
\IR{*} \c{*} operator
|
||||
\IR{..@} \c{..@} symbol prefix
|
||||
\IR{/} \c{/} operator
|
||||
\IR{//} \c{//} operator
|
||||
\IR{<} \c{<} operator
|
||||
\IR{<<} \c{<<} operator
|
||||
\IR{<<<} \c{<<<} operator
|
||||
\IR{<=>} \c{<=>} operator
|
||||
\IR{<=} \c{<=} operator
|
||||
\IR{<>} \c{<>} operator
|
||||
\IR{<=>} \c{<=>} operator
|
||||
\IR{=} \c{=} operator
|
||||
\IR{==} \c{==} operator
|
||||
\IR{>} \c{>} operator
|
||||
\IR{>=} \c{>=} operator
|
||||
\IR{>>} \c{>>} operator
|
||||
\IR{>>>} \c{>>>} operator
|
||||
\IR{?db} \c{?}, data syntax
|
||||
\IR{?op} \c{?}, operator
|
||||
\IR{^} \c{^} operator
|
||||
\IR{^^} \c{^^} operator
|
||||
\IR{|} \c{|} operator
|
||||
\IR{||} \c{||} operator
|
||||
\IR{%$} \c{%$} and \c{%$$} prefixes
|
||||
\IA{%$$}{%$}
|
||||
\IR{+ opaddition} \c{+} operator, binary
|
||||
\IR{+ opunary} \c{+} operator, unary
|
||||
\IR{+ modifier} \c{+} modifier
|
||||
\IR{- opsubtraction} \c{-} operator, binary
|
||||
\IR{- opunary} \c{-} operator, unary
|
||||
\IR{! opunary} \c{!} operator
|
||||
\IA{~}{~ opunary}
|
||||
\IR{~ opunary} \c{~} operator
|
||||
\IA{A16}{a16}
|
||||
\IA{A32}{a32}
|
||||
\IA{A64}{a64}
|
||||
\IA{O16}{o16}
|
||||
\IA{O32}{o32}
|
||||
\IA{O64}{o64}
|
||||
\IR{alignment, in bin sections} alignment, in \c{bin} sections
|
||||
\IR{alignment, in elf sections} alignment, in ELF sections
|
||||
\IR{alignment, in win32 sections} alignment, in \c{win32} sections
|
||||
\IR{alignment, of elf common variables} alignment, of ELF common
|
||||
variables
|
||||
\IR{alignment, in obj sections} alignment, in \c{obj} sections
|
||||
\IR{a.out, bsd version} \c{a.out}, BSD version
|
||||
\IR{a.out, linux version} \c{a.out}, Linux version
|
||||
\IR{bin} \c{bin} output format
|
||||
\IR{bitwise and} bitwise AND
|
||||
\IR{bitwise or} bitwise OR
|
||||
\IR{bitwise xor} bitwise XOR
|
||||
\IR{block ifs} block IFs
|
||||
\IR{borland pascal} Borland, Pascal
|
||||
\IR{borland's win32 compilers} Borland, Win32 compilers
|
||||
\IR{braces, after % sign} braces, after \c{%} sign
|
||||
\IR{bsd} BSD
|
||||
\IR{c calling convention} C calling convention
|
||||
\IR{c symbol names} C symbol names
|
||||
\IA{critical expressions}{critical expression}
|
||||
\IA{command-line}{command line}
|
||||
\IA{comments}{comment}
|
||||
\IR{ccomment} comment, ending in \c{\\}
|
||||
\IA{case sensitivity}{case sensitive}
|
||||
\IA{case-sensitive}{case sensitive}
|
||||
\IA{case-insensitive}{case sensitive}
|
||||
\IA{character constants}{character constant}
|
||||
\IR{codeview debugging format} CodeView debugging format
|
||||
\IR{continuation line} continuation line
|
||||
\IR{continuation line} preprocessor, continuation line
|
||||
\IR{common object file format} Common Object File Format
|
||||
\IR{common variables, alignment in elf} common variables, alignment in ELF
|
||||
\IR{common, elf extensions to} \c{COMMON}, ELF extensions to
|
||||
\IR{common, obj extensions to} \c{COMMON}, \c{obj} extensions to
|
||||
\IR{declaring structure} declaring structures
|
||||
\IR{default-wrt mechanism} default-\c{WRT} mechanism
|
||||
\IR{devpac} DevPac
|
||||
\IR{djgpp} DJGPP
|
||||
\IR{dll symbols, exporting} DLL symbols, exporting
|
||||
\IR{dll symbols, importing} DLL symbols, importing
|
||||
\IR{dos} DOS
|
||||
\IA{effective addresses}{effective address}
|
||||
\IA{effective-address}{effective address}
|
||||
\IR{elf} ELF
|
||||
\IR{elf, 16-bit code} ELF, 16-bit code
|
||||
\IR{elf, debug formats} ELF, debug formats
|
||||
\IR{elf shared library} ELF, shared libraries
|
||||
\IR{elf32} \c{elf32}
|
||||
\IR{elf64} \c{elf64}
|
||||
\IR{elfx32} \c{elfx32}
|
||||
\IR{executable and linkable format} Executable and Linkable Format
|
||||
\IR{extern, elf extensions to} \c{EXTERN}, \c{elf} extensions to
|
||||
\IR{extern, obj extensions to} \c{EXTERN}, \c{obj} extensions to
|
||||
\IR{floating-point, constants} floating-point, constants
|
||||
\IR{floating-point, packed bcd constants} floating-point, packed BCD constants
|
||||
\IR{freebsd} FreeBSD
|
||||
\IR{freelink} FreeLink
|
||||
\IR{functions, c calling convention} functions, C calling convention
|
||||
\IR{functions, pascal calling convention} functions, \c{PASCAL} calling convention
|
||||
\IR{global, aoutb extensions to} \c{GLOBAL}, \c{aoutb} extensions to
|
||||
\IR{global, elf extensions to} \c{GLOBAL}, ELF extensions to
|
||||
\IR{global, rdf extensions to} \c{GLOBAL}, \c{rdf} extensions to
|
||||
\IR{got} GOT
|
||||
\IR{got relocations} \c{GOT} relocations
|
||||
\IR{gotoff relocation} \c{GOTOFF} relocations
|
||||
\IR{gotpc relocation} \c{GOTPC} relocations
|
||||
\IR{intel number formats} Intel number formats
|
||||
\IR{linux, elf} Linux, ELF
|
||||
\IR{linux, a.out} Linux, \c{a.out}
|
||||
\IR{linux, as86} Linux, \c{as86}
|
||||
\IR{mach object file format} Mach, object file format
|
||||
\IA{mach-o}{macho}
|
||||
\IR{mach-o} Mach-O, object file format
|
||||
\IR{macho32} \c{macho32}
|
||||
\IR{macho64} \c{macho64}
|
||||
\IR{macos x} MacOS X
|
||||
\IR{masm} MASM
|
||||
\IR{masmdb} MASM, \c{DB} syntax
|
||||
\IA{memory reference}{memory references}
|
||||
\IR{minix} Minix
|
||||
\IA{misc directory}{misc subdirectory}
|
||||
\IR{misc subdirectory} \c{misc} subdirectory
|
||||
\IR{microsoft omf} Microsoft OMF
|
||||
\IR{ms-dos} MS-DOS
|
||||
\IR{ms-dos device drivers} MS-DOS device drivers
|
||||
\IR{multipush} \c{multipush} macro
|
||||
\IR{nan} NaN
|
||||
\IR{nasm version} NASM version
|
||||
\IR{nasm version history} NASM version, history
|
||||
\IR{nasm version macros} NASM version, macros
|
||||
\IR{nasm version id} NASM version, ID macro
|
||||
\IR{nasm version string} NASM version, string macro
|
||||
\IR{arithmetic negation} negation, arithmetic
|
||||
\IR{bitwise negation} negation, bitwise
|
||||
\IR{boolean negation} negation, boolean
|
||||
\IR{boolean and} boolean, AND
|
||||
\IR{boolean or} boolean, OR
|
||||
\IR{boolean xor} boolean, XOR
|
||||
\IR{netbsd} NetBSD
|
||||
\IR{nsis} NSIS
|
||||
\IR{nullsoft scriptable installer} Nullsoft Scriptable Installer
|
||||
\IA{.OBJ}{.obj}
|
||||
\IR{omf} OMF
|
||||
\IR{openbsd} OpenBSD
|
||||
\IR{operating system} operating system
|
||||
\IR{os/2} OS/2
|
||||
\IR{pascal calling convention} Pascal calling convention
|
||||
\IR{pic} PIC
|
||||
\IR{pharlap} PharLap
|
||||
\IR{plt} PLT
|
||||
\IR{plt} \c{PLT} relocations
|
||||
\IA{pre-defining macros}{pre-define}
|
||||
\IR{preprocessor conditionals} preprocessor, conditionals
|
||||
\IR{preprocessor expansions} preprocessor, expansions
|
||||
\IR{preprocessor expressions} preprocessor, expressions
|
||||
\IR{preprocessor loops} preprocessor, loops
|
||||
\IR{preprocessor variables} preprocessor, variables
|
||||
\IR{preprocessor variables} variables, preprocessor
|
||||
\IA{comments}{comment}
|
||||
\IR{relocations, pic-specific} relocations, PIC-specific
|
||||
\IA{repeating}{repeating code}
|
||||
\IR{section alignment, in elf} section alignment, in ELF
|
||||
\IR{section alignment, in bin} section alignment, in \c{bin}
|
||||
\IR{section alignment, in obj} section alignment, in \c{obj}
|
||||
\IR{section alignment, in win32} section alignment, in \c{win32}
|
||||
\IR{section, elf extensions to} \c{SECTION}, ELF extensions to
|
||||
\IR{section, macho extensions to} \c{SECTION}, \c{macho} extensions to
|
||||
\IR{section, windows extensions to} \c{SECTION}, Windows extensions to
|
||||
\IR{segment alignment, in bin} segment alignment, in \c{bin}
|
||||
\IR{segment alignment, in obj} segment alignment, in \c{obj}
|
||||
\IR{segment, obj extensions to} \c{SEGMENT}, \c{obj} extensions to
|
||||
\IR{segment names, borland pascal} segment names, Borland Pascal
|
||||
\IR{shift command} \c{shift} command
|
||||
\IA{string constant}{string constants}
|
||||
\IR{string constants} string, constants
|
||||
\IR{string length} string, length
|
||||
\IR{string manipulation in macros} string, manipulation in macros
|
||||
\IR{align, smart} \c{ALIGN}, smart
|
||||
\IA{sectalign}{sectalign}
|
||||
\IR{solaris x86} Solaris x86
|
||||
\IA{standard section names}{standardized section names}
|
||||
\IR{symbols, exporting from dlls} symbols, exporting from DLLs
|
||||
\IR{symbols, importing from dlls} symbols, importing from DLLs
|
||||
\IR{test subdirectory} \c{test} subdirectory
|
||||
\IR{thread local storage in elf} thread local storage, in ELF
|
||||
\IR{thread local storage in mach-o} thread local storage, in \c{macho}
|
||||
\IR{tlink} \c{TLINK}
|
||||
\IR{unconditionally importing symbols} importing symbols, unconditionally
|
||||
\IR{underscore, in c symbols} underscore, in C symbols
|
||||
\IA{uninitialized storage}{storage, uninitialized}
|
||||
\IR{unicode} Unicode
|
||||
\IR{unix} Unix
|
||||
\IR{utf-8} UTF-8
|
||||
\IR{utf-16} UTF-16
|
||||
\IR{utf-32} UTF-32
|
||||
\IA{sco unix}{unix, sco}
|
||||
\IR{unix, sco} Unix, SCO
|
||||
\IA{unix system v}{unix, system v}
|
||||
\IR{unix, system v} Unix, System V
|
||||
\IR{unixware} UnixWare
|
||||
\IR{val} VAL
|
||||
\IA{version number of nasm}{nasm, version}
|
||||
\IR{visual c++} Visual C++
|
||||
\IR{win32} Win32
|
||||
\IR{win64} Win64
|
||||
\IR{windows} Windows
|
||||
\IR{windows debugging formats} Windows, debugging formats
|
||||
\# \IC{program entry point}{entry point, program}
|
||||
\# \IC{program entry point}{start point, program}
|
||||
\# \IC{MS-DOS device drivers}{device drivers, MS-DOS}
|
||||
\# \IC{16-bit mode, versus 32-bit mode}{32-bit mode, versus 16-bit mode}
|
||||
\# \IC{c symbol names}{symbol names, in C}
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/perl
|
||||
## --------------------------------------------------------------------------
|
||||
##
|
||||
## Copyright 1996-2017 The NASM Authors - All Rights Reserved
|
||||
##
|
||||
## Copyright 1996-2024 The NASM Authors - All Rights Reserved
|
||||
## See the file AUTHORS included with the NASM distribution for
|
||||
## the specific copyright holders.
|
||||
##
|
||||
|
@ -15,7 +15,7 @@
|
|||
## copyright notice, this list of conditions and the following
|
||||
## disclaimer in the documentation and/or other materials provided
|
||||
## with the distribution.
|
||||
##
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
## CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
## INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
|
@ -52,10 +52,11 @@ foreach $arg ( @ARGV ) {
|
|||
}
|
||||
}
|
||||
|
||||
$fname = "../insns.dat" unless $fname = $args[0];
|
||||
open (F, '<', $fname) || die "unable to open $fname";
|
||||
print STDERR "Writing inslist.src...\n";
|
||||
open S, '>', 'inslist.src';
|
||||
$fname = "../insns.dat" unless $fname = shift(@args);
|
||||
open (F, '<', $fname) or die "$0: $fname, $!\n";
|
||||
$ofile = "insns.src" unless $ofile = shift(@args);
|
||||
open(S, '>', $ofile) or die "$0: $ofile: $!\n";
|
||||
print STDERR "Writing $ofile...\n";
|
||||
$line = 0;
|
||||
$insns = 0;
|
||||
while (<F>) {
|
||||
|
@ -105,4 +106,3 @@ print S "\n";
|
|||
close S;
|
||||
close F;
|
||||
printf STDERR "Done: %d instructions\n", $insns;
|
||||
|
||||
|
|
10
doc/inslist.src
Normal file
10
doc/inslist.src
Normal file
|
@ -0,0 +1,10 @@
|
|||
\A{inslist} \i{Instruction List}
|
||||
|
||||
\H{inslistintro} Introduction
|
||||
|
||||
The following sections show the instructions which NASM currently supports. For each
|
||||
instruction, there is a separate entry for each supported addressing mode. The third
|
||||
column shows the processor type in which the instruction was introduced and,
|
||||
when appropriate, one or more usage flags.
|
||||
|
||||
\& insns.src
|
46
doc/intro.src
Normal file
46
doc/intro.src
Normal file
|
@ -0,0 +1,46 @@
|
|||
\C{intro} Introduction
|
||||
|
||||
\H{whatsnasm} What Is NASM?
|
||||
|
||||
The Netwide Assembler, NASM, is an 80x86 and x86-64 assembler designed
|
||||
for portability and modularity. It supports a range of object file
|
||||
formats, including Linux and *BSD \c{a.out}, ELF, Mach-O, 16-bit and
|
||||
32-bit \c{.obj} (OMF) format, COFF (including its Win32 and Win64
|
||||
variants.) It can also output plain binary files, Intel hex and
|
||||
Motorola S-Record formats. Its syntax is designed to be simple and
|
||||
easy to understand, similar to the syntax in the Intel Software
|
||||
Developer Manual with minimal complexity. It supports all currently
|
||||
known x86 architectural extensions, and has strong support for macros.
|
||||
|
||||
\S{legal} \i{License}
|
||||
|
||||
NASM is under the so-called 2-clause BSD license, also
|
||||
known as the simplified BSD license:
|
||||
|
||||
Copyright \m{year} the NASM Authors - All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
\b Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
\b Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
1008
doc/lang.src
Normal file
1008
doc/lang.src
Normal file
File diff suppressed because it is too large
Load diff
196
doc/macropkg.src
Normal file
196
doc/macropkg.src
Normal file
|
@ -0,0 +1,196 @@
|
|||
\C{macropkg} \i{Standard Macro Packages}
|
||||
|
||||
The \i\c{%use} directive (see \k{use}) includes one of the standard
|
||||
macro packages included with the NASM distribution and compiled into
|
||||
the NASM binary. It operates like the \c{%include} directive (see
|
||||
\k{include}), but the included contents is provided by NASM itself.
|
||||
|
||||
The names of standard macro packages are case insensitive and can be
|
||||
quoted or not.
|
||||
|
||||
As of version 2.15, NASM has \c{%ifusable} and \c{%ifusing} directives to help
|
||||
the user understand whether an individual package available in this version of
|
||||
NASM (\c{%ifusable}) or a particular package already loaded (\c{%ifusing}).
|
||||
|
||||
|
||||
\H{pkg_altreg} \i\c{altreg}: \i{Alternate Register Names}
|
||||
|
||||
The \c{altreg} standard macro package provides alternate register
|
||||
names. It provides numeric register names for all registers (not just
|
||||
\c{R8}-\c{R15}), the Intel-defined aliases \c{R8L}-\c{R15L} for the
|
||||
low bytes of register (as opposed to the NASM/AMD standard names
|
||||
\c{R8B}-\c{R15B}), and the names \c{R0H}-\c{R3H} (by analogy with
|
||||
\c{R0L}-\c{R3L}) for \c{AH}, \c{CH}, \c{DH}, and \c{BH}.
|
||||
|
||||
Example use:
|
||||
|
||||
\c %use altreg
|
||||
\c
|
||||
\c proc:
|
||||
\c mov r0l,r3h ; mov al,bh
|
||||
\c ret
|
||||
|
||||
See also \k{reg64}.
|
||||
|
||||
|
||||
\H{pkg_smartalign} \i\c{smartalign}\I{align, smart}: Smart \c{ALIGN} Macro
|
||||
|
||||
The \c{smartalign} standard macro package provides for an \i\c{ALIGN}
|
||||
macro which is more powerful than the default (and
|
||||
backwards-compatible) one (see \k{align}). When the \c{smartalign}
|
||||
package is enabled, when \c{ALIGN} is used without a second argument,
|
||||
NASM will generate a sequence of instructions more efficient than a
|
||||
series of \c{NOP}. Furthermore, if the padding exceeds a specific
|
||||
threshold, then NASM will generate a jump over the entire padding
|
||||
sequence.
|
||||
|
||||
The specific instructions generated can be controlled with the
|
||||
new \i\c{ALIGNMODE} macro. This macro takes two parameters: one mode,
|
||||
and an optional jump threshold override. If (for any reason) you need
|
||||
to turn off the jump completely just set jump threshold value to -1
|
||||
(or set it to \c{nojmp}). The following modes are possible:
|
||||
|
||||
\b \c{generic}: Works on all x86 CPUs and should have reasonable
|
||||
performance. The default jump threshold is 8. This is the
|
||||
default.
|
||||
|
||||
\b \c{nop}: Pad out with \c{NOP} instructions. The only difference
|
||||
compared to the standard \c{ALIGN} macro is that NASM can still jump
|
||||
over a large padding area. The default jump threshold is 16.
|
||||
|
||||
\b \c{k7}: Optimize for the AMD K7 (Athlon/Althon XP). These
|
||||
instructions should still work on all x86 CPUs. The default jump
|
||||
threshold is 16.
|
||||
|
||||
\b \c{k8}: Optimize for the AMD K8 (Opteron/Althon 64). These
|
||||
instructions should still work on all x86 CPUs. The default jump
|
||||
threshold is 16.
|
||||
|
||||
\b \c{p6}: Optimize for Intel CPUs. This uses the long \c{NOP}
|
||||
instructions first introduced in Pentium Pro. This is incompatible
|
||||
with all CPUs of family 5 or lower, as well as some VIA CPUs and
|
||||
several virtualization solutions. The default jump threshold is 16.
|
||||
|
||||
The macro \i\c{__?ALIGNMODE?__} is defined to contain the current
|
||||
alignment mode. A number of other macros beginning with \c{__?ALIGN_}
|
||||
are used internally by this macro package.
|
||||
|
||||
|
||||
\H{pkg_fp} \i\c\{fp}: Floating-point macros
|
||||
|
||||
This packages contains the following floating-point convenience macros:
|
||||
|
||||
\c %define Inf __?Infinity?__
|
||||
\c %define NaN __?QNaN?__
|
||||
\c %define QNaN __?QNaN?__
|
||||
\c %define SNaN __?SNaN?__
|
||||
\c
|
||||
\c %define float8(x) __?float8?__(x)
|
||||
\c %define float16(x) __?float16?__(x)
|
||||
\c %define bfloat16(x) __?bfloat16?__(x)
|
||||
\c %define float32(x) __?float32?__(x)
|
||||
\c %define float64(x) __?float64?__(x)
|
||||
\c %define float80m(x) __?float80m?__(x)
|
||||
\c %define float80e(x) __?float80e?__(x)
|
||||
\c %define float128l(x) __?float128l?__(x)
|
||||
\c %define float128h(x) __?float128h?__(x)
|
||||
|
||||
It also defines the a multi-line macro \i\c{bf16} that can be used
|
||||
in a similar way to the \c{D}\e{x} directives for the other
|
||||
floating-point numbers:
|
||||
|
||||
\c bf16 -3.1415, NaN, 2000.0, +Inf
|
||||
|
||||
|
||||
\H{pkg_ifunc} \i\c{ifunc}: \i{Integer functions}
|
||||
|
||||
This package contains a set of macros which implement integer
|
||||
functions. These are actually implemented as special operators, but
|
||||
are most conveniently accessed via this macro package.
|
||||
|
||||
The macros provided are:
|
||||
|
||||
\S{ilog2} \i{Integer logarithms}
|
||||
|
||||
These functions calculate the integer logarithm base 2 of their
|
||||
argument, considered as an unsigned integer. The only differences
|
||||
between the functions is their respective behavior if the argument
|
||||
provided is not a power of two.
|
||||
|
||||
The function \i\c{ilog2e()} (alias \i\c{ilog2()}) generates an error if
|
||||
the argument is not a power of two.
|
||||
|
||||
The function \i\c{ilog2f()} rounds the argument down to the nearest
|
||||
power of two; if the argument is zero it returns zero.
|
||||
|
||||
The function \i\c{ilog2c()} rounds the argument up to the nearest
|
||||
power of two.
|
||||
|
||||
The functions \i\c{ilog2fw()} (alias \i\c{ilog2w()}) and
|
||||
\i\c{ilog2cw()} generate a warning if the argument is not a power of
|
||||
two, but otherwise behaves like \c{ilog2f()} and \c{ilog2c()},
|
||||
respectively.
|
||||
|
||||
\H{pkg_masm} \i\c{masm}: \i{MASM compatibility}
|
||||
|
||||
Since version 2.15, NASM has a MASM compatibility package with minimal
|
||||
functionality, as intended to be used primarily with machine-generated code.
|
||||
It does not include any "programmer-friendly" shortcuts, nor does it in any way
|
||||
support ASSUME, symbol typing, or MASM-style structures.
|
||||
|
||||
To enable the package, use the directive:
|
||||
|
||||
\c{%use masm}
|
||||
|
||||
Currently, the MASM compatibility package emulates:
|
||||
|
||||
\b The \c{FLAT} and \c{OFFSET} keywords are recognized and ignored.
|
||||
|
||||
\b The \c{PTR} keyword signifies a memory reference, as if the
|
||||
argument had been put in square brackets:
|
||||
|
||||
\c mov eax,[foo] ; memory reference
|
||||
\c mov eax,dword ptr foo ; memory reference
|
||||
\c mov eax,dowrd ptr flat:foo ; memory reference
|
||||
\c mov eax,offset foo ; address
|
||||
\c mov eax,foo ; address (ambiguous syntax in MASM)
|
||||
|
||||
\b The \c{SEGMENT} ... \c{ENDS} syntax:
|
||||
|
||||
\c segname SEGMENT
|
||||
\c ...
|
||||
\c segname ENDS
|
||||
|
||||
\b The \c{PROC} ... \c{ENDP} syntax:
|
||||
|
||||
\c procname PROC [FAR]
|
||||
\c ...
|
||||
\c procname ENDP
|
||||
|
||||
\> \c{PROC} will also define \c{RET} as a macro expanding to either
|
||||
\c{RETF} if \c{FAR} is specified and \c{RETN} otherwise. Any keyword
|
||||
after \c{PROC} other than \c{FAR} is ignored.
|
||||
|
||||
\b The \c{TBYTE} keyword as an alias for \c{TWORD} (see \k{qsother}).
|
||||
|
||||
\b The \c{END} directive is ignored.
|
||||
|
||||
\b In 64-bit mode relative addressing is the default (\c{DEFAULT REL},
|
||||
see \k{REL & ABS}).
|
||||
|
||||
In addition, NASM now natively supports, regardless of whether this
|
||||
package is used or not:
|
||||
|
||||
\b \c{?} and \c{DUP} syntax for the \c{DB} etc data declaration
|
||||
directives (see \k{db}).
|
||||
|
||||
\b \c{displacement[base+index]} syntax for memory operations, instead
|
||||
of \c{[base+index+displacement]}.
|
||||
|
||||
\b \c{seg:[addr]} instead of \c{[seg:addr]} syntax.
|
||||
|
||||
\b A pure offset can be given to \c{LEA} without square brackets:
|
||||
|
||||
\c lea rax,[foo] ; standard syntax
|
||||
\c lea rax,foo ; also accepted
|
||||
|
168
doc/mixsize.src
Normal file
168
doc/mixsize.src
Normal file
|
@ -0,0 +1,168 @@
|
|||
\C{mixsize} Mixing 16- and 32-bit Code
|
||||
|
||||
This chapter tries to cover some of the issues, largely related to
|
||||
unusual forms of addressing and jump instructions, encountered when
|
||||
writing operating system code such as protected-mode initialization
|
||||
routines, which require code that operates in mixed segment sizes,
|
||||
such as code in a 16-bit segment trying to modify data in a 32-bit
|
||||
one, or jumps between different-size segments.
|
||||
|
||||
|
||||
\H{mixjump} Mixed-Size Jumps\I{jumps, mixed-size}
|
||||
|
||||
\I{operating system, writing}\I{writing operating systems}The most
|
||||
common form of \i{mixed-size instruction} is the one used when
|
||||
writing a 32-bit OS: having done your setup in 16-bit mode, such as
|
||||
loading the kernel, you then have to boot it by switching into
|
||||
protected mode and jumping to the 32-bit kernel start address. In a
|
||||
fully 32-bit OS, this tends to be the \e{only} mixed-size
|
||||
instruction you need, since everything before it can be done in pure
|
||||
16-bit code, and everything after it can be pure 32-bit.
|
||||
|
||||
This jump must specify a 48-bit far address, since the target
|
||||
segment is a 32-bit one. However, it must be assembled in a 16-bit
|
||||
segment, so just coding, for example,
|
||||
|
||||
\c jmp 0x1234:0x56789ABC ; wrong!
|
||||
|
||||
will not work, since the offset part of the address will be
|
||||
truncated to \c{0x9ABC} and the jump will be an ordinary 16-bit far
|
||||
one.
|
||||
|
||||
The Linux kernel setup code gets round the inability of \c{as86} to
|
||||
generate the required instruction by coding it manually, using
|
||||
\c{DB} instructions. NASM can go one better than that, by actually
|
||||
generating the right instruction itself. Here's how to do it right:
|
||||
|
||||
\c jmp dword 0x1234:0x56789ABC ; right
|
||||
|
||||
\I\c{JMP DWORD}The \c{DWORD} prefix (strictly speaking, it should
|
||||
come \e{after} the colon, since it is declaring the \e{offset} field
|
||||
to be a doubleword; but NASM will accept either form, since both are
|
||||
unambiguous) forces the offset part to be treated as far, in the
|
||||
assumption that you are deliberately writing a jump from a 16-bit
|
||||
segment to a 32-bit one.
|
||||
|
||||
You can do the reverse operation, jumping from a 32-bit segment to a
|
||||
16-bit one, by means of the \c{WORD} prefix:
|
||||
|
||||
\c jmp word 0x8765:0x4321 ; 32 to 16 bit
|
||||
|
||||
If the \c{WORD} prefix is specified in 16-bit mode, or the \c{DWORD}
|
||||
prefix in 32-bit mode, they will be ignored, since each is
|
||||
explicitly forcing NASM into a mode it was in anyway.
|
||||
|
||||
|
||||
\H{mixaddr} Addressing Between Different-Size Segments\I{addressing,
|
||||
mixed-size}\I{mixed-size addressing}
|
||||
|
||||
If your OS is mixed 16 and 32-bit, or if you are writing a DOS
|
||||
extender, you are likely to have to deal with some 16-bit segments
|
||||
and some 32-bit ones. At some point, you will probably end up
|
||||
writing code in a 16-bit segment which has to access data in a
|
||||
32-bit segment, or vice versa.
|
||||
|
||||
If the data you are trying to access in a 32-bit segment lies within
|
||||
the first 64K of the segment, you may be able to get away with using
|
||||
an ordinary 16-bit addressing operation for the purpose; but sooner
|
||||
or later, you will want to do 32-bit addressing from 16-bit mode.
|
||||
|
||||
The easiest way to do this is to make sure you use a register for
|
||||
the address, since any effective address containing a 32-bit
|
||||
register is forced to be a 32-bit address. So you can do
|
||||
|
||||
\c mov eax,offset_into_32_bit_segment_specified_by_fs
|
||||
\c mov dword [fs:eax],0x11223344
|
||||
|
||||
This is fine, but slightly cumbersome (since it wastes an
|
||||
instruction and a register) if you already know the precise offset
|
||||
you are aiming at. The x86 architecture does allow 32-bit effective
|
||||
addresses to specify nothing but a 4-byte offset, so why shouldn't
|
||||
NASM be able to generate the best instruction for the purpose?
|
||||
|
||||
It can. As in \k{mixjump}, you need only prefix the address with the
|
||||
\c{DWORD} keyword, and it will be forced to be a 32-bit address:
|
||||
|
||||
\c mov dword [fs:dword my_offset],0x11223344
|
||||
|
||||
Also as in \k{mixjump}, NASM is not fussy about whether the
|
||||
\c{DWORD} prefix comes before or after the segment override, so
|
||||
arguably a nicer-looking way to code the above instruction is
|
||||
|
||||
\c mov dword [dword fs:my_offset],0x11223344
|
||||
|
||||
Don't confuse the \c{DWORD} prefix \e{outside} the square brackets,
|
||||
which controls the size of the data stored at the address, with the
|
||||
one \c{inside} the square brackets which controls the length of the
|
||||
address itself. The two can quite easily be different:
|
||||
|
||||
\c mov word [dword 0x12345678],0x9ABC
|
||||
|
||||
This moves 16 bits of data to an address specified by a 32-bit
|
||||
offset.
|
||||
|
||||
You can also specify \c{WORD} or \c{DWORD} prefixes along with the
|
||||
\c{FAR} prefix to indirect far jumps or calls. For example:
|
||||
|
||||
\c call dword far [fs:word 0x4321]
|
||||
|
||||
This instruction contains an address specified by a 16-bit offset;
|
||||
it loads a 48-bit far pointer from that (16-bit segment and 32-bit
|
||||
offset), and calls that address.
|
||||
|
||||
|
||||
\H{mixother} Other Mixed-Size Instructions
|
||||
|
||||
The other way you might want to access data might be using the
|
||||
string instructions (\c{LODSx}, \c{STOSx} and so on) or the
|
||||
\c{XLATB} instruction. These instructions, since they take no
|
||||
parameters, might seem to have no easy way to make them perform
|
||||
32-bit addressing when assembled in a 16-bit segment.
|
||||
|
||||
This is the purpose of NASM's \i\c{a16}, \i\c{a32} and \i\c{a64} prefixes. If
|
||||
you are coding \c{LODSB} in a 16-bit segment but it is supposed to
|
||||
be accessing a string in a 32-bit segment, you should load the
|
||||
desired address into \c{ESI} and then code
|
||||
|
||||
\c a32 lodsb
|
||||
|
||||
The prefix forces the addressing size to 32 bits, meaning that
|
||||
\c{LODSB} loads from \c{[DS:ESI]} instead of \c{[DS:SI]}. To access
|
||||
a string in a 16-bit segment when coding in a 32-bit one, the
|
||||
corresponding \c{a16} prefix can be used.
|
||||
|
||||
The \c{a16}, \c{a32} and \c{a64} prefixes can be applied to any instruction
|
||||
in NASM's instruction table, but most of them can generate all the
|
||||
useful forms without them. The prefixes are necessary only for
|
||||
instructions with implicit addressing:
|
||||
\# \c{CMPSx} (\k{insCMPSB}),
|
||||
\# \c{SCASx} (\k{insSCASB}), \c{LODSx} (\k{insLODSB}), \c{STOSx}
|
||||
\# (\k{insSTOSB}), \c{MOVSx} (\k{insMOVSB}), \c{INSx} (\k{insINSB}),
|
||||
\# \c{OUTSx} (\k{insOUTSB}), and \c{XLATB} (\k{insXLATB}).
|
||||
\c{CMPSx}, \c{SCASx}, \c{LODSx}, \c{STOSx}, \c{MOVSx}, \c{INSx},
|
||||
\c{OUTSx}, and \c{XLATB}.
|
||||
Also, the
|
||||
various push and pop instructions (\c{PUSHA} and \c{POPF} as well as
|
||||
the more usual \c{PUSH} and \c{POP}) can accept \c{a16}, \c{a32} or \c{a64}
|
||||
prefixes to force a particular one of \c{SP}, \c{ESP} or \c{RSP} to be used
|
||||
as a stack pointer, in case the stack segment in use is a different
|
||||
size from the code segment.
|
||||
|
||||
\c{PUSH} and \c{POP}, when applied to segment registers in 32-bit
|
||||
mode, also have the slightly odd behaviour that they push and pop 4
|
||||
bytes at a time, of which the top two are ignored and the bottom two
|
||||
give the value of the segment register being manipulated. To force
|
||||
the 16-bit behaviour of segment-register push and pop instructions,
|
||||
you can use the operand-size prefix \i\c{o16}:
|
||||
|
||||
\c o16 push ss
|
||||
\c o16 push ds
|
||||
|
||||
This code saves a doubleword of stack space by fitting two segment
|
||||
registers into the space which would normally be consumed by pushing
|
||||
one.
|
||||
|
||||
(You can also use the \i\c{o32} prefix to force the 32-bit behaviour
|
||||
when in 16-bit mode, but this seems less useful.)
|
||||
|
||||
|
9508
doc/nasmdoc.src
9508
doc/nasmdoc.src
File diff suppressed because it is too large
Load diff
168
doc/ndisasm.src
Normal file
168
doc/ndisasm.src
Normal file
|
@ -0,0 +1,168 @@
|
|||
\A{ndisasm} \i{Ndisasm}
|
||||
|
||||
The Netwide Disassembler, NDISASM
|
||||
|
||||
\H{ndisintro} Introduction
|
||||
|
||||
|
||||
The Netwide Disassembler is a small companion program to the Netwide
|
||||
Assembler, NASM. It seemed a shame to have an x86 assembler,
|
||||
complete with a full instruction table, and not make as much use of
|
||||
it as possible, so here's a disassembler which shares the
|
||||
instruction table (and some other bits of code) with NASM.
|
||||
|
||||
The Netwide Disassembler does nothing except to produce
|
||||
disassemblies of \e{binary} source files. NDISASM does not have any
|
||||
understanding of object file formats, like \c{objdump}, and it will
|
||||
not understand \c{DOS .EXE} files like \c{debug} will. It just
|
||||
disassembles.
|
||||
|
||||
|
||||
\H{ndisrun} Running NDISASM
|
||||
|
||||
To disassemble a file, you will typically use a command of the form
|
||||
|
||||
\c ndisasm -b {16|32|64} filename
|
||||
|
||||
NDISASM can disassemble 16-, 32- or 64-bit code equally easily,
|
||||
provided of course that you remember to specify which it is to work
|
||||
with. If no \i\c{-b} switch is present, NDISASM works in 16-bit mode
|
||||
by default. The \i\c{-u} switch (for USE32) also invokes 32-bit mode.
|
||||
|
||||
Two more command line options are \i\c{-r} which reports the version
|
||||
number of NDISASM you are running, and \i\c{-h} which gives a short
|
||||
summary of command line options.
|
||||
|
||||
|
||||
\S{ndiscom} Specifying the Input Origin
|
||||
|
||||
To disassemble a \c{DOS .COM} file correctly, a disassembler must assume
|
||||
that the first instruction in the file is loaded at address \c{0x100},
|
||||
rather than at zero. NDISASM, which assumes by default that any file
|
||||
you give it is loaded at zero, will therefore need to be informed of
|
||||
this.
|
||||
|
||||
The \i\c{-o} option allows you to declare a different origin for the
|
||||
file you are disassembling. Its argument may be expressed in any of
|
||||
the NASM numeric formats: decimal by default, if it begins with `\c{$}'
|
||||
or `\c{0x}' or ends in `\c{H}' it's \c{hex}, if it ends in `\c{Q}' it's
|
||||
\c{octal}, and if it ends in `\c{B}' it's \c{binary}.
|
||||
|
||||
Hence, to disassemble a \c{.COM} file:
|
||||
|
||||
\c ndisasm -o100h filename.com
|
||||
|
||||
will do the trick.
|
||||
|
||||
|
||||
\S{ndissync} Code Following Data: Synchronization
|
||||
|
||||
Suppose you are disassembling a file which contains some data which
|
||||
isn't machine code, and \e{then} contains some machine code. NDISASM
|
||||
will faithfully plough through the data section, producing machine
|
||||
instructions wherever it can (although most of them will look
|
||||
bizarre, and some may have unusual prefixes, e.g. `\c{FS OR AX,0x240A}'),
|
||||
and generating `DB' instructions ever so often if it's totally stumped.
|
||||
Then it will reach the code section.
|
||||
|
||||
Supposing NDISASM has just finished generating a strange machine
|
||||
instruction from part of the data section, and its file position is
|
||||
now one byte \e{before} the beginning of the code section. It's
|
||||
entirely possible that another spurious instruction will get
|
||||
generated, starting with the final byte of the data section, and
|
||||
then the correct first instruction in the code section will not be
|
||||
seen because the starting point skipped over it. This isn't really
|
||||
ideal.
|
||||
|
||||
To avoid this, you can specify a `\i{synchronization}' point, or indeed
|
||||
as many synchronization points as you like (although NDISASM can
|
||||
only handle 2147483647 sync points internally). The definition of a sync
|
||||
point is this: NDISASM guarantees to hit sync points exactly during
|
||||
disassembly. If it is thinking about generating an instruction which
|
||||
would cause it to jump over a sync point, it will discard that
|
||||
instruction and output a `\c{db}' instead. So it \e{will} start
|
||||
disassembly exactly from the sync point, and so you \e{will} see all
|
||||
the instructions in your code section.
|
||||
|
||||
Sync points are specified using the \i\c{-s} option: they are measured
|
||||
in terms of the program origin, not the file position. So if you
|
||||
want to synchronize after 32 bytes of a \c{.COM} file, you would have to
|
||||
do
|
||||
|
||||
\c ndisasm -o100h -s120h file.com
|
||||
|
||||
rather than
|
||||
|
||||
\c ndisasm -o100h -s20h file.com
|
||||
|
||||
As stated above, you can specify multiple sync markers if you need
|
||||
to, just by repeating the \c{-s} option.
|
||||
|
||||
|
||||
\S{ndisisync} Mixed Code and Data: Automatic (Intelligent) Synchronization
|
||||
\I\c{auto-sync}
|
||||
|
||||
Suppose you are disassembling the boot sector of a \c{DOS} floppy (maybe
|
||||
it has a virus, and you need to understand the virus so that you
|
||||
know what kinds of damage it might have done you). Typically, this
|
||||
will contain a \c{JMP} instruction, then some data, then the rest of the
|
||||
code. So there is a very good chance of NDISASM being \e{misaligned}
|
||||
when the data ends and the code begins. Hence a sync point is
|
||||
needed.
|
||||
|
||||
On the other hand, why should you have to specify the sync point
|
||||
manually? What you'd do in order to find where the sync point would
|
||||
be, surely, would be to read the \c{JMP} instruction, and then to use
|
||||
its target address as a sync point. So can NDISASM do that for you?
|
||||
|
||||
The answer, of course, is yes: using either of the synonymous
|
||||
switches \i\c{-a} (for automatic sync) or \i\c{-i} (for intelligent
|
||||
sync) will enable \c{auto-sync} mode. Auto-sync mode automatically
|
||||
generates a sync point for any forward-referring PC-relative jump or
|
||||
call instruction that NDISASM encounters. (Since NDISASM is one-pass,
|
||||
if it encounters a PC-relative jump whose target has already been
|
||||
processed, there isn't much it can do about it...)
|
||||
|
||||
Only PC-relative jumps are processed, since an absolute jump is
|
||||
either through a register (in which case NDISASM doesn't know what
|
||||
the register contains) or involves a segment address (in which case
|
||||
the target code isn't in the same segment that NDISASM is working
|
||||
in, and so the sync point can't be placed anywhere useful).
|
||||
|
||||
For some kinds of file, this mechanism will automatically put sync
|
||||
points in all the right places, and save you from having to place
|
||||
any sync points manually. However, it should be stressed that
|
||||
auto-sync mode is \e{not} guaranteed to catch all the sync points, and
|
||||
you may still have to place some manually.
|
||||
|
||||
Auto-sync mode doesn't prevent you from declaring manual sync
|
||||
points: it just adds automatically generated ones to the ones you
|
||||
provide. It's perfectly feasible to specify \c{-i} \e{and} some \c{-s}
|
||||
options.
|
||||
|
||||
Another caveat with auto-sync mode is that if, by some unpleasant
|
||||
fluke, something in your data section should disassemble to a
|
||||
PC-relative call or jump instruction, NDISASM may obediently place a
|
||||
sync point in a totally random place, for example in the middle of
|
||||
one of the instructions in your code section. So you may end up with
|
||||
a wrong disassembly even if you use auto-sync. Again, there isn't
|
||||
much I can do about this. If you have problems, you'll have to use
|
||||
manual sync points, or use the \c{-k} option (documented below) to
|
||||
suppress disassembly of the data area.
|
||||
|
||||
|
||||
\S{ndisother} Other Options
|
||||
|
||||
The \i\c{-e} option skips a header on the file, by ignoring the first N
|
||||
bytes. This means that the header is \e{not} counted towards the
|
||||
disassembly offset: if you give \c{-e10 -o10}, disassembly will start
|
||||
at byte 10 in the file, and this will be given offset 10, not 20.
|
||||
|
||||
The \i\c{-k} option is provided with two comma-separated numeric
|
||||
arguments, the first of which is an assembly offset and the second
|
||||
is a number of bytes to skip. This \e{will} count the skipped bytes
|
||||
towards the assembly offset: its use is to suppress disassembly of a
|
||||
data section which wouldn't contain anything you wanted to see
|
||||
anyway.
|
||||
|
||||
|
1494
doc/outfmt.src
Normal file
1494
doc/outfmt.src
Normal file
File diff suppressed because it is too large
Load diff
2465
doc/preproc.src
Normal file
2465
doc/preproc.src
Normal file
File diff suppressed because it is too large
Load diff
109
doc/rdsrc.pl
109
doc/rdsrc.pl
|
@ -135,10 +135,15 @@ use File::Spec;
|
|||
@include_path = ();
|
||||
$out_path = File::Spec->curdir();
|
||||
|
||||
my %srcfiles; # For dependencies
|
||||
my $depend_path;
|
||||
|
||||
while ($ARGV[0] =~ /^-/) {
|
||||
my $opt = shift @ARGV;
|
||||
if ($opt eq '-d') {
|
||||
$diag = 1;
|
||||
} elsif ($opt =~ /^\-M(.*)$/) {
|
||||
$depend_path = $1;
|
||||
} elsif ($opt =~ /^\-[Ii](.*)$/) {
|
||||
push(@include_path, $1);
|
||||
} elsif ($opt =~ /^\-[Oo](.*)$/) {
|
||||
|
@ -159,7 +164,6 @@ $tstruct_last[$tstruct_level{$tstruct_previtem}] = $tstruct_previtem;
|
|||
$MAXLEVEL = 10; # really 3, but play safe ;-)
|
||||
|
||||
# Read the file; pass a paragraph at a time to the paragraph processor.
|
||||
print "Reading input...";
|
||||
$pname = [];
|
||||
@pnames = @pflags = ();
|
||||
$para = undef;
|
||||
|
@ -167,45 +171,71 @@ foreach $file (@files) {
|
|||
&include($file);
|
||||
}
|
||||
&got_para($para);
|
||||
print "done.\n";
|
||||
print "$outfile: done.\n";
|
||||
|
||||
# Now we've read in the entire document and we know what all the
|
||||
# heading keywords refer to. Go through and fix up the \k references.
|
||||
print "Fixing up cross-references...";
|
||||
print "$outfile: Fixing up cross-references...\n";
|
||||
&fixup_xrefs;
|
||||
print "done.\n";
|
||||
|
||||
# Sort the index tags, according to the slightly odd order I've decided on.
|
||||
print "Sorting index tags...";
|
||||
print "$outfile: sorting index tags...\n";
|
||||
&indexsort;
|
||||
print "done.\n";
|
||||
|
||||
# Make output directory if necessary
|
||||
mkdir($out_path);
|
||||
|
||||
if ($diag) {
|
||||
print "Writing index-diagnostic file...";
|
||||
print "$outfile: writing index-diagnostic file...\n";
|
||||
&indexdiag;
|
||||
print "done.\n";
|
||||
}
|
||||
|
||||
# OK. Write out the various output files.
|
||||
my $outfile;
|
||||
if ($out_format eq 'txt') {
|
||||
print "Producing text output: ";
|
||||
$outfile = 'nasmdoc.txt';
|
||||
print "$outfile: producing text output...\n";
|
||||
&write_txt;
|
||||
print "done.\n";
|
||||
} elsif ($out_format eq 'html') {
|
||||
print "Producing HTML output: ";
|
||||
$outfile = 'nasmdoc0.html';
|
||||
print "$outfile: producing HTML output...\n";
|
||||
&write_html;
|
||||
print "done.\n";
|
||||
} elsif ($out_format eq 'dip') {
|
||||
print "Producing Documentation Intermediate Paragraphs: ";
|
||||
$outfile = 'nasmdoc.dip';
|
||||
print "$outfile: producing Documentation Intermediate Paragraphs...\n";
|
||||
&write_dip;
|
||||
print "done.\n";
|
||||
} else {
|
||||
die "$0: unknown output format: $out_format\n";
|
||||
}
|
||||
|
||||
if (defined($depend_path)) {
|
||||
# Write dependencies
|
||||
print "$outfile: writing dependencies\n";
|
||||
open(my $dep, '>', $depend_path)
|
||||
or die "$outfile: $depend_path: $!\n";
|
||||
|
||||
if ($out_path ne File::Spec->curdir()) {
|
||||
$outfile = File::Spec->catfile($out_path, $outfile);
|
||||
}
|
||||
|
||||
my $o = $outfile.' :';
|
||||
my $ol = length($o);
|
||||
foreach my $sf (sort(keys(%srcfiles))) {
|
||||
my $l = length($sf);
|
||||
if ($l + $ol > 77) {
|
||||
print $dep $o, " \\\n";
|
||||
$o = '';
|
||||
$ol = 0;
|
||||
}
|
||||
$o .= ' '.$sf;
|
||||
$ol += $l+1;
|
||||
}
|
||||
print $dep $o, "\n\n";
|
||||
close($dep);
|
||||
}
|
||||
|
||||
print "$outfile: done.\n";
|
||||
|
||||
sub untabify($) {
|
||||
my($s) = @_;
|
||||
my $o = '';
|
||||
|
@ -251,17 +281,22 @@ sub include {
|
|||
my $F;
|
||||
|
||||
if ($name eq '-') {
|
||||
open($F, '<-'); # stdin
|
||||
open($F, '<&', \*STDIN); # stdin
|
||||
print "$outfile: reading stdin...\n";
|
||||
} else {
|
||||
my $found = 0;
|
||||
foreach my $idir ( File::Spec->curdir, @include_path ) {
|
||||
my $fpath = File::Spec->catfile($idir, $name);
|
||||
if (open($F, '<', $fpath)) {
|
||||
$found = 1;
|
||||
last;
|
||||
}
|
||||
if (open($F, '<', $fpath)) {
|
||||
# Assume that make uses VPATH for the input search path,
|
||||
# and so dependencies should not include the search directory.
|
||||
$srcfiles{$name}++;
|
||||
$found = 1;
|
||||
print "$outfile: reading $fpath...\n";
|
||||
last;
|
||||
}
|
||||
}
|
||||
die "Cannot open $name: $!\n" unless ($found);
|
||||
die "$0:$outfile: Cannot open $name: $!\n" unless ($found);
|
||||
}
|
||||
while (defined($_ = <$F>)) {
|
||||
&read_line($_);
|
||||
|
@ -308,7 +343,7 @@ sub got_para {
|
|||
$snum = 0;
|
||||
$xref = "chapter-$cnum";
|
||||
$pflags = "chap $cnum :$xref";
|
||||
die "badly formatted chapter heading: $_\n" if !/^\\C\{([^\}]*)\}\s*(.*)$/;
|
||||
die "$outfile: badly formatted chapter heading: $_\n" if !/^\\C\{([^\}]*)\}\s*(.*)$/;
|
||||
$refs{$1} = "chapter $cnum";
|
||||
$node = "Chapter $cnum";
|
||||
&add_item($node, 1, $para);
|
||||
|
@ -325,7 +360,7 @@ sub got_para {
|
|||
$snum = 0;
|
||||
$xref = "appendix-$cnum";
|
||||
$pflags = "appn $cnum :$xref";
|
||||
die "badly formatted appendix heading: $_\n" if !/^\\A\{([^\}]*)}\s*(.*)$/;
|
||||
die "$outfile: badly formatted appendix heading: $_\n" if !/^\\A\{([^\}]*)}\s*(.*)$/;
|
||||
$refs{$1} = "appendix $cnum";
|
||||
$node = "Appendix $cnum";
|
||||
&add_item($node, 1, $para);
|
||||
|
@ -339,7 +374,7 @@ sub got_para {
|
|||
$snum = 0;
|
||||
$xref = "section-$cnum.$hnum";
|
||||
$pflags = "head $cnum.$hnum :$xref";
|
||||
die "badly formatted heading: $_\n" if !/^\\[HP]\{([^\}]*)\}\s*(.*)$/;
|
||||
die "$outfile: badly formatted heading: $_\n" if !/^\\[HP]\{([^\}]*)\}\s*(.*)$/;
|
||||
$refs{$1} = "section $cnum.$hnum";
|
||||
$node = "Section $cnum.$hnum";
|
||||
&add_item($node, 2, $para);
|
||||
|
@ -352,7 +387,7 @@ sub got_para {
|
|||
$snum++;
|
||||
$xref = "section-$cnum.$hnum.$snum";
|
||||
$pflags = "subh $cnum.$hnum.$snum :$xref";
|
||||
die "badly formatted subheading: $_\n" if !/^\\S\{([^\}]*)\}\s*(.*)$/;
|
||||
die "$outfile: badly formatted subheading: $_\n" if !/^\\S\{([^\}]*)\}\s*(.*)$/;
|
||||
$refs{$1} = "section $cnum.$hnum.$snum";
|
||||
$node = "Section $cnum.$hnum.$snum";
|
||||
&add_item($node, 3, $para);
|
||||
|
@ -362,18 +397,18 @@ sub got_para {
|
|||
# the standard word-by-word code will happen next
|
||||
} elsif (/^\\IR/) {
|
||||
# An index-rewrite.
|
||||
die "badly formatted index rewrite: $_\n" if !/^\\IR\{([^\}]*)\}\s*(.*)$/;
|
||||
die "$outfile: badly formatted index rewrite: $_\n" if !/^\\IR\{([^\}]*)\}\s*(.*)$/;
|
||||
$irewrite = $1;
|
||||
$_ = $2;
|
||||
# the standard word-by-word code will happen next
|
||||
} elsif (/^\\IA/) {
|
||||
# An index-alias.
|
||||
die "badly formatted index alias: $_\n" if !/^\\IA\{([^\}]*)}\{([^\}]*)\}\s*$/;
|
||||
die "$outfile: badly formatted index alias: $_\n" if !/^\\IA\{([^\}]*)}\{([^\}]*)\}\s*$/;
|
||||
$idxalias{$1} = $2;
|
||||
return; # avoid word-by-word code
|
||||
} elsif (/^\\M/) {
|
||||
# Metadata
|
||||
die "badly formed metadata: $_\n" if !/^\\M\{([^\}]*)}\{([^\}]*)\}\s*$/;
|
||||
die "$outfile: badly formed metadata: $_\n" if !/^\\M\{([^\}]*)}\{([^\}]*)\}\s*$/;
|
||||
$metadata{$1} = $2;
|
||||
return; # avoid word-by-word code
|
||||
} elsif (/^\\([b\>q])/) {
|
||||
|
@ -425,7 +460,7 @@ sub got_para {
|
|||
$qindex = 1 if $1 eq "\\I";
|
||||
$indexing = 1, s/^\\[iI]// if $1;
|
||||
s/^\\c//;
|
||||
die "badly formatted \\c: \\c$_\n" if !/\{(([^\\}]|\\.)*)\}(.*)$/;
|
||||
die "$outfile: badly formatted \\c: \\c$_\n" if !/\{(([^\\}]|\\.)*)\}(.*)$/;
|
||||
$w = $1;
|
||||
$_ = $3;
|
||||
$w =~ s/\\\{/\{/g;
|
||||
|
@ -441,7 +476,7 @@ sub got_para {
|
|||
$indexing = 1, $type = "\\i" if $1;
|
||||
$emph = 1, $type = "\\e" if $2;
|
||||
s/^(\\[iI])?(\\e?)//;
|
||||
die "badly formatted $type: $type$_\n" if !/\{(([^\\}]|\\.)*)\}(.*)$/;
|
||||
die "$outfile: badly formatted $type: $type$_\n" if !/\{(([^\\}]|\\.)*)\}(.*)$/;
|
||||
$w = $1;
|
||||
$_ = $3;
|
||||
$w =~ s/\\\{/\{/g;
|
||||
|
@ -474,12 +509,12 @@ sub got_para {
|
|||
$t = "k ";
|
||||
$t = "kK" if /^\\K/;
|
||||
s/^\\[kK]//;
|
||||
die "badly formatted \\k: \\k$_\n" if !/\{([^\}]*)\}(.*)$/;
|
||||
die "$outfile: badly formatted \\k: \\k$_\n" if !/\{([^\}]*)\}(.*)$/;
|
||||
$_ = $2;
|
||||
push @$para,"$t$1";
|
||||
} elsif (/^\\[Ww]/) {
|
||||
if (/^\\w/) {
|
||||
die "badly formatted \\w: $_\n"
|
||||
die "$outfile: badly formatted \\w: $_\n"
|
||||
if !/^\\w(\\i)?\{([^\\}]*)\}(.*)$/;
|
||||
$l = $2;
|
||||
$w = $2;
|
||||
|
@ -487,7 +522,7 @@ sub got_para {
|
|||
$c = 1;
|
||||
$_ = $3;
|
||||
} else {
|
||||
die "badly formatted \\W: $_\n"
|
||||
die "$outfile: badly formatted \\W: $_\n"
|
||||
if !/^\\W\{([^\\}]*)\}(\\i)?(\\c)?\{(([^\\}]|\\.)*)\}(.*)$/;
|
||||
$l = $1;
|
||||
$w = $4;
|
||||
|
@ -503,8 +538,8 @@ sub got_para {
|
|||
push(@$para, addidx($node, $w, "c $w")) if $indexing;
|
||||
push(@$para, "$t<$l>$w");
|
||||
} else {
|
||||
die "what the hell? $_\n" if !/^(([^\s\\\-]|\\[\\{}\-])*-?)(.*)$/;
|
||||
die "painful death! $_\n" if !length $1;
|
||||
die "$outfile: what the hell? $_\n" if !/^(([^\s\\\-]|\\[\\{}\-])*-?)(.*)$/;
|
||||
die "$outfile: painful death! $_\n" if !length $1;
|
||||
$w = $1;
|
||||
$_ = $3;
|
||||
$w =~ s/\\\{/\{/g;
|
||||
|
@ -633,7 +668,7 @@ sub fixup_xrefs {
|
|||
$caps = ($k =~ /^kK/);
|
||||
$k = substr($k,2);
|
||||
$repl = $refs{$k};
|
||||
die "undefined keyword `$k'\n" unless $repl;
|
||||
die "$outfile: undefined keyword `$k'\n" unless $repl;
|
||||
substr($repl,0,1) =~ tr/a-z/A-Z/ if $caps;
|
||||
@repl = ();
|
||||
push @repl,"x $xrefs{$k}";
|
||||
|
@ -777,7 +812,7 @@ sub word_txt {
|
|||
} elsif ($wmajt eq "x" || $wmajt eq "i") {
|
||||
return "\001";
|
||||
} else {
|
||||
die "panic in word_txt: $wtype$w\n";
|
||||
die "$outfile: panic in word_txt: $wtype$w\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1142,7 +1177,7 @@ sub word_html($) {
|
|||
} elsif ($wmajt eq "i") {
|
||||
return "\001";
|
||||
} else {
|
||||
die "panic in word_html: $wtype$w\n";
|
||||
die "$outfile: panic in word_html: $wtype$w\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
811
doc/running.src
Normal file
811
doc/running.src
Normal file
|
@ -0,0 +1,811 @@
|
|||
\C{running} Running NASM
|
||||
|
||||
\H{syntax} NASM \i{Command-Line} Syntax
|
||||
|
||||
To assemble a file, you issue a command of the form
|
||||
|
||||
\c nasm -f <format> <filename> [-o <output>]
|
||||
|
||||
For example,
|
||||
|
||||
\c nasm -f elf myfile.asm
|
||||
|
||||
will assemble \c{myfile.asm} into an ELF object file \c{myfile.o}. And
|
||||
|
||||
\c nasm -f bin myfile.asm -o myfile.com
|
||||
|
||||
will assemble \c{myfile.asm} into a raw binary file \c{myfile.com}.
|
||||
|
||||
To produce a listing file, with the hex codes output from NASM
|
||||
displayed on the left of the original sources, use the \c{-l} option
|
||||
to give a listing file name, for example:
|
||||
|
||||
\c nasm -f coff myfile.asm -l myfile.lst
|
||||
|
||||
To get further usage instructions from NASM, try typing
|
||||
|
||||
\c nasm -h
|
||||
|
||||
The option \c{--help} is an alias for the \c{-h} option.
|
||||
|
||||
If you use Linux but aren't sure whether your system is \c{a.out}
|
||||
or ELF, type
|
||||
|
||||
\c file nasm
|
||||
|
||||
(in the directory in which you put the NASM binary when you
|
||||
installed it). If it says something like
|
||||
|
||||
\c nasm: ELF 32-bit LSB executable i386 (386 and up) Version 1
|
||||
|
||||
then your system is \c{ELF}, and you should use the option \c{-f elf}
|
||||
when you want NASM to produce Linux object files. If it says
|
||||
|
||||
\c nasm: Linux/i386 demand-paged executable (QMAGIC)
|
||||
|
||||
or something similar, your system is \c{a.out}, and you should use
|
||||
\c{-f aout} instead (Linux \c{a.out} systems have long been obsolete,
|
||||
and are rare these days.)
|
||||
|
||||
Like Unix compilers and assemblers, NASM is silent unless it
|
||||
goes wrong: you won't see any output at all, unless it gives error
|
||||
messages.
|
||||
|
||||
|
||||
\S{opt-o} The \i\c{-o} Option: Output File Name
|
||||
|
||||
NASM will normally choose the name of your output file for you;
|
||||
precisely how it does this is dependent on the object file format.
|
||||
For Microsoft object file formats (\c{obj}, \c{win32} and \c{win64}),
|
||||
it will remove the \c{.asm} \i{extension} (or whatever extension you
|
||||
like to use - NASM doesn't care) from your source file name and
|
||||
substitute \c{.obj}. For Unix object file formats (\c{aout}, \c{as86},
|
||||
\c{coff}, \c{elf32}, \c{elf64}, \c{elfx32}, \c{ieee}, \c{macho32} and
|
||||
\c{macho64}) it will substitute \c{.o}. For \c{dbg}, \c{ith}
|
||||
and \c{srec}, it will use \c{.dbg}, \c{.ith} and \c{.srec},
|
||||
respectively, and for the \c{bin} format it will simply remove the
|
||||
extension, so that \c{myfile.asm} produces the output file \c{myfile}.
|
||||
|
||||
If the output file already exists, NASM will overwrite it, unless it
|
||||
has the same name as the input file, in which case it will give a
|
||||
warning and use \i\c{nasm.out} as the output file name instead.
|
||||
|
||||
For situations in which this behaviour is unacceptable, NASM
|
||||
provides the \c{-o} command-line option, which allows you to specify
|
||||
your desired output file name. You invoke \c{-o} by following it
|
||||
with the name you wish for the output file, either with or without
|
||||
an intervening space. For example:
|
||||
|
||||
\c nasm -f bin program.asm -o program.com
|
||||
\c nasm -f bin driver.asm -odriver.sys
|
||||
|
||||
Note that this is a small o, and is different from a capital O , which
|
||||
is used to specify the number of optimization passes required. See \k{opt-O}.
|
||||
|
||||
|
||||
\S{opt-f} The \i\c{-f} Option: \i{Output File Format}
|
||||
|
||||
If you do not supply the \c{-f} option to NASM, it will choose an
|
||||
output file format for you itself. In the distribution versions of
|
||||
NASM, the default is always \i\c{bin}; if you've compiled your own
|
||||
copy of NASM, you can redefine \i\c{OF_DEFAULT} at compile time and
|
||||
choose what you want the default to be.
|
||||
|
||||
Like \c{-o}, the intervening space between \c{-f} and the output
|
||||
file format is optional; so \c{-f elf} and \c{-felf} are both valid.
|
||||
|
||||
A complete list of the available output file formats can be given by
|
||||
issuing the command \i\c{nasm -h}.
|
||||
|
||||
|
||||
\S{opt-l} The \i\c{-l} Option: Generating a \i{Listing File}
|
||||
|
||||
If you supply the \c{-l} option to NASM, followed (with the usual
|
||||
optional space) by a file name, NASM will generate a
|
||||
\i{source-listing file} for you, in which addresses and generated
|
||||
code are listed on the left, and the actual source code, with
|
||||
expansions of multi-line macros (except those which specifically
|
||||
request no expansion in source listings: see \k{nolist}) on the
|
||||
right. For example:
|
||||
|
||||
\c nasm -f elf myfile.asm -l myfile.lst
|
||||
|
||||
If a list file is selected, you may turn off listing for a
|
||||
section of your source with \c{[list -]}, and turn it back on
|
||||
with \c{[list +]}, (the default, obviously). There is no "user
|
||||
form" (without the brackets). This can be used to list only
|
||||
sections of interest, avoiding excessively long listings.
|
||||
|
||||
\S{opt-L} The \i\c{-L} Option: Additional or Modified Listing Info
|
||||
|
||||
Use this option to specify listing output details.
|
||||
|
||||
Supported options are:
|
||||
|
||||
\b \c{-Lb} show builtin macro packages (standard and \c{%use})
|
||||
|
||||
\b \c{-Ld} show byte and repeat counts in decimal, not hex
|
||||
|
||||
\b \c{-Le} show the preprocessed input
|
||||
|
||||
\b \c{-Lf} ignore \c{.nolist} and force listing output
|
||||
|
||||
\b \c{-Lm} show multi-line macro calls with expanded parameters
|
||||
|
||||
\b \c{-Lp} output a list file in every pass, in case of errors
|
||||
|
||||
\b \c{-Ls} show all single-line macro definitions
|
||||
|
||||
\b \c{-Lw} flush the output after every line (very slow, mainly useful
|
||||
to debug NASM crashes)
|
||||
|
||||
\b \c{-L+} enable \e{all} listing options except \c{-Lw} (very verbose)
|
||||
|
||||
These options can be enabled or disabled at runtime using the
|
||||
\c{%pragma list options} directive:
|
||||
|
||||
\c %pragma list options [+|-]flags...
|
||||
|
||||
For example, to turn on the \c{d} and \c{m} flags but disable the
|
||||
\c{s} flag:
|
||||
|
||||
\c %pragma list options +dm -s
|
||||
|
||||
For forward compatility reasons, an undefined flag will be
|
||||
ignored. Thus, a new flag introduced in a newer version of NASM can be
|
||||
specified without breaking older versions. Listing flags will always
|
||||
be a single alphanumeric character and are case sensitive.
|
||||
|
||||
\S{opt-M} The \i\c{-M} Option: Generate \i{Makefile Dependencies}
|
||||
|
||||
This option can be used to generate makefile dependencies on stdout.
|
||||
This can be redirected to a file for further processing. For example:
|
||||
|
||||
\c nasm -M myfile.asm > myfile.dep
|
||||
|
||||
|
||||
\S{opt-MG} The \i\c{-MG} Option: Generate \i{Makefile Dependencies}
|
||||
|
||||
This option can be used to generate makefile dependencies on stdout.
|
||||
This differs from the \c{-M} option in that if a nonexisting file is
|
||||
encountered, it is assumed to be a generated file and is added to the
|
||||
dependency list without a prefix.
|
||||
|
||||
|
||||
\S{opt-MF} The \i\c\{-MF} Option: Set Makefile Dependency File
|
||||
|
||||
This option can be used with the \c{-M} or \c{-MG} options to send the
|
||||
output to a file, rather than to stdout. For example:
|
||||
|
||||
\c nasm -M -MF myfile.dep myfile.asm
|
||||
|
||||
|
||||
\S{opt-MD} The \i\c{-MD} Option: Assemble and Generate Dependencies
|
||||
|
||||
The \c{-MD} option acts as the combination of the \c{-M} and \c{-MF}
|
||||
options (i.e. a filename has to be specified.) However, unlike the
|
||||
\c{-M} or \c{-MG} options, \c{-MD} does \e{not} inhibit the normal
|
||||
operation of the assembler. Use this to automatically generate
|
||||
updated dependencies with every assembly session. For example:
|
||||
|
||||
\c nasm -f elf -o myfile.o -MD myfile.dep myfile.asm
|
||||
|
||||
If the argument after \c{-MD} is an option rather than a filename,
|
||||
then the output filename is the first applicable one of:
|
||||
|
||||
\b the filename set in the \c{-MF} option;
|
||||
|
||||
\b the output filename from the \c{-o} option with \c{.d} appended;
|
||||
|
||||
\b the input filename with the extension set to \c{.d}.
|
||||
|
||||
|
||||
\S{opt-MT} The \i\c{-MT} Option: Dependency Target Name
|
||||
|
||||
The \c{-MT} option can be used to override the default name of the
|
||||
dependency target. This is normally the same as the output filename,
|
||||
specified by the \c{-o} option.
|
||||
|
||||
|
||||
\S{opt-MQ} The \i\c{-MQ} Option: Dependency Target Name (Quoted)
|
||||
|
||||
The \c{-MQ} option acts as the \c{-MT} option, except it tries to
|
||||
quote characters that have special meaning in Makefile syntax. This
|
||||
is not foolproof, as not all characters with special meaning are
|
||||
quotable in \c{make}. The default output (if no \c{-MT} or \c{-MQ} option
|
||||
is specified) is automatically quoted.
|
||||
|
||||
|
||||
\S{opt-MP} The \i\c{-MP} Option: Emit Phony Makefile Targets
|
||||
|
||||
When used with any of the dependency generation options, the \c{-MP}
|
||||
option causes NASM to emit a phony target without dependencies for
|
||||
each header file. This prevents \c{make} from complaining if a header
|
||||
file has been removed.
|
||||
|
||||
|
||||
\S{opt-MW} The \i\c{-MW} Option: Watcom \c{make} quoting style
|
||||
|
||||
This option causes NASM to attempt to quote dependencies according to
|
||||
Watcom \c{make} conventions rather than POSIX \c{make} conventions (also used
|
||||
by most other \c{make} variants.) This quotes \c{#} as \c{$#} rather than
|
||||
\c{\\#}, uses \c{&} rather than \c{\\} for continuation lines, and
|
||||
encloses filenames containing whitespace in double quotes.
|
||||
|
||||
|
||||
\S{opt-F} The \i\c{-F} Option: \i{Debug Information Format}
|
||||
|
||||
This option is used to select the format of the debug information
|
||||
emitted into the output file, to be used by a debugger (or \e{will}
|
||||
be). Prior to version 2.03.01, the use of this switch did \e{not} enable
|
||||
output of the selected debug info format. Use \c{-g}, see \k{opt-g},
|
||||
to enable output. Versions 2.03.01 and later automatically enable \c{-g}
|
||||
if \c{-F} is specified.
|
||||
|
||||
A complete list of the available debug file formats for an output
|
||||
format can be seen by issuing the command \c{nasm -h}. Not
|
||||
all output formats currently support debugging output.
|
||||
|
||||
This should not be confused with the \c{-f dbg} output format option,
|
||||
see \k{dbgfmt}.
|
||||
|
||||
|
||||
\S{opt-g} The \i\c{-g} Option: Enabling \i{Debug Information}.
|
||||
|
||||
This option can be used to generate debugging information in the specified
|
||||
format. See \k{opt-F}. Using \c{-g} without \c{-F} results in emitting
|
||||
debug info in the default format, if any, for the selected output format.
|
||||
If no debug information is currently implemented in the selected output
|
||||
format, \c{-g} is \e{silently ignored}.
|
||||
|
||||
|
||||
\S{opt-X} The \i\c{-X} Option: Selecting an \i{Error Reporting Format}
|
||||
|
||||
This option can be used to select an error reporting format for any
|
||||
error messages that might be produced by NASM.
|
||||
|
||||
Currently, two error reporting formats may be selected. They are
|
||||
the \c{-Xvc} option and the \c{-Xgnu} option. The GNU format is
|
||||
the default and looks like this:
|
||||
|
||||
\c filename.asm:65: error: specific error message
|
||||
|
||||
where \c{filename.asm} is the name of the source file in which the
|
||||
error was detected, \c{65} is the source file line number on which
|
||||
the error was detected, \c{error} is the severity of the error (this
|
||||
could be \c{warning}), and \c{specific error message} is a more
|
||||
detailed text message which should help pinpoint the exact problem.
|
||||
|
||||
The other format, specified by \c{-Xvc} is the style used by Microsoft
|
||||
Visual C++ and some other programs. It looks like this:
|
||||
|
||||
\c filename.asm(65) : error: specific error message
|
||||
|
||||
where the only difference is that the line number is in parentheses
|
||||
instead of being delimited by colons.
|
||||
|
||||
See also the \c{Visual C++} output format, \k{win32fmt}.
|
||||
|
||||
\S{opt-Z} The \i\c{-Z} Option: Send Errors to a File
|
||||
|
||||
Under \I{DOS}\c{MS-DOS} it can be difficult (though there are ways) to
|
||||
redirect the standard-error output of a program to a file. Since
|
||||
NASM usually produces its warning and \i{error messages} on
|
||||
\i\c{stderr}, this can make it hard to capture the errors if (for
|
||||
example) you want to load them into an editor.
|
||||
|
||||
NASM therefore provides the \c{-Z} option, taking a filename argument
|
||||
which causes errors to be sent to the specified files rather than
|
||||
standard error. Therefore you can \I{redirecting errors}redirect
|
||||
the errors into a file by typing
|
||||
|
||||
\c nasm -Z myfile.err -f obj myfile.asm
|
||||
|
||||
In earlier versions of NASM, this option was called \c{-E}, but it was
|
||||
changed since \c{-E} is an option conventionally used for
|
||||
preprocessing only, with disastrous results. See \k{opt-E}.
|
||||
|
||||
\S{opt-s} The \i\c{-s} Option: Send Errors to \i\c{stdout}
|
||||
|
||||
The \c{-s} option redirects \i{error messages} to \c{stdout} rather
|
||||
than \c{stderr}, so it can be redirected under \I{DOS}\c{MS-DOS}. To
|
||||
assemble the file \c{myfile.asm} and pipe its output to the \c{more}
|
||||
program, you can type:
|
||||
|
||||
\c nasm -s -f obj myfile.asm | more
|
||||
|
||||
See also the \c{-Z} option, \k{opt-Z}.
|
||||
|
||||
|
||||
\S{opt-i} The \i\c{-i}\I\c{-I} Option: Include File Search Directories
|
||||
|
||||
When NASM sees the \i\c{%include} or \i\c{%pathsearch} directive in a
|
||||
source file (see \k{include}, \k{pathsearch} or \k{incbin}), it will
|
||||
search for the given file not only in the current directory, but also
|
||||
in any directories specified on the command line by the use of the
|
||||
\c{-i} option. Therefore you can include files from a \i{macro
|
||||
library}, for example, by typing
|
||||
|
||||
\c nasm -ic:\macrolib\ -f obj myfile.asm
|
||||
|
||||
(As usual, a space between \c{-i} and the path name is allowed, and
|
||||
optional).
|
||||
|
||||
Prior NASM 2.14 a path provided in the option has been considered as
|
||||
a verbatim copy and providing a path separator been up to a caller.
|
||||
One could implicitly concatenate a search path together with a filename.
|
||||
Still this was rather a trick than something useful. Now the trailing
|
||||
path separator is made to always present, thus \c{-ifoo} will be
|
||||
considered as the \c{-ifoo/} directory.
|
||||
|
||||
If you want to define a \e{standard} \i{include search path},
|
||||
similar to \c{/usr/include} on Unix systems, you should place one or
|
||||
more \c{-i} directives in the \c{NASMENV} environment variable (see
|
||||
\k{nasmenv}).
|
||||
|
||||
For Makefile compatibility with many C compilers, this option can also
|
||||
be specified as \c{-I}.
|
||||
|
||||
|
||||
\S{opt-p} The \i\c{-p}\I\c{-P} Option: \I{pre-including files}Pre-Include a File
|
||||
|
||||
\I\c{%include}NASM allows you to specify files to be
|
||||
\e{pre-included} into your source file, by the use of the \c{-p}
|
||||
option. So running
|
||||
|
||||
\c nasm myfile.asm -p myinc.inc
|
||||
|
||||
is equivalent to running \c{nasm myfile.asm} and placing the
|
||||
directive \c{%include "myinc.inc"} at the start of the file.
|
||||
|
||||
\c{--include} option is also accepted.
|
||||
|
||||
For consistency with the \c{-I}, \c{-D} and \c{-U} options, this
|
||||
option can also be specified as \c{-P}.
|
||||
|
||||
|
||||
|
||||
\S{opt-d} The \i\c{-d}\I\c{-D} Option: \I{pre-defining macros}Pre-Define a Macro
|
||||
|
||||
\I\c{%define}Just as the \c{-p} option gives an alternative to placing
|
||||
\c{%include} directives at the start of a source file, the \c{-d}
|
||||
option gives an alternative to placing a \c{%define} directive. You
|
||||
could code
|
||||
|
||||
\c nasm myfile.asm -dFOO=100
|
||||
|
||||
as an alternative to placing the directive
|
||||
|
||||
\c %define FOO 100
|
||||
|
||||
at the start of the file. You can miss off the macro value, as well:
|
||||
the option \c{-dFOO} is equivalent to coding \c{%define FOO}. This
|
||||
form of the directive may be useful for selecting \i{assembly-time
|
||||
options} which are then tested using \c{%ifdef}, for example
|
||||
\c{-dDEBUG}.
|
||||
|
||||
For Makefile compatibility with many C compilers, this option can also
|
||||
be specified as \c{-D}.
|
||||
|
||||
|
||||
\S{opt-u} The \i\c{-u}\I\c{-U} Option: \I{Undefining macros}Undefine a Macro
|
||||
|
||||
\I\c{%undef}The \c{-u} option undefines a macro that would otherwise
|
||||
have been pre-defined, either automatically or by a \c{-p} or \c{-d}
|
||||
option specified earlier on the command lines.
|
||||
|
||||
For example, the following command line:
|
||||
|
||||
\c nasm myfile.asm -dFOO=100 -uFOO
|
||||
|
||||
would result in \c{FOO} \e{not} being a predefined macro in the
|
||||
program. This is useful to override options specified at a different
|
||||
point in a Makefile.
|
||||
|
||||
For Makefile compatibility with many C compilers, this option can also
|
||||
be specified as \c{-U}.
|
||||
|
||||
|
||||
\S{opt-E} The \i\c{-E}\I{-e} Option: Preprocess Only
|
||||
|
||||
NASM allows the \i{preprocessor} to be run on its own, up to a
|
||||
point. Using the \c{-E} option (which requires no arguments) will
|
||||
cause NASM to preprocess its input file, expand all the macro
|
||||
references, remove all the comments and preprocessor directives, and
|
||||
print the resulting file on standard output (or save it to a file,
|
||||
if the \c{-o} option is also used).
|
||||
|
||||
This option cannot be applied to programs which require the
|
||||
preprocessor to evaluate \I{preprocessor expressions}\i{expressions}
|
||||
which depend on the values of symbols: so code such as
|
||||
|
||||
\c %assign tablesize ($-tablestart)
|
||||
|
||||
will cause an error in \i{preprocess-only mode}.
|
||||
|
||||
For compatibility with older version of NASM, this option can also be
|
||||
written \c{-e}. \c{-E} in older versions of NASM was the equivalent
|
||||
of the current \c{-Z} option, \k{opt-Z}.
|
||||
|
||||
\S{opt-a} The \i\c{-a} Option: Suppress Preprocessing
|
||||
|
||||
If NASM is being used as the back end to a compiler, it might be
|
||||
desirable to \I{suppressing preprocessing}suppress preprocessing
|
||||
completely and assume the compiler has already done it, to save time
|
||||
and increase compilation speeds. The \c{-a} option, requiring no
|
||||
argument, instructs NASM to replace its powerful \i{preprocessor}
|
||||
with a \i{stub preprocessor} which does nothing.
|
||||
|
||||
|
||||
\S{opt-O} The \i\c{-O} Option: \i{Multipass Optimization}
|
||||
|
||||
Using the \c{-O} option, you can tell NASM to carry out different
|
||||
levels of optimization. Multiple flags can be specified after the
|
||||
\c{-O} options, some of which can be combined in a single option,
|
||||
e.g. \c{-Oxv}.
|
||||
|
||||
\b \c{-O0}: No optimization. All operands take their long forms,
|
||||
if a short form is not specified, except conditional jumps.
|
||||
This is intended to match NASM 0.98 behavior.
|
||||
|
||||
\b \c{-O1}: Minimal optimization. As above, but immediate operands
|
||||
which will fit in a signed byte are optimized,
|
||||
unless the long form is specified. Conditional jumps default
|
||||
to the long form unless otherwise specified.
|
||||
|
||||
\b \c{-Ox} (where \c{x} is the actual letter \c{x}): Multipass optimization.
|
||||
Minimize branch offsets and signed immediate bytes,
|
||||
overriding size specification unless the \c{strict} keyword
|
||||
has been used (see \k{strict}). For compatibility with earlier
|
||||
releases, the letter \c{x} may also be any number greater than
|
||||
one. This number has no effect on the actual number of passes.
|
||||
|
||||
\b \c{-Ov}: At the end of assembly, print the number of passes
|
||||
actually executed.
|
||||
|
||||
The \c{-Ox} mode is recommended for most uses, and is the default
|
||||
since NASM 2.09. \e{Any other mode will generate worse quality
|
||||
output.} Use \c{-O0} or \c{-O1} only if you need the finer
|
||||
programmer-level control of output and \c{strict} is not suitable for
|
||||
your use case.
|
||||
|
||||
Note that this is a capital \c{O}, and is different from a small \c{o}, which
|
||||
is used to specify the output file name. See \k{opt-o}.
|
||||
|
||||
|
||||
\S{opt-t} The \i\c{-t} Option: \i{TASM} Compatibility Mode
|
||||
|
||||
NASM includes a limited form of compatibility with Borland's TASM.
|
||||
When NASM's \c{-t} option is used, the following changes are made:
|
||||
|
||||
\b local labels may be prefixed with \c{@@} instead of \c{.}
|
||||
|
||||
\b size override is supported within brackets. In TASM compatible mode,
|
||||
a size override inside square brackets changes the size of the operand,
|
||||
and not the address type of the operand as it does in NASM syntax. E.g.
|
||||
\c{mov eax,[DWORD val]} is valid syntax in TASM compatibility mode.
|
||||
Note that you lose the ability to override the default address type for
|
||||
the instruction.
|
||||
|
||||
\b unprefixed forms of some directives supported (\c{arg}, \c{elif},
|
||||
\c{else}, \c{endif}, \c{if}, \c{ifdef}, \c{ifdifi}, \c{ifndef},
|
||||
\c{include}, \c{local})
|
||||
|
||||
\S{opt-w} The \i\c{-w} and \i\c{-W} Options: Enable or Disable Assembly \i{Warnings}
|
||||
|
||||
NASM can observe many conditions during the course of assembly which
|
||||
are worth mentioning to the user, but not a sufficiently severe
|
||||
error to justify NASM refusing to generate an output file. These
|
||||
conditions are reported like errors, but come up with the word
|
||||
`warning' before the message. Warnings do not prevent NASM from
|
||||
generating an output file and returning a success status to the
|
||||
operating system.
|
||||
|
||||
Some conditions are even less severe than that: they are only
|
||||
sometimes worth mentioning to the user. Therefore NASM supports the
|
||||
\c{-w} command-line option, which enables or disables certain
|
||||
classes of assembly warning. Such warning classes are described by a
|
||||
name, for example \c{label-orphan}; you can enable warnings of
|
||||
this class by the command-line option \c{-w+label-orphan} and
|
||||
disable it by \c{-w-label-orphan}.
|
||||
|
||||
Since version 2.15, NASM has group aliases for all prefixed warnings,
|
||||
so they can be used to enable or disable all warnings in the group.
|
||||
For example, -w+float enables all warnings with names starting with float-*.
|
||||
|
||||
Since version 2.00, NASM has also supported the \c{gcc}-like syntax
|
||||
\c{-Wwarning-class} and \c{-Wno-warning-class} instead of
|
||||
\c{-w+warning-class} and \c{-w-warning-class}, respectively; both
|
||||
syntaxes work identically.
|
||||
|
||||
The option \c{-w+error} or \i\c{-Werror} can be used to treat warnings
|
||||
as errors. This can be controlled on a per warning class basis
|
||||
(\c{-w+error=}\e{warning-class} or \c{-Werror=}\e{warning-class});
|
||||
if no \e{warning-class} is specified NASM treats it as
|
||||
\c{-w+error=all}; the same applies to \c{-w-error} or
|
||||
\i\c{-Wno-error},
|
||||
of course.
|
||||
|
||||
In addition, you can control warnings in the source code itself, using
|
||||
the \i\c{[WARNING]} directive. See \k{asmdir-warning}.
|
||||
|
||||
See \k{warnings} for the complete list of warning classes.
|
||||
|
||||
\S{opt-v} The \i\c{-v} Option: Display \i{Version} Info
|
||||
|
||||
Typing \c{NASM -v} will display the version of NASM which you are using,
|
||||
and the date on which it was compiled.
|
||||
|
||||
You will need the version number if you report a bug.
|
||||
|
||||
For command-line compatibility with Yasm, the form \i\c{--v} is also
|
||||
accepted for this option starting in NASM version 2.11.05.
|
||||
|
||||
|
||||
\S{opt-pfix} The \i\c{--(g|l)prefix}, \i\c{--(g|l)postfix} Options.
|
||||
|
||||
The \c{--(g)prefix} options prepend the given argument
|
||||
to all \c{extern}, \c{common}, \c{static}, and \c{global} symbols, and the
|
||||
\c{--lprefix} option prepends to all other symbols. Similarly,
|
||||
\c{--(g)postfix} and \c{--lpostfix} options append
|
||||
the argument in the exactly same way as the \c{--xxprefix} options does.
|
||||
|
||||
Running this:
|
||||
|
||||
\c nasm -f macho --gprefix _
|
||||
|
||||
is equivalent to place the directive with \c{%pragma macho gprefix _}
|
||||
at the start of the file (\k{mangling}). It will prepend the underscore
|
||||
to all global and external variables, as C requires it in some, but not all,
|
||||
system calling conventions.
|
||||
|
||||
\S{opt-pragma} The \i\c{--pragma} Option
|
||||
|
||||
NASM accepts an argument as \c{%pragma} option, which is like placing
|
||||
a \c{%pragma} preprocess statement at the beginning of the source.
|
||||
Running this:
|
||||
|
||||
\c nasm -f macho --pragma "macho gprefix _"
|
||||
|
||||
is equivalent to the example in \k{opt-pfix}. See \k{pragma}.
|
||||
|
||||
|
||||
\S{opt-before} The \i\c{--before} Option
|
||||
|
||||
A preprocess statement can be accepted with this option. The example
|
||||
shown in \k{opt-pragma} is the same as running this:
|
||||
|
||||
\c nasm -f macho --before "%pragma macho gprefix _"
|
||||
|
||||
|
||||
\S{opt-limit} The \i\c{--limit-X} Option
|
||||
|
||||
This option allows user to setup various maximum values after which
|
||||
NASM will terminate with a fatal error rather than consume arbitrary
|
||||
amount of compute time. Each limit can be set to a positive number or
|
||||
\c{unlimited}.
|
||||
|
||||
\b\c{--limit-passes}: Number of maximum allowed passes. Default is
|
||||
\c{unlimited}.
|
||||
|
||||
\b\c{--limit-stalled-passes}: Maximum number of allowed unfinished
|
||||
passes. Default is 1000.
|
||||
|
||||
\b\c{--limit-macro-levels}: Define maximum depth of macro expansion
|
||||
(in preprocess). Default is 10000
|
||||
|
||||
\b\c{--limit-macro-tokens}: Maximum number of tokens processed during
|
||||
single-line macro expansion. Default is 10000000.
|
||||
|
||||
\b\c{--limit-mmacros}: Maximum number of multi-line macros processed
|
||||
before returning to the top-level input. Default is 100000.
|
||||
|
||||
\b\c{--limit-rep}: Maximum number of allowed preprocessor loop, defined
|
||||
under \c{%rep}. Default is 1000000.
|
||||
|
||||
\b\c{--limit-eval}: This number sets the boundary condition of allowed
|
||||
expression length. Default is 8192 on most systems.
|
||||
|
||||
\b\c{--limit-lines}: Total number of source lines allowed to be
|
||||
processed. Default is 2000000000.
|
||||
|
||||
For example, set the maximum line count to 1000:
|
||||
|
||||
\c nasm --limit-lines 1000
|
||||
|
||||
Limits can also be set via the directive \c{%pragma limit}, for
|
||||
example:
|
||||
|
||||
\c %pragma limit lines 1000
|
||||
|
||||
|
||||
\S{opt-keep-all} The \i\c{--keep-all} Option
|
||||
|
||||
This option prevents NASM from deleting any output files even if an
|
||||
error happens.
|
||||
|
||||
\S{opt-no-line} The \i\c{--no-line} Option
|
||||
|
||||
If this option is given, all \i\c{%line} directives in the source code
|
||||
are ignored. This can be useful for debugging already preprocessed
|
||||
code. See \k{line}.
|
||||
|
||||
\S{opt-reproducible} The \i\c{--reproducible} Option
|
||||
|
||||
If this option is given, NASM will not emit information that is
|
||||
inherently dependent on the NASM version or different from run to run
|
||||
(such as timestamps) into the output file.
|
||||
|
||||
|
||||
\S{nasmenv} The \i\c{NASMENV} \i{Environment} Variable
|
||||
|
||||
If you define an environment variable called \c{NASMENV}, the program
|
||||
will interpret it as a list of extra command-line options, which are
|
||||
processed before the real command line. You can use this to define
|
||||
standard search directories for include files, by putting \c{-i}
|
||||
options in the \c{NASMENV} variable.
|
||||
|
||||
The value of the variable is split up at white space, so that the
|
||||
value \c{-s -ic:\\nasmlib\\} will be treated as two separate options.
|
||||
However, that means that the value \c{-dNAME="my name"} won't do
|
||||
what you might want, because it will be split at the space and the
|
||||
NASM command-line processing will get confused by the two
|
||||
nonsensical words \c{-dNAME="my} and \c{name"}.
|
||||
|
||||
To get round this, NASM provides a feature whereby, if you begin the
|
||||
\c{NASMENV} environment variable with some character that isn't a minus
|
||||
sign, then NASM will treat this character as the \i{separator
|
||||
character} for options. So setting the \c{NASMENV} variable to the
|
||||
value \c{!-s!-ic:\\nasmlib\\} is equivalent to setting it to \c{-s
|
||||
-ic:\\nasmlib\\}, but \c{!-dNAME="my name"} will work.
|
||||
|
||||
This environment variable was previously called \c{NASM}. This was
|
||||
changed with version 0.98.31.
|
||||
|
||||
|
||||
\H{qstart} \i{Quick Start} for \i{MASM} Users
|
||||
|
||||
If you're used to writing programs with MASM, or with \i{TASM} in
|
||||
MASM-compatible (non-Ideal) mode, or with \i\c{a86}, this section
|
||||
attempts to outline the major differences between MASM's syntax and
|
||||
NASM's. If you're not already used to MASM, it's probably worth
|
||||
skipping this section.
|
||||
|
||||
|
||||
\S{qscs} NASM Is \I{case sensitivity}Case-Sensitive
|
||||
|
||||
One simple difference is that NASM is case-sensitive. It makes a
|
||||
difference whether you call your label \c{foo}, \c{Foo} or \c{FOO}.
|
||||
If you're assembling to \c{DOS} or \c{OS/2} \c{.OBJ} files, you can
|
||||
invoke the \i\c{UPPERCASE} directive (documented in \k{objfmt}) to
|
||||
ensure that all symbols exported to other code modules are forced
|
||||
to be upper case; but even then, \e{within} a single module, NASM
|
||||
will distinguish between labels differing only in case.
|
||||
|
||||
|
||||
\S{qsbrackets} NASM Requires \i{Square Brackets} For \i{Memory References}
|
||||
|
||||
NASM was designed with simplicity of syntax in mind. One of the
|
||||
\i{design goals} of NASM is that it should be possible, as far as is
|
||||
practical, for the user to look at a single line of NASM code
|
||||
and tell what opcode is generated by it. You can't do this in MASM:
|
||||
if you declare, for example,
|
||||
|
||||
\c foo equ 1
|
||||
\c bar dw 2
|
||||
|
||||
then the two lines of code
|
||||
|
||||
\c mov ax,foo
|
||||
\c mov ax,bar
|
||||
|
||||
generate completely different opcodes, despite having
|
||||
identical-looking syntaxes.
|
||||
|
||||
NASM avoids this undesirable situation by having a much simpler
|
||||
syntax for memory references. The rule is simply that any access to
|
||||
the \e{contents} of a memory location requires square brackets
|
||||
around the address, and any access to the \e{address} of a variable
|
||||
doesn't. So an instruction of the form \c{mov ax,foo} will
|
||||
\e{always} refer to a compile-time constant, whether it's an \c{EQU}
|
||||
or the address of a variable; and to access the \e{contents} of the
|
||||
variable \c{bar}, you must code \c{mov ax,[bar]}.
|
||||
|
||||
This also means that NASM has no need for MASM's \i\c{OFFSET}
|
||||
keyword, since the MASM code \c{mov ax,offset bar} means exactly the
|
||||
same thing as NASM's \c{mov ax,bar}. If you're trying to get
|
||||
large amounts of MASM code to assemble sensibly under NASM, you
|
||||
can always code \c{%idefine offset} to make the preprocessor treat
|
||||
the \c{OFFSET} keyword as a no-op.
|
||||
|
||||
This issue is even more confusing in \i\c{a86}, where declaring a
|
||||
label with a trailing colon defines it to be a `label' as opposed to
|
||||
a `variable' and causes \c{a86} to adopt NASM-style semantics; so in
|
||||
\c{a86}, \c{mov ax,var} has different behaviour depending on whether
|
||||
\c{var} was declared as \c{var: dw 0} (a label) or \c{var dw 0} (a
|
||||
word-size variable). NASM is very simple by comparison:
|
||||
\e{everything} is a label.
|
||||
|
||||
NASM, in the interests of simplicity, also does not support the
|
||||
\i{hybrid syntaxes} supported by MASM and its clones, such as
|
||||
\c{mov ax,table[bx]}, where a memory reference is denoted by one
|
||||
portion outside square brackets and another portion inside. The
|
||||
correct syntax for the above is \c{mov ax,[table+bx]}. Likewise,
|
||||
\c{mov ax,es:[di]} is wrong and \c{mov ax,[es:di]} is right.
|
||||
|
||||
|
||||
\S{qstypes} NASM Doesn't Store \i{Variable Types}
|
||||
|
||||
NASM, by design, chooses not to remember the types of variables you
|
||||
declare. Whereas MASM will remember, on seeing \c{var dw 0}, that
|
||||
you declared \c{var} as a word-size variable, and will then be able
|
||||
to fill in the \i{ambiguity} in the size of the instruction \c{mov
|
||||
var,2}, NASM will deliberately remember nothing about the symbol
|
||||
\c{var} except where it begins, and so you must explicitly code
|
||||
\c{mov word [var],2}.
|
||||
|
||||
For this reason, NASM doesn't support the \c{LODS}, \c{MOVS},
|
||||
\c{STOS}, \c{SCAS}, \c{CMPS}, \c{INS}, or \c{OUTS} instructions,
|
||||
but only supports the forms such as \c{LODSB}, \c{MOVSW}, and
|
||||
\c{SCASD}, which explicitly specify the size of the components of
|
||||
the strings being manipulated.
|
||||
|
||||
|
||||
\S{qsassume} NASM Doesn't \i\c{ASSUME}
|
||||
|
||||
As part of NASM's drive for simplicity, it also does not support the
|
||||
\c{ASSUME} directive. NASM will not keep track of what values you
|
||||
choose to put in your segment registers, and will never
|
||||
\e{automatically} generate a \i{segment override} prefix.
|
||||
|
||||
|
||||
\S{qsmodel} NASM Doesn't Support \i{Memory Models}
|
||||
|
||||
NASM also does not have any directives to support different 16-bit
|
||||
memory models. The programmer has to keep track of which functions
|
||||
are supposed to be called with a \i{far call} and which with a
|
||||
\i{near call}, and is responsible for putting the correct form of
|
||||
\c{RET} instruction (\c{RETN} or \c{RETF}; NASM accepts \c{RET}
|
||||
itself as an alternate form for \c{RETN}); in addition, the
|
||||
programmer is responsible for coding CALL FAR instructions where
|
||||
necessary when calling \e{external} functions, and must also keep
|
||||
track of which external variable definitions are far and which are
|
||||
near.
|
||||
|
||||
|
||||
\S{qsfpu} \i{Floating-Point} Differences
|
||||
|
||||
NASM uses different names to refer to floating-point registers from
|
||||
MASM: where MASM would call them \c{ST(0)}, \c{ST(1)} and so on, and
|
||||
\i\c{a86} would call them simply \c{0}, \c{1} and so on, NASM
|
||||
chooses to call them \c{st0}, \c{st1} etc.
|
||||
|
||||
As of version 0.96, NASM now treats the instructions with
|
||||
\i{`nowait'} forms in the same way as MASM-compatible assemblers.
|
||||
The idiosyncratic treatment employed by 0.95 and earlier was based
|
||||
on a misunderstanding by the authors.
|
||||
|
||||
|
||||
\S{qsother} Other Differences
|
||||
|
||||
For historical reasons, NASM uses the keyword \i\c{TWORD} where MASM
|
||||
and compatible assemblers use \i\c{TBYTE}.
|
||||
|
||||
Historically, NASM does not declare \i{uninitialized storage} in the
|
||||
same way as MASM: where a MASM programmer might use \c{stack db 64 dup
|
||||
(?)}, NASM requires \c{stack resb 64}, intended to be read as `reserve
|
||||
64 bytes'. For a limited amount of compatibility, since NASM treats
|
||||
\c{?} as a valid character in symbol names, you can code \c{? equ 0}
|
||||
and then writing \c{dw ?} will at least do something vaguely useful.
|
||||
|
||||
As of NASM 2.15, the MASM syntax is also supported.
|
||||
|
||||
In addition to all of this, macros and directives work completely
|
||||
differently to MASM. See \k{preproc} and \k{directive} for further
|
||||
details.
|
||||
|
||||
\S{masm-compat} MASM compatibility package
|
||||
|
||||
See \k{pkg_masm}.
|
||||
|
||||
|
147
doc/source.src
Normal file
147
doc/source.src
Normal file
|
@ -0,0 +1,147 @@
|
|||
\A{source} Building NASM from Source
|
||||
|
||||
The source code for NASM is available from our website,
|
||||
\w{https://www.nasm.us/}, see \k{website}.
|
||||
|
||||
\H{tarball} Building from a Source Archive
|
||||
|
||||
The source archives available on the web site should be capable of
|
||||
building on a number of platforms. This is the recommended method for
|
||||
building NASM to support platforms for which executables are not
|
||||
available, if you do not require changing the source code.
|
||||
|
||||
The preferred build platforms are development environments which
|
||||
support POSIX (Unix)-style tools (a "POSIX environment"). For Windows,
|
||||
MSYS2 (\w{https://www.msys2.org/}) is such a development environment.
|
||||
|
||||
In a POSIX environment, run:
|
||||
|
||||
\c sh configure
|
||||
\c make
|
||||
|
||||
A number of options can be passed to \c{configure}; see
|
||||
\c{sh configure --help}. In particular, the \c{--host} option can be
|
||||
used to cross-compile NASM to run on another host system.
|
||||
|
||||
For non-POSIX environments, a set of Makefiles for some other
|
||||
environments are also available; please see the file
|
||||
\c{Mkfiles/README}.
|
||||
|
||||
The \c{.zip} version of the source archive has DOS/Windows line
|
||||
endings (\c{CR LF}), which many POSIX systems will not recognize. To
|
||||
extract the \c{.zip} version on such a system, use \c{unzip
|
||||
-a}. The \c{.tar} versions of the source archive has POSIX line
|
||||
endings (\c{LF}).
|
||||
|
||||
|
||||
\H{buildtools} Optional Build Tools
|
||||
|
||||
The following additional tools are required to build specific
|
||||
subsystems, to build from the \c{git} repository, or if the sources
|
||||
are modified.
|
||||
|
||||
Note that some of these tools will have their own dependencies.
|
||||
|
||||
Make sure all tools are available in your \c{PATH} (or equivalent.)
|
||||
|
||||
To build the installer for the Windows platform:
|
||||
|
||||
\b The \i{Nullsoft Scriptable Installer} (\i{NSIS},
|
||||
\w{https://nsis-dev.github.io/}).
|
||||
|
||||
To modify the sources, \e{or} to build the documentation:
|
||||
|
||||
\b A Perl interpreter (\w{https://www.perl.org/}).
|
||||
|
||||
\b Modules from CPAN (\w{https://www.cpan.org/}). The following Perl
|
||||
modules are currently required, some of which will be bundled with the
|
||||
Perl interpreter or into larger CPAN packages:
|
||||
|
||||
\& perlbreq.src
|
||||
|
||||
To build the documentation:
|
||||
|
||||
\b Either Ghostscript (\w{https://www.ghostscript.com/}) or Adobe
|
||||
Acrobat Distiller (untested.)
|
||||
|
||||
\b The Adobe \e{Source Sans} (or \e{Source Sans 3}) and \e{Source
|
||||
Code} fonts, which are freely available under the SIL Open Font
|
||||
License (\w{https://fonts.adobe.com/}).
|
||||
|
||||
To build the Unix man pages:
|
||||
|
||||
\b AsciiDoc (\w{https://asciidoc.org/}).
|
||||
|
||||
\b xmlto (\w{https://pagure.io/xmlto/}).
|
||||
|
||||
To build from the \c{git} repository on a POSIX platform:
|
||||
|
||||
\b GNU \c{m4}, \c{autoconf} and \c{autoheader}
|
||||
(\w{https://www.gnu.org/}).
|
||||
|
||||
|
||||
|
||||
\H{buildopt} Building Optional Components
|
||||
|
||||
Install the required tools for the subsystem in question as described
|
||||
in \k{buildtools}.
|
||||
|
||||
To build the documentation:
|
||||
|
||||
\c make doc
|
||||
|
||||
Building the documentation may not work in a non-POSIX environment.
|
||||
|
||||
To build the Windows installer:
|
||||
|
||||
\c make nsis
|
||||
|
||||
To build the Unix man pages:
|
||||
|
||||
\c make manpages
|
||||
|
||||
To build everything available on the current platform:
|
||||
|
||||
\c make everything
|
||||
|
||||
|
||||
\H{git} Building from the \i\c{git} Repository
|
||||
|
||||
The NASM development tree is kept in a source code repository using
|
||||
the \c{git} distributed source control system. The link is available
|
||||
on the website. This is recommended only to participate in the
|
||||
development of NASM or to assist with testing the development code.
|
||||
|
||||
Install the required tools as described in section \k{buildtools}.
|
||||
|
||||
In a POSIX environment:
|
||||
|
||||
Run:
|
||||
|
||||
\c sh autogen.sh
|
||||
|
||||
to create the \c{configure} script and then build as described in
|
||||
\k{tarball}.
|
||||
|
||||
In a non-POSIX environment, use the tool-specific Makefiles
|
||||
as described in \k{tarball}.
|
||||
|
||||
|
||||
\H{modifysrc} Modifying the Sources
|
||||
|
||||
To build modified sources, you will need the tools described in
|
||||
\k{buildtools}.
|
||||
|
||||
Some build system changes might not be possible without a POSIX
|
||||
environment.
|
||||
|
||||
If you have modified the sources to change the embedded declarations
|
||||
of warning classes, you may have to manually re-build the warning
|
||||
catalog:
|
||||
|
||||
\c make warnings
|
||||
|
||||
This is not done automatically, as the tools do not have the ability
|
||||
to automatically detect when it is necessary to do so.
|
||||
|
||||
|
416
doc/stdmac.src
Normal file
416
doc/stdmac.src
Normal file
|
@ -0,0 +1,416 @@
|
|||
\C{stdmac} \i{Standard Macros}
|
||||
|
||||
NASM defines a set of standard macros, which are already defined when
|
||||
it starts to process any source file. If you really need a program to
|
||||
be assembled with no pre-defined macros, you can use the \i\c{%clear}
|
||||
directive to empty the preprocessor of everything but context-local
|
||||
preprocessor variables and single-line macros, see \k{clear}.
|
||||
|
||||
Most \i{user-level directives} (see \k{directive}) are implemented as
|
||||
macros which invoke primitive directives; these are described in
|
||||
\k{directive}. The rest of the standard macro set is described here.
|
||||
|
||||
For compatibility with NASM versions before NASM 2.15, most standard
|
||||
macros of the form \c{__?foo?__} have aliases of form \c{__foo__} (see
|
||||
\k{defalias}). These can be removed with the directive \c{%clear
|
||||
defalias}.
|
||||
|
||||
|
||||
\H{stdmacver} \i{NASM Version Macros}
|
||||
|
||||
The single-line macros \i\c{__?NASM_MAJOR?__}, \i\c{__?NASM_MINOR?__},
|
||||
\i\c{__?NASM_SUBMINOR?__} and \i\c{__?NASM_PATCHLEVEL?__} expand to the
|
||||
major, minor, subminor and patch level parts of the \i{version
|
||||
number of NASM} being used. So, under NASM 0.98.32p1 for
|
||||
example, \c{__?NASM_MAJOR?__} would be defined to be 0, \c{__?NASM_MINOR?__}
|
||||
would be defined as 98, \c{__?NASM_SUBMINOR?__} would be defined to 32,
|
||||
and \c{__?NASM_PATCHLEVEL?__} would be defined as 1.
|
||||
|
||||
Additionally, the macro \i\c{__?NASM_SNAPSHOT?__} is defined for
|
||||
automatically generated snapshot releases \e{only}.
|
||||
|
||||
|
||||
\S{stdmacverid} \i\c{__?NASM_VERSION_ID?__}: \i{NASM Version ID}
|
||||
|
||||
The single-line macro \c{__?NASM_VERSION_ID?__} expands to a dword integer
|
||||
representing the full version number of the version of nasm being used.
|
||||
The value is the equivalent to \c{__?NASM_MAJOR?__}, \c{__?NASM_MINOR?__},
|
||||
\c{__?NASM_SUBMINOR?__} and \c{__?NASM_PATCHLEVEL?__} concatenated to
|
||||
produce a single doubleword. Hence, for 0.98.32p1, the returned number
|
||||
would be equivalent to:
|
||||
|
||||
\c dd 0x00622001
|
||||
|
||||
or
|
||||
|
||||
\c db 1,32,98,0
|
||||
|
||||
Note that the above lines are generate exactly the same code, the second
|
||||
line is used just to give an indication of the order that the separate
|
||||
values will be present in memory.
|
||||
|
||||
|
||||
\S{stdmacverstr} \i\c{__?NASM_VER?__}: \i{NASM Version String}
|
||||
|
||||
The single-line macro \c{__?NASM_VER?__} expands to a string which defines
|
||||
the version number of nasm being used. So, under NASM 0.98.32 for example,
|
||||
|
||||
\c db __?NASM_VER?__
|
||||
|
||||
would expand to
|
||||
|
||||
\c db "0.98.32"
|
||||
|
||||
|
||||
\H{fileline} \i\c{__?FILE?__} and \i\c{__?LINE?__}: File Name and Line Number
|
||||
|
||||
Like the C preprocessor, NASM allows the user to find out the file
|
||||
name and line number containing the current instruction. The macro
|
||||
\c{__?FILE?__} expands to a string constant giving the name of the
|
||||
current input file (which may change through the course of assembly
|
||||
if \c{%include} directives are used), and \c{__?LINE?__} expands to a
|
||||
numeric constant giving the current line number in the input file.
|
||||
|
||||
These macros could be used, for example, to communicate debugging
|
||||
information to a macro, since invoking \c{__?LINE?__} inside a macro
|
||||
definition (either single-line or multi-line) will return the line
|
||||
number of the macro \e{call}, rather than \e{definition}. So to
|
||||
determine where in a piece of code a crash is occurring, for
|
||||
example, one could write a routine \c{stillhere}, which is passed a
|
||||
line number in \c{EAX} and outputs something like \c{line 155: still
|
||||
here}. You could then write a macro:
|
||||
|
||||
\c %macro notdeadyet 0
|
||||
\c
|
||||
\c push eax
|
||||
\c mov eax,__?LINE?__
|
||||
\c call stillhere
|
||||
\c pop eax
|
||||
\c
|
||||
\c %endmacro
|
||||
|
||||
and then pepper your code with calls to \c{notdeadyet} until you
|
||||
find the crash point.
|
||||
|
||||
|
||||
\H{bitsm} \i\c{__?BITS?__}: Current Code Generation Mode
|
||||
|
||||
The \c{__?BITS?__} standard macro is updated every time that the BITS mode is
|
||||
set using the \c{BITS XX} or \c{[BITS XX]} directive, where XX is a valid mode
|
||||
number of 16, 32 or 64. \c{__?BITS?__} receives the specified mode number and
|
||||
makes it globally available. This can be very useful for those who utilize
|
||||
mode-dependent macros.
|
||||
|
||||
\H{ofmtm} \i\c{__?OUTPUT_FORMAT?__}: Current Output Format
|
||||
|
||||
The \c{__?OUTPUT_FORMAT?__} standard macro holds the current output
|
||||
format name, as given by the \c{-f} option or NASM's default. Type
|
||||
\c{nasm -h} for a list.
|
||||
|
||||
\c %ifidn __?OUTPUT_FORMAT?__, win32
|
||||
\c %define NEWLINE 13, 10
|
||||
\c %elifidn __?OUTPUT_FORMAT?__, elf32
|
||||
\c %define NEWLINE 10
|
||||
\c %endif
|
||||
|
||||
\H{dfmtm} \i\c{__?DEBUG_FORMAT?__}: Current Debug Format
|
||||
|
||||
If debugging information generation is enabled, The
|
||||
\c{__?DEBUG_FORMAT?__} standard macro holds the current debug format
|
||||
name as specified by the \c{-F} or \c{-g} option or the output format
|
||||
default. Type \c{nasm -f} \e{output} \c{y} for a list.
|
||||
|
||||
\c{__?DEBUG_FORMAT?__} is not defined if debugging is not enabled, or if
|
||||
the debug format specified is \c{null}.
|
||||
|
||||
\H{datetime} Assembly Date and Time Macros
|
||||
|
||||
NASM provides a variety of macros that represent the timestamp of the
|
||||
assembly session.
|
||||
|
||||
\b The \i\c{__?DATE?__} and \i\c{__?TIME?__} macros give the assembly date and
|
||||
time as strings, in ISO 8601 format (\c{"YYYY-MM-DD"} and \c{"HH:MM:SS"},
|
||||
respectively.)
|
||||
|
||||
\b The \i\c{__?DATE_NUM?__} and \i\c{__?TIME_NUM?__} macros give the assembly
|
||||
date and time in numeric form; in the format \c{YYYYMMDD} and
|
||||
\c{HHMMSS} respectively.
|
||||
|
||||
\b The \i\c{__?UTC_DATE?__} and \i\c{__?UTC_TIME?__} macros give the assembly
|
||||
date and time in universal time (UTC) as strings, in ISO 8601 format
|
||||
(\c{"YYYY-MM-DD"} and \c{"HH:MM:SS"}, respectively.) If the host
|
||||
platform doesn't provide UTC time, these macros are undefined.
|
||||
|
||||
\b The \i\c{__?UTC_DATE_NUM?__} and \i\c{__?UTC_TIME_NUM?__} macros give the
|
||||
assembly date and time universal time (UTC) in numeric form; in the
|
||||
format \c{YYYYMMDD} and \c{HHMMSS} respectively. If the
|
||||
host platform doesn't provide UTC time, these macros are
|
||||
undefined.
|
||||
|
||||
\b The \c{__?POSIX_TIME?__} macro is defined as a number containing the
|
||||
number of seconds since the POSIX epoch, 1 January 1970 00:00:00 UTC;
|
||||
excluding any leap seconds. This is computed using UTC time if
|
||||
available on the host platform, otherwise it is computed using the
|
||||
local time as if it was UTC.
|
||||
|
||||
All instances of time and date macros in the same assembly session
|
||||
produce consistent output. For example, in an assembly session
|
||||
started at 42 seconds after midnight on January 1, 2010 in Moscow
|
||||
(timezone UTC+3) these macros would have the following values,
|
||||
assuming, of course, a properly configured environment with a correct
|
||||
clock:
|
||||
|
||||
\c __?DATE?__ "2010-01-01"
|
||||
\c __?TIME?__ "00:00:42"
|
||||
\c __?DATE_NUM?__ 20100101
|
||||
\c __?TIME_NUM?__ 000042
|
||||
\c __?UTC_DATE?__ "2009-12-31"
|
||||
\c __?UTC_TIME?__ "21:00:42"
|
||||
\c __?UTC_DATE_NUM?__ 20091231
|
||||
\c __?UTC_TIME_NUM?__ 210042
|
||||
\c __?POSIX_TIME?__ 1262293242
|
||||
|
||||
|
||||
\H{use_def} \I\c{__?USE_*?__}\c{__?USE_}\e{package}\c{?__}: Package
|
||||
Include Test
|
||||
|
||||
When a standard macro package (see \k{macropkg}) is included with the
|
||||
\c{%use} directive (see \k{use}), a single-line macro of the form
|
||||
\c{__?USE_}\e{package}\c{?__} is automatically defined. This allows
|
||||
testing if a particular package is invoked or not.
|
||||
|
||||
For example, if the \c{altreg} package is included (see
|
||||
\k{pkg_altreg}), then the macro \c{__?USE_ALTREG?__} is defined.
|
||||
|
||||
|
||||
\H{pass_macro} \i\c{__?PASS?__}: Assembly Pass
|
||||
|
||||
The macro \c{__?PASS?__} is defined to be \c{1} on preparatory passes,
|
||||
and \c{2} on the final pass. In preprocess-only mode, it is set to
|
||||
\c{3}, and when running only to generate dependencies (due to the
|
||||
\c{-M} or \c{-MG} option, see \k{opt-M}) it is set to \c{0}.
|
||||
|
||||
\e{Avoid using this macro if at all possible. It is tremendously easy
|
||||
to generate very strange errors by misusing it, and the semantics may
|
||||
change in future versions of NASM.}
|
||||
|
||||
|
||||
\H{strucs} \i{Structure Data Types}
|
||||
|
||||
\S{struc} \i\c{STRUC} and \i\c{ENDSTRUC}: \i{Declaring Structure} Data Types
|
||||
|
||||
The core of NASM contains no intrinsic means of defining data
|
||||
structures; instead, the preprocessor is sufficiently powerful that
|
||||
data structures can be implemented as a set of macros. The macros
|
||||
\c{STRUC} and \c{ENDSTRUC} are used to define a structure data type.
|
||||
|
||||
\c{STRUC} takes one or two parameters. The first parameter is the name
|
||||
of the data type. The second, optional parameter is the base offset of
|
||||
the structure. The name of the data type is defined as a symbol with
|
||||
the value of the base offset, and the name of the data type with the
|
||||
suffix \c{_size} appended to it is defined as an \c{EQU} giving the
|
||||
size of the structure. Once \c{STRUC} has been issued, you are
|
||||
defining the structure, and should define fields using the \c{RESB}
|
||||
family of pseudo-instructions, and then invoke \c{ENDSTRUC} to finish
|
||||
the definition.
|
||||
|
||||
For example, to define a structure called \c{mytype} containing a
|
||||
longword, a word, a byte and a string of bytes, you might code
|
||||
|
||||
\c struc mytype
|
||||
\c
|
||||
\c mt_long: resd 1
|
||||
\c mt_word: resw 1
|
||||
\c mt_byte: resb 1
|
||||
\c mt_str: resb 32
|
||||
\c
|
||||
\c endstruc
|
||||
|
||||
The above code defines six symbols: \c{mt_long} as 0 (the offset
|
||||
from the beginning of a \c{mytype} structure to the longword field),
|
||||
\c{mt_word} as 4, \c{mt_byte} as 6, \c{mt_str} as 7, \c{mytype_size}
|
||||
as 39, and \c{mytype} itself as zero.
|
||||
|
||||
The reason why the structure type name is defined at zero by default
|
||||
is a side effect of allowing structures to work with the local label
|
||||
mechanism: if your structure members tend to have the same names in
|
||||
more than one structure, you can define the above structure like this:
|
||||
|
||||
\c struc mytype
|
||||
\c
|
||||
\c .long: resd 1
|
||||
\c .word: resw 1
|
||||
\c .byte: resb 1
|
||||
\c .str: resb 32
|
||||
\c
|
||||
\c endstruc
|
||||
|
||||
This defines the offsets to the structure fields as \c{mytype.long},
|
||||
\c{mytype.word}, \c{mytype.byte} and \c{mytype.str}.
|
||||
|
||||
NASM, since it has no \e{intrinsic} structure support, does not
|
||||
support any form of period notation to refer to the elements of a
|
||||
structure once you have one (except the above local-label notation),
|
||||
so code such as \c{mov ax,[mystruc.mt_word]} is not valid.
|
||||
\c{mt_word} is a constant just like any other constant, so the
|
||||
correct syntax is \c{mov ax,[mystruc+mt_word]} or \c{mov
|
||||
ax,[mystruc+mytype.word]}.
|
||||
|
||||
Sometimes you only have the address of the structure displaced by an
|
||||
offset. For example, consider this standard stack frame setup:
|
||||
|
||||
\c push ebp
|
||||
\c mov ebp, esp
|
||||
\c sub esp, 40
|
||||
|
||||
In this case, you could access an element by subtracting the offset:
|
||||
|
||||
\c mov [ebp - 40 + mytype.word], ax
|
||||
|
||||
However, if you do not want to repeat this offset, you can use -40 as
|
||||
a base offset:
|
||||
|
||||
\c struc mytype, -40
|
||||
|
||||
And access an element this way:
|
||||
|
||||
\c mov [ebp + mytype.word], ax
|
||||
|
||||
|
||||
\S{istruc} \i\c{ISTRUC}, \i\c{AT} and \i\c{IEND}: Declaring
|
||||
\i{Instances of Structures}
|
||||
|
||||
Having defined a structure type, the next thing you typically want
|
||||
to do is to declare instances of that structure in your data
|
||||
segment. NASM provides an easy way to do this in the \c{ISTRUC}
|
||||
mechanism. To declare a structure of type \c{mytype} in a program,
|
||||
you code something like this:
|
||||
|
||||
\c mystruc:
|
||||
\c istruc mytype
|
||||
\c
|
||||
\c at mt_long, dd 123456
|
||||
\c at mt_word, dw 1024
|
||||
\c at mt_byte, db 'x'
|
||||
\c at mt_str, db 'hello, world', 13, 10, 0
|
||||
\c
|
||||
\c iend
|
||||
|
||||
The function of the \c{AT} macro is to make use of the \c{TIMES}
|
||||
prefix to advance the assembly position to the correct point for the
|
||||
specified structure field, and then to declare the specified data.
|
||||
Therefore the structure fields must be declared in the same order as
|
||||
they were specified in the structure definition.
|
||||
|
||||
If the data to go in a structure field requires more than one source
|
||||
line to specify, the remaining source lines can easily come after
|
||||
the \c{AT} line. For example:
|
||||
|
||||
\c at mt_str, db 123,134,145,156,167,178,189
|
||||
\c db 190,100,0
|
||||
|
||||
Depending on personal taste, you can also omit the code part of the
|
||||
\c{AT} line completely, and start the structure field on the next
|
||||
line:
|
||||
|
||||
\c at mt_str
|
||||
\c db 'hello, world'
|
||||
\c db 13,10,0
|
||||
|
||||
\H{alignment} \i{Alignment} Control
|
||||
|
||||
\S{align} \i\c{ALIGN} and \i\c{ALIGNB}: Code and Data Alignment
|
||||
|
||||
The \c{ALIGN} and \c{ALIGNB} macros provides a convenient way to
|
||||
align code or data on a word, longword, paragraph or other boundary.
|
||||
(Some assemblers call this directive \i\c{EVEN}.) The syntax of the
|
||||
\c{ALIGN} and \c{ALIGNB} macros is
|
||||
|
||||
\c align 4 ; align on 4-byte boundary
|
||||
\c align 16 ; align on 16-byte boundary
|
||||
\c align 8,db 0 ; pad with 0s rather than NOPs
|
||||
\c align 4,resb 1 ; align to 4 in the BSS
|
||||
\c alignb 4 ; equivalent to previous line
|
||||
|
||||
Both macros require their first argument to be a power of two; they
|
||||
both compute the number of additional bytes required to bring the
|
||||
length of the current section up to a multiple of that power of two,
|
||||
and then apply the \c{TIMES} prefix to their second argument to
|
||||
perform the alignment.
|
||||
|
||||
If the second argument is not specified, the default for \c{ALIGN}
|
||||
is \c{NOP}, and the default for \c{ALIGNB} is \c{RESB 1}. So if the
|
||||
second argument is specified, the two macros are equivalent.
|
||||
Normally, you can just use \c{ALIGN} in code and data sections and
|
||||
\c{ALIGNB} in BSS sections, and never need the second argument
|
||||
except for special purposes.
|
||||
|
||||
\c{ALIGN} and \c{ALIGNB}, being simple macros, perform no error
|
||||
checking: they cannot warn you if their first argument fails to be a
|
||||
power of two, or if their second argument generates more than one
|
||||
byte of code. In each of these cases they will silently do the wrong
|
||||
thing.
|
||||
|
||||
\c{ALIGNB} (or \c{ALIGN} with a second argument of \c{RESB 1}) can
|
||||
be used within structure definitions:
|
||||
|
||||
\c struc mytype2
|
||||
\c
|
||||
\c mt_byte:
|
||||
\c resb 1
|
||||
\c alignb 2
|
||||
\c mt_word:
|
||||
\c resw 1
|
||||
\c alignb 4
|
||||
\c mt_long:
|
||||
\c resd 1
|
||||
\c mt_str:
|
||||
\c resb 32
|
||||
\c
|
||||
\c endstruc
|
||||
|
||||
This will ensure that the structure members are sensibly aligned
|
||||
relative to the base of the structure.
|
||||
|
||||
A final caveat: \c{ALIGN} and \c{ALIGNB} work relative to the
|
||||
beginning of the \e{section}, not the beginning of the address space
|
||||
in the final executable. Aligning to a 16-byte boundary when the
|
||||
section you're in is only guaranteed to be aligned to a 4-byte
|
||||
boundary, for example, is a waste of effort. Again, NASM does not
|
||||
check that the section's alignment characteristics are sensible for
|
||||
the use of \c{ALIGN} or \c{ALIGNB}.
|
||||
|
||||
Both \c{ALIGN} and \c{ALIGNB} do call \c{SECTALIGN} macro implicitly.
|
||||
See \k{sectalign} for details.
|
||||
|
||||
See also the \c{smartalign} standard macro package, \k{pkg_smartalign}.
|
||||
|
||||
|
||||
\S{sectalign} \i\c{SECTALIGN}: Section Alignment
|
||||
|
||||
The \c{SECTALIGN} macros provides a way to modify alignment attribute
|
||||
of output file section. Unlike the \c{align=} attribute (which is allowed
|
||||
at section definition only) the \c{SECTALIGN} macro may be used at any time.
|
||||
|
||||
For example the directive
|
||||
|
||||
\c SECTALIGN 16
|
||||
|
||||
sets the section alignment requirements to 16 bytes. Once increased it can
|
||||
not be decreased, the magnitude may grow only.
|
||||
|
||||
Note that \c{ALIGN} (see \k{align}) calls the \c{SECTALIGN} macro implicitly
|
||||
so the active section alignment requirements may be updated. This is by default
|
||||
behaviour, if for some reason you want the \c{ALIGN} do not call \c{SECTALIGN}
|
||||
at all use the directive
|
||||
|
||||
\c SECTALIGN OFF
|
||||
|
||||
It is still possible to turn in on again by
|
||||
|
||||
\c SECTALIGN ON
|
||||
|
||||
Note that \c{SECTALIGN <ON|OFF>} affects only the \c{ALIGN}/\c{ALIGNB} directives,
|
||||
not an explicit \c{SECTALIGN} directive.
|
||||
|
||||
|
107
doc/trouble.src
Normal file
107
doc/trouble.src
Normal file
|
@ -0,0 +1,107 @@
|
|||
\C{trouble} Troubleshooting
|
||||
|
||||
This chapter describes some of the common problems that users have
|
||||
been known to encounter with NASM, and answers them. If you think you
|
||||
have found a bug in NASM, please see \k{bugs}.
|
||||
|
||||
|
||||
\H{problems} Common Problems
|
||||
|
||||
\S{inefficient} NASM Generates \i{Inefficient Code}
|
||||
|
||||
We sometimes get `bug' reports about NASM generating inefficient, or
|
||||
even `wrong', code on instructions such as \c{ADD ESP,8}. This is a
|
||||
deliberate design feature, connected to predictability of output:
|
||||
NASM, on seeing \c{ADD ESP,8}, will generate the form of the
|
||||
instruction which leaves room for a 32-bit offset. You need to code
|
||||
\I\c{BYTE}\c{ADD ESP,BYTE 8} if you want the space-efficient form of
|
||||
the instruction. This isn't a bug, it's user error: if you prefer to
|
||||
have NASM produce the more efficient code automatically enable
|
||||
optimization with the \c{-O} option (see \k{opt-O}).
|
||||
|
||||
|
||||
\S{jmprange} My Jumps are Out of Range\I{out of range, jumps}
|
||||
|
||||
Similarly, people complain that when they issue \i{conditional
|
||||
jumps} (which are \c{SHORT} by default) that try to jump too far,
|
||||
NASM reports `short jump out of range' instead of making the jumps
|
||||
longer.
|
||||
|
||||
This, again, is partly a predictability issue, but in fact has a
|
||||
more practical reason as well. NASM has no means of being told what
|
||||
type of processor the code it is generating will be run on; so it
|
||||
cannot decide for itself that it should generate \i\c{Jcc NEAR} type
|
||||
instructions, because it doesn't know that it's working for a 386 or
|
||||
above. Alternatively, it could replace the out-of-range short
|
||||
\c{JNE} instruction with a very short \c{JE} instruction that jumps
|
||||
over a \c{JMP NEAR}; this is a sensible solution for processors
|
||||
below a 386, but hardly efficient on processors which have good
|
||||
branch prediction \e{and} could have used \c{JNE NEAR} instead. So,
|
||||
once again, it's up to the user, not the assembler, to decide what
|
||||
instructions should be generated. See \k{opt-O}.
|
||||
|
||||
|
||||
\S{proborg} \i\c{ORG} Doesn't Work
|
||||
|
||||
People writing \i{boot sector} programs in the \c{bin} format often
|
||||
complain that \c{ORG} doesn't work the way they'd like: in order to
|
||||
place the \c{0xAA55} signature word at the end of a 512-byte boot
|
||||
sector, people who are used to MASM tend to code
|
||||
|
||||
\c ORG 0
|
||||
\c
|
||||
\c ; some boot sector code
|
||||
\c
|
||||
\c ORG 510
|
||||
\c DW 0xAA55
|
||||
|
||||
This is not the intended use of the \c{ORG} directive in NASM, and
|
||||
will not work. The correct way to solve this problem in NASM is to
|
||||
use the \i\c{TIMES} directive, like this:
|
||||
|
||||
\c ORG 0
|
||||
\c
|
||||
\c ; some boot sector code
|
||||
\c
|
||||
\c TIMES 510-($-$$) DB 0
|
||||
\c DW 0xAA55
|
||||
|
||||
The \c{TIMES} directive will insert exactly enough zero bytes into
|
||||
the output to move the assembly point up to 510. This method also
|
||||
has the advantage that if you accidentally fill your boot sector too
|
||||
full, NASM will catch the problem at assembly time and report it, so
|
||||
you won't end up with a boot sector that you have to disassemble to
|
||||
find out what's wrong with it.
|
||||
|
||||
|
||||
\S{probtimes} \i\c{TIMES} Doesn't Work
|
||||
|
||||
The other common problem with the above code is people who write the
|
||||
\c{TIMES} line as
|
||||
|
||||
\c TIMES 510-$ DB 0
|
||||
|
||||
by reasoning that \c{$} should be a pure number, just like 510, so
|
||||
the difference between them is also a pure number and can happily be
|
||||
fed to \c{TIMES}.
|
||||
|
||||
NASM is a \e{modular} assembler: the various component parts are
|
||||
designed to be easily separable for re-use, so they don't exchange
|
||||
information unnecessarily. In consequence, the \c{bin} output
|
||||
format, even though it has been told by the \c{ORG} directive that
|
||||
the \c{.text} section should start at 0, does not pass that
|
||||
information back to the expression evaluator. So from the
|
||||
evaluator's point of view, \c{$} isn't a pure number: it's an offset
|
||||
from a section base. Therefore the difference between \c{$} and 510
|
||||
is also not a pure number, but involves a section base. Values
|
||||
involving section bases cannot be passed as arguments to \c{TIMES}.
|
||||
|
||||
The solution, as in the previous section, is to code the \c{TIMES}
|
||||
line in the form
|
||||
|
||||
\c TIMES 510-($-$$) DB 0
|
||||
|
||||
in which \c{$} and \c{$$} are offsets from the same section base,
|
||||
and so their difference is a pure number. This will solve the
|
||||
problem and generate sensible code.
|
||||
|
8
doc/warn.src
Normal file
8
doc/warn.src
Normal file
|
@ -0,0 +1,8 @@
|
|||
\A{warnings} \I{warning class}\I{warning classes, list}\i{List of Warning Classes}
|
||||
|
||||
These are the warning classes currently defined by NASM for the
|
||||
purpose of enabling, disabling and promoting to error. See \k{opt-w}
|
||||
and \k{asmdir-warning}.
|
||||
|
||||
\& warnings.src
|
||||
|
Loading…
Reference in a new issue