fasm/FASM.DOC
Tomasz Grysztar df8d463dd8 release 1.03
2000-07-19 12:00:00 +00:00

384 lines
13 KiB
Text

ÜÜÜ
Ûßßß ßÛ
ÛÛ
ÛÛ
Ü ÛÛÜÜ ÜßßßÛÜ ÜßßßßÜÞßÜÞßßÜßÛÝ
ÛÛ ÛÝ ÞÛ ß ÞÛ Û Ý
ÛÛ ÜßßßßßÛÛ ßßßÛÜÜ ÞÛ Û Ý
ÛÛ Û ÛÛ Ü ÞÛ ÞÛ Û Ý
ßßßßßß ßßßßß ßß ßßßßßß ß ß ß
flat assembler version 1.03
Copyright (c) 1999-2000, Tomasz Grysztar. All rights reserved.
Table of Contents
1 Introduction
1.1 What is fasm?
1.2 Hardware requirements
1.3 Software and OS requirements
1.4 Output formats
1.5 Output file ordering
2 Using flat assembler
2.1 Assembler syntax
2.1.1 Instruction syntax
2.1.1.1 Data access
2.1.1.2 Jumps and calls
2.1.1.3 Labels and constants
2.1.1.4 Addresses
2.1.1.5 Special cases
2.1.2 Number syntax
2.1.3 Logical expressions syntax
2.1.4 Defining constants
2.1.5 Defining data
2.2 Directives
2.2.1 Preprocessor directives
2.2.2 Code settings
2.2.3 Other directives
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
1 Introduction
1.1 What is fasm?
The fasm assembler is a fast, efficient 80x86 assembler that runs
in 'flat real mode'. So, it must be run on at least an 80386 PC, but
it can certainly assemble programs for any 80x86 PC. Unlike many other
80x86 assemblers, fasm only requires the source code to include the
information it really needs. See the 'asm' files in the 'examples'
subdirectory to see how simple it can be! The files in the 'source' and
'examples' subdirectories are good references for more complex examples.
1.2 Hardware requirements
Aside from the above-mentioned need for at least an 80386 CPU, the
hardware needs are small; at least one megabyte of extended memory is
reccommended for best performance.
1.3 Software and OS requirements
Other than an OS compatible with MSDOS 2.0+, fasm needs no other
software. Note that fasm will not run if the CPU is in protected or
V86 modes, since flat real mode cannot be entered in that case.
1.4 Output formats
There are two possible output formats; by default, the output of
fasm is a non-relocatable binary image such as a 'com' or 'sys' program.
Use of the directive 'format MZ' produces a relocatable and possibly
multi-segment 'exe' program. No extra 'linking' step is needed!
1.5 Output file ordering
All output code is in the order in which it was entered into the
source file. So, program code or at least an instruction such as 'jmp
start' must be at the beginning of the source code unless the program
is in multi-segment MZ format. In that case, see the 'entry' directive
(below).
2 Using flat assembler
2.1 Assembler syntax
2.1.1 Instruction syntax
2.1.1.1 Data access
Moving data to or from a register involves two simple rules;
'mov eax,myvar' will place the offset (address) of 'myvar' in the eax
register, while 'mov eax,[myvar]' will place the 32-bit value of the
variable 'myvar' in eax. Note that fasm will exit with an error if 'myvar'
has not been defined as a 32-bit value. When 'myvar' has not been defined
as 32-bit value, but you need to assemble instruction 'mov eax,[myvar]',
use size override: 'mov eax,dword [myvar]', or (short form):
'mov eax,d[myvar]'. This is dangerous if 'myvar' has been defined as an
8-bit or a 16-bit variable; eax will contain whatever is in the four bytes
beginning at the address of 'myvar'!
2.1.1.2 Jumps and calls
Unconditional:
jmp alpha ; simple jump
jmp near byte beta ; short jump
jmp near dword beta ; force dword size
jmp 10h:50h ; far jump
jmp 10h:dword 50000h ; 32-bit far jump
call far pword [1000h] ; 32-bit far call
call far dword [delta] ; 16-bit far call
call near dword [delta] ; 32-bit near call
Conditional:
je alpha ; will be optimized
jge byte alpha ; force byte (error if out of range)
jb dword alpha ; force dword (no optimization)
2.1.1.3 Labels and constants
Examples of defining labels:
alpha: ; simple label
label beta ; as above
label gamma byte ; low byte of delta dword
delta dd 0 ; data label
epsilon = alpha + 1 ; constant definition
Local labels:
sigma:
.alpha: ; local label (1)
jmp .alpha ; jump to (1)
omega:
.alpha: ; local label (2)
jmp .alpha ; jump to (2)
jmp sigma.alpha ; jump to (1)
2.1.1.4 Addresses
The fasm is able to do some simple arithmetics on registers, so forms
like '[ebx*5]' are allowed (it will be assembled as '[ebx+ebx*4]').
Defining size of address value is possible; '[word 4]' and '[dword 4]'
will generate different output code: [0000] and [00000000], '[word bx]'
will be [bx+0000], '[byte bx]' will be [bx+00], '[dword ebx+1]' will
be [ebx+00000001], etc.
2.1.1.5 Special cases
'xlat' instruction accepts no arguments, or one argument:
'[bx]'/'byte [bx]' to create 16-bit version, or '[ebx]'/'byte [ebx]'
to create 32-bit version of opcode; in the similar way advanced settings
of string instructions can be done, like 'movs byte [es:edi],[fs:esi]',
to adjust address registers size and segment override ('movs' needs two
arguments). 'xlatb', 'movsb', etc. accept no arguments.
2.1.2 Number syntax
Decimal numbers: 15, 15d
Binary: 1011b
Hexadecimal: ABh, 0xAB (case sensitive)
Special: $ - current address value, % - current repeat number (see 2.2.3)
Operators: +,-,*,/,mod,not,and,or,xor,shl,shr
2.1.3 Logical expressions syntax
See 'macros' examples in Section 2.2.1 for usage examples.
The logical operators are: ~ (not), | (or), & (and). Logical values
can be defined using comparing operators: = (equal), < (less), > (greater),
<= (less or equal), >= (greater or equal) for numbers and 'equ' for all
other symbols. Word 'equ' is also used to define symbolic constants.
When you want to use 'true' and 'false' values in logical expressions,
define them using 'equ': 'true equ 0=0', 'false equ ~true'.
2.1.4 Defining constants
As opposed to 'equ', '=' works with values only, and they are
calculated at define time; for example 'xyz = $' defines xyz symbol
as an address of point where it was defined, 'xyz equ $' will just
define equivalent to '$', which will be always address of point
where it's used.
2.1.5 Defining data
Data can be defined in two ways; if the data is to be initialised
to a specific value, the forms are:
gdtr db 16,0,0,0,0,0,0 ; sequence of bytes
attrib db 0x1E ; single byte (hexadecimal)
command: times 127 db 0 ; byte string
str001 db 'test.bin',0 ; character string
argv: times 10 dd 0 ; ten 32-bit double words
picture file 'star.gif' ; whole file contents
Other forms available are:
dw ; 16-bit word
dp ; 48-bit pointer
dq ; 64-bit quad word
If it is only desired to reserve space for data, the forms are:
_proname rd 1 ; reserve one dword
_inch rb 1 ; reserve one byte
newstack rd 255 ; reserve 255 dwords
Other forms available are:
rw ; 16-bit word
rp ; 48-bit pointer
rq ; 64-bit quad word
Note that if the pre-defined 'times' macro is to be used to define
multiple data items, any label used must end with a colon. The other way is
to use 'label' directive before data definition, for example:
label argv dword
times 10 dd 0
There's no struc directive in fasm, but when you really need, in most
cases you can do the same thing easily using macros:
macro pixel name,x,y,color
{
name:
.x dw x
.y dw y
.color db color
}
virtual at 0
pixel pixel,?,?,?
end virtual
; so we have pixel.x, pixel.y and pixel.color offsets defined
pixel mypix,10,10,4
; and now also mypix.x, mypix.y, mypix.color variables
To handle cases, when one or more of macro params are empty (for
example just: 'pixel mypix'), you can write something like '.x dw x+0',
or use 'if <x> equ <>'.
2.2 Directives
2.2.1 Preprocessor directives
include - includes source file in source code before assembly
macro - defines macroinstructions, arguments are macro name and names
of macro arguments separated with commas, then '{' (start of macro)
character, macro instructions, and '}' (end of macro) character.
Here's an example of macroinstruction for data alignment:
macro align value { rb (value-1) - ($ + value-1) mod value }
Macroinstructions may have empty arguments; to check if argument
is empty use something like 'if <argument> equ <>'.
If a macro is defined that uses an instruction with the same name
inside the macro definition, the previous meaning of this name is
used; useful redefinition of macros can be done in that way, for
example:
macro mov arg1,arg2
{
if (arg1 equ ds | arg1 equ es) & (arg2 equ ds | arg2 equ es)
push arg2
pop arg1
else
mov arg1,arg2 ; here original mov instruction will be used
end if
}
macro mov arg1,arg2,arg3
{
if <arg3> equ <>
mov arg1,arg2 ; here previous macro will be used
else
mov arg1,arg2
mov arg2,arg3
end if
}
mov ax,bx ; just 'mov ax,bx'
mov ds,es ; 'push es' and 'pop ds'
mov es,ds,dx ; 'push ds', 'pop es' and 'mov ds,dx'
But note that using these macros in big programs will dramatically
slow down assembly (up to 4 times!) and increase memory requirements.
local - used inside macro definitions, defines local symbols, which
will have unique names in every macro call; arguments are local
symbol names, separated with commas.
purge - argument is one or more macro names, separated with commas; this
directive will remove last definition of specified macro; for example
when you've redefined some macro, you can get previous definition
back using purge (it's different than TASM in this respect; there
purge eliminates all macros of that name). If the macro has not been
defined, you won't get any error (exactly like in TASM).
When you need do totally undefine some non-preprocessor symbol
(defined with equ, or labels), use this clever macro:
macro undefine symbol
{
local undefined
symbol equ undefined
}
For example after 'undefine add', you can't use 'add' instruction,
but definition and usage of 'add' label is possible. Also, if you
use '_add equ add', and then 'undefine add', you can define 'add'
label and have access to 'add' instruction using '_add' symbol.
equ - defines symbolic constant.
2.2.2 Code settings
use16 - set code type to 16-bit (this is default code setting).
use32 - set code type to 32-bit.
org - argument must be an address value; set from what address this
code will start in memory.
format - set output file format, can be set binary or MZ; binary
is the default format, MZ is an EXE file format.
label - define label, needed argument is a name of label, optional
arguments are size of label and 'at <address>' phrase.
segment - define segment at current position (only in MZ format),
code will be aligned to paragraph. In segment definition, after
segment name, 'use16' or 'use32' is allowed.
entry - define program entry point (only in MZ format), argument must
be a segment:offset address (like in far jump).
stack - define program stack size (only in MZ format), when no stack
is defined, default size of 2000h bytes is used. Or, the stack
location can be defined in segment:offset form.
heap - define 'heap' size in paragraphs (only in MZ format) - argument
is a 16-bit value, defining maximum size of additional heap in
paragraphs (note that this is heap in addition to stack and undefined
data; use 'heap 0' to always allocate only memory program really
needs); default value of 'heap' is FFFFh.
2.2.3 Other directives
times - repeat instruction n times; arguments are number of repeats and
instruction to repeat (optionally character ':' can be used to
separate number and instructions), also % value (current repeat
number) can be used in instruction, so 'times 5 db %' will create
01,02,03,04,05 bytes; recurrency is also allowed, so
'times 3 times % db %' will create 01,01,02,01,02,03 bytes.
repeat - larger version of times directive, repeat has one argument -
number of repeats, instructions to repeat are expected in next
lines, ended with 'end repeat' directive.
virtual - creates virtual code or data at specified address; this data
won't be included in output file, but labels defined there can
be useful in other parts of program; argument to virtual is
'at <address>' phrase, virtual instructions are expected in
next lines, ended with 'end virtual' directive.
if - used to assemble some part of codes, when specified conditions are
met; argument is a logical expression, in next lines instructions to
assemble when this expression value is true, then 'end if' directive,
or 'else', or 'else if' and next logical expression.
end - used to end structures defined with some other directives,
correct forms are 'end repeat', 'end virtual' and 'end if'.
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Thanks to:
Ken Martwick - for help in writing documentation
Bartek Uliasz - for help at the beginning of fasm project
Bill Isherwood - for all useful suggestions