mirror of
https://github.com/tgrysztar/fasm
synced 2026-08-26 00:23:06 -04:00
release 1.40
This commit is contained in:
parent
6307fd8c56
commit
17dee461f0
16 changed files with 870 additions and 838 deletions
554
FASM.TXT
554
FASM.TXT
|
|
@ -1,554 +0,0 @@
|
|||
|
||||
ÜÜÜ
|
||||
Ûßßß ßÛ
|
||||
ÛÛ
|
||||
ÛÛ
|
||||
Ü ÛÛÜÜ ÜßßßÛÜ ÜßßßßÜÞßÜÞßßÜßÛÝ
|
||||
ÛÛ ÛÝ ÞÛ ß ÞÛ Û Ý
|
||||
ÛÛ ÜßßßßßÛÛ ßßßÛÜÜ ÞÛ Û Ý
|
||||
ÛÛ Û ÛÛ Ü ÞÛ ÞÛ Û Ý
|
||||
ßßßßßß ßßßßß ßß ßßßßßß ß ß ß
|
||||
|
||||
flat assembler version 1.39
|
||||
|
||||
Copyright (c) 1999-2002, 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
|
||||
1.6 Output code optimization
|
||||
|
||||
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.1.6 FPU and MMX instructions
|
||||
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 Label and constant definitions
|
||||
2.2.3 Code and format settings
|
||||
2.2.4 Other directives
|
||||
|
||||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
|
||||
1 Introduction
|
||||
|
||||
1.1 What is fasm?
|
||||
|
||||
The flat 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.
|
||||
You may notice that fasm is case sensitive for all symbols (even instructions
|
||||
and directives).
|
||||
|
||||
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. But
|
||||
it will still run under Win32, because version for that system is attached
|
||||
to fasm executable. There exists also version for Linux, distributed in
|
||||
a separate package.
|
||||
|
||||
1.4 Output formats
|
||||
|
||||
There are four 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! Use of
|
||||
the directive 'format PE' produces portable executable and use of the
|
||||
diretive 'format COFF' produces object file.
|
||||
|
||||
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 format other than binary. In that case, see the 'entry' directive
|
||||
(below).
|
||||
|
||||
1.6 Output code optimization
|
||||
|
||||
The flat assembler will do multiple (but fast) assembly passes to
|
||||
generate optimal output code. When size of jump or address in instruction
|
||||
is not specified, fasm will generate as small instruction code as possible.
|
||||
That's the only code optimization fasm will do.
|
||||
|
||||
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]'. 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'! Allowed size overrides
|
||||
are: byte (8-bit), word (16-bit), dword (32-bit), pword (48-bit),
|
||||
qword (64-bit), tword (80-bit), dqword (128-bit).
|
||||
You can also use 'ptr' operator instead of brackets to get the value of
|
||||
the variable, so 'mov byte ptr myvar,7' is the same as 'mov byte [myvar],7'.
|
||||
|
||||
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 pword 10h: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 = delta - 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: [0004] and [00000004], '[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 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.1.6 FPU and MMX instructions
|
||||
|
||||
Examples of FPU instructions:
|
||||
|
||||
fld tword [si] ; load fp
|
||||
fadd st0,st3 ; add fp
|
||||
fimul dword [ebx] ; multiply integer
|
||||
fstp qword [edx] ; store fp and pop stack
|
||||
|
||||
Examples of MMX instructions:
|
||||
|
||||
paddb mm0,mm1 ; packed add bytes
|
||||
pand mm7,qword [esi] ; logical and
|
||||
addps xmm0,xmm1 ; packed single fp add
|
||||
cmpeqps xmm7,dqword [esi] ; packed single fp compare
|
||||
shufps xmm4,xmm5,1 ; shuffle single fp
|
||||
|
||||
2.1.2 Number syntax
|
||||
|
||||
Decimal numbers: 15, 15d
|
||||
Binary: 1011b
|
||||
Hexadecimal: 0ABh, 0xAB
|
||||
Octal: 231o, 0231
|
||||
Floating point: 3.14, 1.0E3
|
||||
Special: $ - current address value, % - current repeat number (see 2.2.3)
|
||||
Operators: +,-,*,/,mod,not,and,or,xor,shl,shr
|
||||
Address conversion operator: RVA (only in PE format)
|
||||
Symbol concatenation operator: #
|
||||
|
||||
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), <> (not equal) for numbers;
|
||||
'eq' or 'in' for all other symbols.
|
||||
|
||||
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
|
||||
|
||||
When loading data with 'file' instruction, after file name can follow
|
||||
position in file preceded by colon, then comma and count of bytes to load.
|
||||
|
||||
Other forms available are:
|
||||
|
||||
dw ; 16-bit word
|
||||
dp ; 48-bit pointer
|
||||
dq ; 64-bit quad word
|
||||
dt ; 80-bit floating point
|
||||
du ; 16-bit word strings
|
||||
|
||||
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
|
||||
rt ; 80-bit floating point
|
||||
|
||||
Note that if the 'times' directive 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
|
||||
|
||||
To create union of some variables, you can use label directive with
|
||||
'at <address>' phrase, or virtual directive, for example:
|
||||
|
||||
GDT_limit dw 15
|
||||
GDT_address dd ?
|
||||
|
||||
; now define virtual variable for lgdt and sgdt instructions
|
||||
|
||||
label GDTR pword at GDT_limit
|
||||
|
||||
; and now the other method
|
||||
|
||||
LDTR dp ?
|
||||
|
||||
virtual at LDTR
|
||||
LDT_limit dw ?
|
||||
LDT_address dd ?
|
||||
end virtual
|
||||
|
||||
2.2 Directives
|
||||
|
||||
2.2.1 Preprocessor directives
|
||||
|
||||
The all preprocessor directives in the source code are processed before
|
||||
the main assembly process, and so they are not affected by the 'if' or
|
||||
'repeat' directives, which are processed at assembly time (see 2.2.4).
|
||||
|
||||
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 }
|
||||
|
||||
Note that in PE format you should replace '$' with 'RVA $' to allow
|
||||
this calculations.
|
||||
|
||||
Macroinstructions may have empty arguments; to check if argument
|
||||
is empty use something like 'if <argument> eq <>'.
|
||||
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 in <ds,es,fs,gs,ss> & arg2 in <cs,ds,es,fs,gs,ss>
|
||||
push arg2
|
||||
pop arg1
|
||||
else
|
||||
mov arg1,arg2 ; here original mov instruction will be used
|
||||
end if
|
||||
}
|
||||
macro mov arg1,arg2,arg3
|
||||
{
|
||||
if <arg3> eq <>
|
||||
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 3 times!) and increase memory requirements.
|
||||
|
||||
If you type arguments in brackets, macroinstruction will allow
|
||||
multiple groups of arguments, and will repeat all instructions for
|
||||
each arguments group separately. For example:
|
||||
|
||||
macro stoschar [char]
|
||||
{
|
||||
mov al,char
|
||||
stosb
|
||||
}
|
||||
|
||||
stoschar 1,2,3,4 ; store four bytes at es:di
|
||||
|
||||
There are some special directives available only inside macro
|
||||
definitions. The 'local' directive defines local symbols, which
|
||||
will have unique names in every macro call; arguments are local
|
||||
symbol names, separated with commas. The 'forward', 'reverse' and
|
||||
'common' directives divide macroinstruction into parts, each one
|
||||
processed after the previous one processing is finished. The part
|
||||
defined using 'forward' directive will be processed for each
|
||||
group of multiple arguments, from first to last; the same as
|
||||
default macroinstruction behaviour. Local symbol defined in one of
|
||||
the parts will be available in all next parts, when processing the
|
||||
same group of arguments.
|
||||
|
||||
For example, to create table of addresses to strings, and then
|
||||
strings data, use this macro:
|
||||
|
||||
macro strtbl [string]
|
||||
{ forward
|
||||
local label
|
||||
dd label
|
||||
forward
|
||||
label db string,0 }
|
||||
|
||||
The 'reverse' directive will cause groups of arguments to be
|
||||
processed from last to first; and the 'common' directive will define
|
||||
part, which will be processed only once.
|
||||
|
||||
Here's example how to define macro for calling procedures with
|
||||
arguments on stack in using the above directives:
|
||||
|
||||
macro stdcall proc,[arg]
|
||||
{ reverse push arg
|
||||
common call proc }
|
||||
|
||||
Note that instructions can follow the directive defining part of
|
||||
macroinstruction.
|
||||
|
||||
Also, in 'common' part name of the macro argument will be replaced
|
||||
with all the argument values, from first to last, separated with
|
||||
commas. So we can define next macro for indirectly invoking
|
||||
procedures this way:
|
||||
|
||||
macro invoke proc,[arg]
|
||||
{ common stdcall [proc],arg }
|
||||
|
||||
struc - this is the variant of macro directive used to create data
|
||||
structures. When struc macro is used in program, it must be preceded
|
||||
by a label. Preprocessor will insert this label at the beginning of
|
||||
every symbol starting with a single dot. For example:
|
||||
|
||||
struc pixel x,y,color
|
||||
{
|
||||
.x dw x
|
||||
.y dw y
|
||||
.color db color
|
||||
}
|
||||
|
||||
mypix pixel 10,10,4
|
||||
|
||||
; so we have defined mypix.x, mypix.y and mypix.color variables
|
||||
|
||||
virtual at 0
|
||||
pixel pixel ?,?,?
|
||||
end virtual
|
||||
|
||||
; and now also pixel.x, pixel.y, pixel.color offsets
|
||||
|
||||
To handle cases, when one or more of macro params are empty (for
|
||||
example just: 'mypix pixel'), you can write something like
|
||||
'.x dw x+0', or use 'if <x> eq <>'.
|
||||
|
||||
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. If the macro has not been defined, you won't get
|
||||
any error. When you need to 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. This directive should be preceded by the
|
||||
symbol name, and followed by the symbol value.
|
||||
|
||||
2.2.2 Label and constant definitions
|
||||
|
||||
label - define label, needed argument is a name of label, optional
|
||||
arguments are size of labeled data and 'at <address>' phrase.
|
||||
|
||||
load - define constant equal to binary value loaded from file; arguments are
|
||||
constant name, optionally constant size (when no size is specified,
|
||||
constant will be one byte), then 'from <file>' phrase, after file
|
||||
name position in file preceded by a colon can follow.
|
||||
|
||||
2.2.3 Code and format settings
|
||||
|
||||
use16 - set code type to 16-bit (this is default code setting).
|
||||
|
||||
use32 - set code type to 32-bit (this is default code setting for PE format).
|
||||
|
||||
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, MZ, PE, or COFF; binary
|
||||
is the default format, MZ is an EXE file format, PE is a portable
|
||||
executable file format and COFF is a common object file format.
|
||||
To make Microsoft COFF file, use 'format MS COFF' phrase.
|
||||
specified format is PE, more format settings can follow; use
|
||||
'console', 'GUI' or 'native' words to set target subsystem type
|
||||
(subsystem version can follow); 'i386', 'i486' or 'i586' to specify
|
||||
target machine type; 'DLL' to create dynamic link library. Use
|
||||
'on <file>' phrase to specify custom stub program.
|
||||
|
||||
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.
|
||||
|
||||
section - define section at current position (only in PE and COFF formats).
|
||||
If output format is PE, code will be aligned to page (4096 bytes).
|
||||
First argument is a string containing section name (maximum 8
|
||||
characters), optional next arguments are section type (code, data),
|
||||
and section attributes (readable, writeable, executable, shareable,
|
||||
discardable). With PE format you can also specify that section
|
||||
is one of predefined data types: export, import, resource, fixups.
|
||||
|
||||
public - declare the existing symbol as public (only in COFF format), needed
|
||||
argument is a name of symbol, optional argument is 'as <string>'
|
||||
(string should be quoted) to make this symbol visible outside
|
||||
with the different name.
|
||||
|
||||
extrn - define the external symbol (only in COFF format), needed argument is
|
||||
a name of symbol, optional argument is the size of data labeled by
|
||||
this symbol.
|
||||
|
||||
entry - define program entry point (only in MZ and PE formats). In MZ format
|
||||
argument must be a segment:offset address (like in far jump).
|
||||
|
||||
stack - define program stack size (only in MZ and PE formats), when no stack
|
||||
is defined, default size of 1000h bytes is used. In MZ format the
|
||||
stack location can be defined in segment:offset form. In PE format
|
||||
second argument is allowed to define stack commit (first argument
|
||||
defines stack reserve).
|
||||
|
||||
heap - define 'heap' size in paragraphs (only in MZ and PE formats). 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. In PE format
|
||||
argument is a 32-bit value, defining heap reserve; second argument is
|
||||
allowed to define heap commit.
|
||||
|
||||
data - begin PE format specific data definition. Argument is a number of PE
|
||||
data directory, or a predefined data type (export, import, resource,
|
||||
fixups). Data definition should be ended with 'end data' directive.
|
||||
|
||||
2.2.4 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 directive
|
||||
has no arguments, it uses the current address, the same as
|
||||
'virtual at $'.
|
||||
|
||||
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.
|
||||
|
||||
display - display text at the assembly time; arguments are strings or byte
|
||||
values to be displayed.
|
||||
|
||||
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
|
||||
Thanks to:
|
||||
|
||||
Leonid Petroff - for really good work with bugs reporting and many
|
||||
helpful suggestions
|
||||
|
||||
Bartek Uliasz - without him the flat assembler project would never
|
||||
be started
|
||||
|
||||
and all others who helped me (there were many of them)!
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
flat assembler version 1.39
|
||||
flat assembler version 1.40
|
||||
Copyright (c) 1999-2002, Tomasz Grysztar
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -35,4 +35,3 @@ The licence and distribution terms for any publically available
|
|||
version or derivative of this code cannot be changed. i.e. this code
|
||||
cannot simply be copied and put under another distribution licence
|
||||
(including the GNU Public Licence).
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ assembler:
|
|||
shr ecx,2
|
||||
xor eax,eax
|
||||
rep stos dword [edi]
|
||||
mov [stub_size],eax
|
||||
mov [current_pass],0
|
||||
mov [number_of_sections],0
|
||||
mov [times_working],0
|
||||
|
|
@ -26,10 +27,12 @@ assembler:
|
|||
mov [virtual_data],0
|
||||
mov esi,[source_start]
|
||||
mov edi,[code_start]
|
||||
mov [org_origin],edi
|
||||
mov [org_start],edi
|
||||
mov [org_sib],0
|
||||
mov [error_line],0
|
||||
mov [counter],0
|
||||
xor eax,eax
|
||||
mov [org_sib],eax
|
||||
mov [error_line],eax
|
||||
mov [counter],eax
|
||||
mov [number_of_relocations],0
|
||||
mov [undefined_data_end],0
|
||||
pass_loop:
|
||||
|
|
@ -61,7 +64,7 @@ assemble_line:
|
|||
mov eax,[display_buffer]
|
||||
sub eax,100h
|
||||
cmp edi,eax
|
||||
jae out_of_memory
|
||||
ja out_of_memory
|
||||
lods byte [esi]
|
||||
or al,al
|
||||
jz source_end
|
||||
|
|
@ -103,7 +106,7 @@ assemble_line:
|
|||
mov cl,al
|
||||
shl ecx,16
|
||||
mov eax,edi
|
||||
sub eax,[org_start]
|
||||
sub eax,[org_origin]
|
||||
cdq
|
||||
xor ch,ch
|
||||
cmp [reloc_labels],0
|
||||
|
|
@ -148,13 +151,23 @@ assemble_line:
|
|||
jmp assemble_line
|
||||
define_constant:
|
||||
lods dword [esi]
|
||||
mov edx,[eax+8]
|
||||
push edx
|
||||
cmp [current_pass],0
|
||||
je get_constant_value
|
||||
test dl,4
|
||||
jnz get_constant_value
|
||||
and dl,not 1
|
||||
mov [eax+8],dl
|
||||
get_constant_value:
|
||||
push eax
|
||||
lods byte [esi]
|
||||
push ax
|
||||
push eax
|
||||
call get_value
|
||||
pop bx
|
||||
pop ebx
|
||||
mov ch,bl
|
||||
pop ebx
|
||||
pop dword [ebx+8]
|
||||
or ebx,ebx
|
||||
jz set_org
|
||||
cmp ebx,10h
|
||||
|
|
@ -331,8 +344,9 @@ org_directive:
|
|||
org_ok:
|
||||
mov ecx,edi
|
||||
sub ecx,eax
|
||||
mov [org_start],ecx
|
||||
mov [org_origin],ecx
|
||||
mov [org_sib],0
|
||||
mov [org_start],edi
|
||||
jmp instruction_assembled
|
||||
label_directive:
|
||||
lods byte [esi]
|
||||
|
|
@ -357,7 +371,7 @@ label_directive:
|
|||
mov cl,ah
|
||||
label_size_ok:
|
||||
mov eax,edi
|
||||
sub eax,[org_start]
|
||||
sub eax,[org_origin]
|
||||
cdq
|
||||
mov ebp,[org_sib]
|
||||
shl ecx,16
|
||||
|
|
@ -367,7 +381,9 @@ label_directive:
|
|||
lods byte [esi]
|
||||
cmp al,'('
|
||||
jne invalid_argument
|
||||
push dword [ebx+8]
|
||||
push ebx ecx
|
||||
and byte [ebx+8],not 1
|
||||
cmp byte [esi],'.'
|
||||
je invalid_value
|
||||
call get_address_value
|
||||
|
|
@ -379,6 +395,7 @@ label_directive:
|
|||
xchg bl,bh
|
||||
mov bp,bx
|
||||
pop ecx ebx
|
||||
pop dword [ebx+8]
|
||||
cdq
|
||||
or ch,[value_type]
|
||||
jz free_label_reloc_ok
|
||||
|
|
@ -444,12 +461,14 @@ load_directive:
|
|||
cmp al,8
|
||||
ja invalid_value
|
||||
mov [operand_size],al
|
||||
lods byte [esi]
|
||||
cmp al,82h
|
||||
jne invalid_argument
|
||||
mov dword [value],0
|
||||
mov dword [value+4],0
|
||||
lods word [esi]
|
||||
cmp ax,'('
|
||||
cmp ax,82h+'(' shl 8
|
||||
jne invalid_argument
|
||||
cmp byte [esi],0
|
||||
jne load_from_code
|
||||
inc esi
|
||||
lea edx,[esi+4]
|
||||
mov eax,[esi]
|
||||
lea esi,[esi+4+eax+1]
|
||||
|
|
@ -474,18 +493,37 @@ load_directive:
|
|||
load_position_ok:
|
||||
xor al,al
|
||||
call lseek
|
||||
mov dword [value],0
|
||||
mov dword [value+4],0
|
||||
movzx ecx,[operand_size]
|
||||
mov edx,value
|
||||
call read
|
||||
jc error_reading_file
|
||||
call close
|
||||
value_loaded:
|
||||
mov eax,dword [value]
|
||||
mov edx,dword [value+4]
|
||||
pop ebx
|
||||
xor cx,cx
|
||||
jmp make_constant
|
||||
load_from_code:
|
||||
cmp byte [esi],'.'
|
||||
je invalid_value
|
||||
call get_relative_offset
|
||||
neg eax
|
||||
cmp [value_type],0
|
||||
jne invalid_use_of_symbol
|
||||
push esi edi
|
||||
mov esi,edi
|
||||
sub esi,eax
|
||||
jc value_out_of_range
|
||||
cmp esi,[org_start]
|
||||
jb value_out_of_range
|
||||
mov edi,value
|
||||
movzx ecx,[operand_size]
|
||||
cmp ecx,eax
|
||||
ja value_out_of_range
|
||||
rep movs byte [edi],[esi]
|
||||
pop edi esi
|
||||
jmp value_loaded
|
||||
display_directive:
|
||||
push esi edi
|
||||
prepare_display:
|
||||
|
|
@ -505,7 +543,7 @@ display_directive:
|
|||
stos byte [edi]
|
||||
display_next:
|
||||
cmp edi,[display_buffer]
|
||||
jae out_of_memory
|
||||
ja out_of_memory
|
||||
lods byte [esi]
|
||||
or al,al
|
||||
jz do_display
|
||||
|
|
@ -608,7 +646,7 @@ virtual_directive:
|
|||
virtual_at_current:
|
||||
dec esi
|
||||
mov eax,edi
|
||||
sub eax,[org_start]
|
||||
sub eax,[org_origin]
|
||||
xor bx,bx
|
||||
xor cx,cx
|
||||
mov [value_type],0
|
||||
|
|
@ -625,14 +663,17 @@ virtual_directive:
|
|||
mov word [ebx],virtual_directive-assembler
|
||||
neg eax
|
||||
add eax,edi
|
||||
xchg [org_start],eax
|
||||
xchg [org_origin],eax
|
||||
mov [ebx+4],eax
|
||||
mov [ebx+8],edx
|
||||
mov al,[virtual_data]
|
||||
mov [ebx+2],al
|
||||
mov al,[reloc_labels]
|
||||
mov [ebx+3],al
|
||||
mov [ebx+0Ch],edi
|
||||
mov eax,edi
|
||||
xchg eax,[org_start]
|
||||
mov [ebx+0Ch],eax
|
||||
mov [ebx+10h],edi
|
||||
or [virtual_data],-1
|
||||
mov [reloc_labels],0
|
||||
cmp [value_type],1
|
||||
|
|
@ -643,7 +684,7 @@ virtual_directive:
|
|||
jmp instruction_assembled
|
||||
allocate_structure_data:
|
||||
mov ebx,[structures_buffer]
|
||||
sub ebx,10h
|
||||
sub ebx,14h
|
||||
cmp ebx,[additional_memory]
|
||||
jb out_of_memory
|
||||
mov [structures_buffer],ebx
|
||||
|
|
@ -668,7 +709,7 @@ virtual_directive:
|
|||
cmp word [ebx],repeat_directive-assembler
|
||||
je no_such_structure
|
||||
repeat_structure_ok:
|
||||
add ebx,10h
|
||||
add ebx,14h
|
||||
jmp scan_structures
|
||||
no_such_structure:
|
||||
stc
|
||||
|
|
@ -681,16 +722,18 @@ virtual_directive:
|
|||
mov al,[ebx+3]
|
||||
mov [reloc_labels],al
|
||||
mov eax,[ebx+4]
|
||||
mov [org_start],eax
|
||||
mov [org_origin],eax
|
||||
mov eax,[ebx+8]
|
||||
mov [org_sib],eax
|
||||
mov edi,[ebx+0Ch]
|
||||
mov eax,[ebx+0Ch]
|
||||
mov [org_start],eax
|
||||
mov edi,[ebx+10h]
|
||||
remove_structure_data:
|
||||
push esi edi
|
||||
mov esi,[structures_buffer]
|
||||
mov ecx,ebx
|
||||
sub ecx,esi
|
||||
lea edi,[esi+10h]
|
||||
lea edi,[esi+14h]
|
||||
mov [structures_buffer],edi
|
||||
shr ecx,2
|
||||
rep movs dword [edi],[esi]
|
||||
|
|
@ -916,7 +959,7 @@ data_bytes:
|
|||
stos byte [edi]
|
||||
byte_ok:
|
||||
cmp edi,[display_buffer]
|
||||
jae out_of_memory
|
||||
ja out_of_memory
|
||||
lods byte [esi]
|
||||
or al,al
|
||||
jz data_end
|
||||
|
|
@ -932,6 +975,9 @@ data_bytes:
|
|||
inc esi
|
||||
lods dword [esi]
|
||||
mov ecx,eax
|
||||
lea eax,[edi+ecx]
|
||||
cmp eax,[display_buffer]
|
||||
ja out_of_memory
|
||||
rep movs byte [edi],[esi]
|
||||
inc esi
|
||||
jmp byte_ok
|
||||
|
|
@ -973,7 +1019,7 @@ data_words:
|
|||
stos word [edi]
|
||||
word_ok:
|
||||
cmp edi,[display_buffer]
|
||||
jae out_of_memory
|
||||
ja out_of_memory
|
||||
lods byte [esi]
|
||||
or al,al
|
||||
jz data_end
|
||||
|
|
@ -987,6 +1033,9 @@ data_words:
|
|||
lods dword [esi]
|
||||
mov ecx,eax
|
||||
jecxz word_string_ok
|
||||
lea eax,[edi+ecx*2]
|
||||
cmp eax,[display_buffer]
|
||||
ja out_of_memory
|
||||
xor ah,ah
|
||||
copy_word_string:
|
||||
lods byte [esi]
|
||||
|
|
@ -1026,20 +1075,20 @@ data_dwords:
|
|||
cmp al,'('
|
||||
jne invalid_operand
|
||||
mov al,[value_type]
|
||||
push ax
|
||||
push eax
|
||||
cmp byte [esi],'.'
|
||||
je invalid_value
|
||||
call get_word_value
|
||||
call mark_relocation
|
||||
stos word [edi]
|
||||
pop ax
|
||||
pop eax
|
||||
mov [value_type],al
|
||||
mov ax,dx
|
||||
call mark_relocation
|
||||
stos word [edi]
|
||||
dword_ok:
|
||||
cmp edi,[display_buffer]
|
||||
jae out_of_memory
|
||||
ja out_of_memory
|
||||
lods byte [esi]
|
||||
or al,al
|
||||
jz data_end
|
||||
|
|
@ -1083,20 +1132,20 @@ data_pwords:
|
|||
cmp al,'('
|
||||
jne invalid_operand
|
||||
mov al,[value_type]
|
||||
push ax
|
||||
push eax
|
||||
cmp byte [esi],'.'
|
||||
je invalid_value
|
||||
call get_dword_value
|
||||
call mark_relocation
|
||||
stos dword [edi]
|
||||
pop ax
|
||||
pop eax
|
||||
mov [value_type],al
|
||||
mov ax,dx
|
||||
call mark_relocation
|
||||
stos word [edi]
|
||||
pword_ok:
|
||||
cmp edi,[display_buffer]
|
||||
jae out_of_memory
|
||||
ja out_of_memory
|
||||
lods byte [esi]
|
||||
or al,al
|
||||
jz data_end
|
||||
|
|
@ -1126,7 +1175,7 @@ data_qwords:
|
|||
stos dword [edi]
|
||||
qword_ok:
|
||||
cmp edi,[display_buffer]
|
||||
jae out_of_memory
|
||||
ja out_of_memory
|
||||
lods byte [esi]
|
||||
or al,al
|
||||
jz data_end
|
||||
|
|
@ -1178,7 +1227,7 @@ data_twords:
|
|||
add esi,12
|
||||
tbyte_ok:
|
||||
cmp edi,[display_buffer]
|
||||
jae out_of_memory
|
||||
ja out_of_memory
|
||||
lods byte [esi]
|
||||
or al,al
|
||||
jz data_end
|
||||
|
|
@ -1237,7 +1286,7 @@ data_file:
|
|||
add edi,ecx
|
||||
jc out_of_memory
|
||||
cmp edi,[display_buffer]
|
||||
jae out_of_memory
|
||||
ja out_of_memory
|
||||
call read
|
||||
jc error_reading_file
|
||||
call close
|
||||
|
|
@ -1253,7 +1302,7 @@ data_file:
|
|||
add edi,ecx
|
||||
jc out_of_memory
|
||||
cmp edi,[display_buffer]
|
||||
jae out_of_memory
|
||||
ja out_of_memory
|
||||
jmp check_for_next_name
|
||||
reserve_bytes:
|
||||
lods byte [esi]
|
||||
|
|
@ -1271,7 +1320,7 @@ reserve_bytes:
|
|||
add edx,edi
|
||||
jc out_of_memory
|
||||
cmp edx,[display_buffer]
|
||||
jae out_of_memory
|
||||
ja out_of_memory
|
||||
push edi
|
||||
cmp [next_pass_needed],0
|
||||
je zero_bytes
|
||||
|
|
@ -1317,7 +1366,7 @@ reserve_words:
|
|||
add edx,edi
|
||||
jc out_of_memory
|
||||
cmp edx,[display_buffer]
|
||||
jae out_of_memory
|
||||
ja out_of_memory
|
||||
push edi
|
||||
cmp [next_pass_needed],0
|
||||
je zero_words
|
||||
|
|
@ -1351,7 +1400,7 @@ reserve_dwords:
|
|||
add edx,edi
|
||||
jc out_of_memory
|
||||
cmp edx,[display_buffer]
|
||||
jae out_of_memory
|
||||
ja out_of_memory
|
||||
push edi
|
||||
cmp [next_pass_needed],0
|
||||
je zero_dwords
|
||||
|
|
@ -1382,7 +1431,7 @@ reserve_pwords:
|
|||
add edx,edi
|
||||
jc out_of_memory
|
||||
cmp edx,[display_buffer]
|
||||
jae out_of_memory
|
||||
ja out_of_memory
|
||||
push edi
|
||||
cmp [next_pass_needed],0
|
||||
je zero_words
|
||||
|
|
@ -1410,7 +1459,7 @@ reserve_qwords:
|
|||
add edx,edi
|
||||
jc out_of_memory
|
||||
cmp edx,[display_buffer]
|
||||
jae out_of_memory
|
||||
ja out_of_memory
|
||||
push edi
|
||||
cmp [next_pass_needed],0
|
||||
je zero_dwords
|
||||
|
|
@ -1437,7 +1486,7 @@ reserve_twords:
|
|||
add edx,edi
|
||||
jc out_of_memory
|
||||
cmp edx,[display_buffer]
|
||||
jae out_of_memory
|
||||
ja out_of_memory
|
||||
push edi
|
||||
cmp [next_pass_needed],0
|
||||
je zero_words
|
||||
|
|
@ -1483,7 +1532,7 @@ int_instruction:
|
|||
stos word [edi]
|
||||
jmp instruction_assembled
|
||||
aa_instruction:
|
||||
push ax
|
||||
push eax
|
||||
mov bl,10
|
||||
cmp byte [esi],'('
|
||||
jne .store
|
||||
|
|
@ -1497,7 +1546,7 @@ aa_instruction:
|
|||
.store:
|
||||
cmp [operand_size],0
|
||||
jne invalid_operand
|
||||
pop ax
|
||||
pop eax
|
||||
mov ah,bl
|
||||
stos word [edi]
|
||||
jmp instruction_assembled
|
||||
|
|
@ -2482,7 +2531,6 @@ test_instruction:
|
|||
inc [base_code]
|
||||
call store_instruction
|
||||
jmp instruction_assembled
|
||||
|
||||
test_mem_imm:
|
||||
mov al,[operand_size]
|
||||
cmp al,1
|
||||
|
|
@ -3252,14 +3300,14 @@ lea_instruction:
|
|||
cmp al,','
|
||||
jne invalid_operand
|
||||
mov al,[operand_size]
|
||||
push ax
|
||||
push eax
|
||||
mov [operand_size],0
|
||||
lods byte [esi]
|
||||
call get_size_operator
|
||||
cmp al,'['
|
||||
jne invalid_operand
|
||||
call get_address
|
||||
pop ax
|
||||
pop eax
|
||||
cmp al,2
|
||||
je lea_16bit
|
||||
cmp al,4
|
||||
|
|
@ -3339,7 +3387,7 @@ enter_instruction:
|
|||
call get_word_value
|
||||
cmp [value_type],0
|
||||
jne invalid_use_of_symbol
|
||||
push ax
|
||||
push eax
|
||||
mov [operand_size],0
|
||||
lods byte [esi]
|
||||
cmp al,','
|
||||
|
|
@ -3355,7 +3403,7 @@ enter_instruction:
|
|||
jne invalid_operand
|
||||
call get_byte_value
|
||||
mov dl,al
|
||||
pop bx
|
||||
pop ebx
|
||||
mov al,0C8h
|
||||
stos byte [edi]
|
||||
mov ax,bx
|
||||
|
|
@ -3375,7 +3423,7 @@ sh_instruction:
|
|||
call get_address
|
||||
push edx bx cx
|
||||
mov al,[operand_size]
|
||||
push ax
|
||||
push eax
|
||||
mov [operand_size],0
|
||||
lods byte [esi]
|
||||
cmp al,','
|
||||
|
|
@ -3390,7 +3438,7 @@ sh_instruction:
|
|||
lods byte [esi]
|
||||
cmp al,11h
|
||||
jne invalid_operand
|
||||
pop ax cx bx edx
|
||||
pop eax cx bx edx
|
||||
cmp al,1
|
||||
je sh_mem_cl_8bit
|
||||
cmp al,2
|
||||
|
|
@ -3426,7 +3474,7 @@ sh_instruction:
|
|||
sh_mem_imm_size_ok:
|
||||
call get_byte_value
|
||||
mov byte [value],al
|
||||
pop ax cx bx edx
|
||||
pop eax cx bx edx
|
||||
cmp al,1
|
||||
je sh_mem_imm_8bit
|
||||
cmp al,2
|
||||
|
|
@ -3486,7 +3534,7 @@ sh_instruction:
|
|||
or al,11000000b
|
||||
or [postbyte_register],al
|
||||
mov al,ah
|
||||
push ax
|
||||
push eax
|
||||
mov [operand_size],0
|
||||
lods byte [esi]
|
||||
cmp al,','
|
||||
|
|
@ -3501,7 +3549,7 @@ sh_instruction:
|
|||
lods byte [esi]
|
||||
cmp al,11h
|
||||
jne invalid_operand
|
||||
pop ax
|
||||
pop eax
|
||||
mov bl,[postbyte_register]
|
||||
cmp al,1
|
||||
je sh_reg_cl_8bit
|
||||
|
|
@ -3539,7 +3587,7 @@ sh_instruction:
|
|||
sh_reg_imm_size_ok:
|
||||
call get_byte_value
|
||||
mov byte [value],al
|
||||
pop ax
|
||||
pop eax
|
||||
mov bl,[postbyte_register]
|
||||
cmp al,1
|
||||
je sh_reg_imm_8bit
|
||||
|
|
@ -3624,7 +3672,7 @@ shd_instruction:
|
|||
jne invalid_operand
|
||||
xor al,al
|
||||
xchg al,[operand_size]
|
||||
push ax
|
||||
push eax
|
||||
lods byte [esi]
|
||||
call get_size_operator
|
||||
cmp al,'('
|
||||
|
|
@ -3634,7 +3682,7 @@ shd_instruction:
|
|||
lods byte [esi]
|
||||
cmp al,11h
|
||||
jne invalid_operand
|
||||
pop ax cx bx edx
|
||||
pop eax cx bx edx
|
||||
cmp al,2
|
||||
je shd_mem_reg_cl_16bit
|
||||
cmp al,4
|
||||
|
|
@ -3659,7 +3707,7 @@ shd_instruction:
|
|||
shd_mem_reg_imm_size_ok:
|
||||
call get_byte_value
|
||||
mov byte [value],al
|
||||
pop ax cx bx edx
|
||||
pop eax cx bx edx
|
||||
cmp al,2
|
||||
je shd_mem_reg_imm_16bit
|
||||
cmp al,4
|
||||
|
|
@ -3924,7 +3972,7 @@ bt_instruction:
|
|||
bt_mem_imm:
|
||||
xor al,al
|
||||
xchg al,[operand_size]
|
||||
push ax
|
||||
push eax
|
||||
lods byte [esi]
|
||||
call get_size_operator
|
||||
cmp al,'('
|
||||
|
|
@ -3938,7 +3986,7 @@ bt_instruction:
|
|||
mov [extended_code],0BAh
|
||||
call get_byte_value
|
||||
mov byte [value],al
|
||||
pop ax
|
||||
pop eax
|
||||
cmp al,2
|
||||
je bt_mem_imm_16bit
|
||||
cmp al,4
|
||||
|
|
@ -4013,7 +4061,7 @@ bt_instruction:
|
|||
bt_reg_imm:
|
||||
xor al,al
|
||||
xchg al,[operand_size]
|
||||
push ax
|
||||
push eax
|
||||
lods byte [esi]
|
||||
call get_size_operator
|
||||
cmp al,'('
|
||||
|
|
@ -4026,7 +4074,7 @@ bt_instruction:
|
|||
bt_reg_imm_size_ok:
|
||||
call get_byte_value
|
||||
mov byte [value],al
|
||||
pop ax
|
||||
pop eax
|
||||
cmp al,2
|
||||
je bt_reg_imm_16bit
|
||||
cmp al,4
|
||||
|
|
@ -4069,6 +4117,7 @@ bs_instruction:
|
|||
cmp al,','
|
||||
jne invalid_operand
|
||||
lods byte [esi]
|
||||
call get_size_operator
|
||||
cmp al,10h
|
||||
je bs_reg_reg
|
||||
cmp al,'['
|
||||
|
|
@ -4500,7 +4549,7 @@ in_instruction:
|
|||
cmp al,','
|
||||
jne invalid_operand
|
||||
mov al,ah
|
||||
push ax
|
||||
push eax
|
||||
mov [operand_size],0
|
||||
lods byte [esi]
|
||||
call get_size_operator
|
||||
|
|
@ -4513,7 +4562,7 @@ in_instruction:
|
|||
lods byte [esi]
|
||||
cmp al,22h
|
||||
jne invalid_operand
|
||||
pop ax
|
||||
pop eax
|
||||
cmp al,1
|
||||
je in_al_dx
|
||||
cmp al,2
|
||||
|
|
@ -4544,7 +4593,7 @@ in_instruction:
|
|||
in_imm_size_ok:
|
||||
call get_byte_value
|
||||
mov dl,al
|
||||
pop ax
|
||||
pop eax
|
||||
cmp al,1
|
||||
je in_al_imm
|
||||
cmp al,2
|
||||
|
|
@ -5176,13 +5225,13 @@ jmp_instruction:
|
|||
cmp [jump_type],1
|
||||
je invalid_operand
|
||||
call get_word_value
|
||||
push ax
|
||||
push eax
|
||||
inc esi
|
||||
lods byte [esi]
|
||||
cmp al,'('
|
||||
jne invalid_operand
|
||||
mov al,[value_type]
|
||||
push ax [symbol_identifier]
|
||||
push eax [symbol_identifier]
|
||||
cmp byte [esi],'.'
|
||||
je invalid_value
|
||||
mov bl,[operand_size]
|
||||
|
|
@ -5204,9 +5253,9 @@ jmp_instruction:
|
|||
call mark_relocation
|
||||
stos word [edi]
|
||||
jmp_far_segment:
|
||||
pop [symbol_identifier] ax
|
||||
pop [symbol_identifier] eax
|
||||
mov [value_type],al
|
||||
pop ax
|
||||
pop eax
|
||||
call mark_relocation
|
||||
stos word [edi]
|
||||
jmp instruction_assembled
|
||||
|
|
@ -5316,7 +5365,7 @@ movs_instruction:
|
|||
jnz invalid_address
|
||||
cmp [segment_register],1
|
||||
ja invalid_address
|
||||
push bx
|
||||
push ebx
|
||||
lods byte [esi]
|
||||
cmp al,','
|
||||
jne invalid_operand
|
||||
|
|
@ -5325,7 +5374,7 @@ movs_instruction:
|
|||
cmp al,'['
|
||||
jne invalid_operand
|
||||
call get_address
|
||||
pop dx
|
||||
pop edx
|
||||
or eax,eax
|
||||
jnz invalid_address
|
||||
or bl,ch
|
||||
|
|
@ -5949,7 +5998,7 @@ movd_instruction:
|
|||
cmp ah,4
|
||||
jne invalid_operand_size
|
||||
mov [operand_size],0
|
||||
push ax
|
||||
push eax
|
||||
lods byte [esi]
|
||||
cmp al,','
|
||||
jne invalid_operand
|
||||
|
|
@ -5959,7 +6008,7 @@ movd_instruction:
|
|||
lods byte [esi]
|
||||
call convert_mmx_register
|
||||
call make_mmx_prefix
|
||||
pop bx
|
||||
pop ebx
|
||||
shl al,3
|
||||
or bl,al
|
||||
or bl,11000000b
|
||||
|
|
@ -5972,7 +6021,7 @@ movd_instruction:
|
|||
movd_mmreg:
|
||||
call convert_mmx_register
|
||||
call make_mmx_prefix
|
||||
push ax
|
||||
push eax
|
||||
mov [operand_size],0
|
||||
lods byte [esi]
|
||||
cmp al,','
|
||||
|
|
@ -5984,7 +6033,7 @@ movd_instruction:
|
|||
cmp al,'['
|
||||
jne invalid_operand
|
||||
call get_address
|
||||
pop ax
|
||||
pop eax
|
||||
mov [postbyte_register],al
|
||||
test [operand_size],not 4
|
||||
jnz invalid_operand_size
|
||||
|
|
@ -5997,7 +6046,7 @@ movd_instruction:
|
|||
call convert_register
|
||||
cmp ah,4
|
||||
jne invalid_operand_size
|
||||
pop bx
|
||||
pop ebx
|
||||
shl bl,3
|
||||
or bl,al
|
||||
or bl,11000000b
|
||||
|
|
@ -6048,7 +6097,7 @@ movq_instruction:
|
|||
movq_mmreg:
|
||||
lods byte [esi]
|
||||
call convert_mmx_register
|
||||
push ax
|
||||
push eax
|
||||
lods byte [esi]
|
||||
cmp al,','
|
||||
jne invalid_operand
|
||||
|
|
@ -6060,7 +6109,7 @@ movq_instruction:
|
|||
call get_address
|
||||
test [operand_size],not 8
|
||||
jnz invalid_operand_size
|
||||
pop ax
|
||||
pop eax
|
||||
mov [postbyte_register],al
|
||||
mov [base_code],0Fh
|
||||
cmp [operand_size],16
|
||||
|
|
@ -6074,7 +6123,7 @@ movq_instruction:
|
|||
call store_instruction
|
||||
jmp instruction_assembled
|
||||
movq_mmreg_mmreg:
|
||||
pop bx
|
||||
pop ebx
|
||||
lods byte [esi]
|
||||
call convert_mmx_register
|
||||
shl bl,3
|
||||
|
|
@ -6123,7 +6172,7 @@ movdq_instruction:
|
|||
call convert_mmx_register
|
||||
cmp ah,16
|
||||
jne invalid_operand_size
|
||||
push ax
|
||||
push eax
|
||||
lods byte [esi]
|
||||
cmp al,','
|
||||
jne invalid_operand
|
||||
|
|
@ -6134,14 +6183,14 @@ movdq_instruction:
|
|||
cmp al,'['
|
||||
jne invalid_operand
|
||||
call get_address
|
||||
pop ax
|
||||
pop eax
|
||||
mov [postbyte_register],al
|
||||
mov [base_code],0Fh
|
||||
mov [extended_code],6Fh
|
||||
call store_mmx_instruction
|
||||
jmp instruction_assembled
|
||||
movdq_mmreg_mmreg:
|
||||
pop bx
|
||||
pop ebx
|
||||
lods byte [esi]
|
||||
call convert_mmx_register
|
||||
cmp ah,16
|
||||
|
|
@ -6223,7 +6272,7 @@ mmx_instruction:
|
|||
lods byte [esi]
|
||||
call convert_mmx_register
|
||||
call make_mmx_prefix
|
||||
push ax
|
||||
push eax
|
||||
lods byte [esi]
|
||||
cmp al,','
|
||||
jne invalid_operand
|
||||
|
|
@ -6235,14 +6284,14 @@ mmx_instruction:
|
|||
jne invalid_operand
|
||||
mmx_mmreg_mem:
|
||||
call get_address
|
||||
pop ax
|
||||
pop eax
|
||||
mov [postbyte_register],al
|
||||
call store_mmx_instruction
|
||||
jmp instruction_assembled
|
||||
mmx_mmreg_mmreg:
|
||||
lods byte [esi]
|
||||
call convert_mmx_register
|
||||
pop bx
|
||||
pop ebx
|
||||
shl bl,3
|
||||
or bl,al
|
||||
or bl,11000000b
|
||||
|
|
@ -6262,7 +6311,7 @@ mmx_ps_instruction:
|
|||
lods byte [esi]
|
||||
call convert_mmx_register
|
||||
call make_mmx_prefix
|
||||
push ax
|
||||
push eax
|
||||
lods byte [esi]
|
||||
cmp al,','
|
||||
jne invalid_operand
|
||||
|
|
@ -6289,7 +6338,7 @@ mmx_ps_instruction:
|
|||
mov [extended_code],ah
|
||||
sub al,0Ch
|
||||
shl al,1
|
||||
pop bx
|
||||
pop ebx
|
||||
shl al,3
|
||||
or bl,al
|
||||
or bl,11000000b
|
||||
|
|
@ -6408,7 +6457,7 @@ pshufd_instruction:
|
|||
call convert_mmx_register
|
||||
cmp ah,[mmx_size]
|
||||
jne invalid_operand_size
|
||||
push ax
|
||||
push eax
|
||||
lods byte [esi]
|
||||
cmp al,','
|
||||
jne invalid_operand
|
||||
|
|
@ -6419,14 +6468,14 @@ pshufd_instruction:
|
|||
cmp al,'['
|
||||
jne invalid_operand
|
||||
call get_address
|
||||
pop ax
|
||||
pop eax
|
||||
mov [postbyte_register],al
|
||||
call store_mmx_instruction
|
||||
jmp mmx_imm8
|
||||
pshufw_mmreg_mmreg:
|
||||
lods byte [esi]
|
||||
call convert_mmx_register
|
||||
pop bx
|
||||
pop ebx
|
||||
shl bl,3
|
||||
or bl,al
|
||||
or bl,11000000b
|
||||
|
|
@ -6481,7 +6530,7 @@ sse_instruction:
|
|||
cmp ah,16
|
||||
jne invalid_operand_size
|
||||
sse_reg:
|
||||
push ax
|
||||
push eax
|
||||
mov [operand_size],0
|
||||
lods byte [esi]
|
||||
cmp al,','
|
||||
|
|
@ -6491,7 +6540,7 @@ sse_instruction:
|
|||
je sse_xmmreg_xmmreg
|
||||
call get_size_operator
|
||||
call get_address
|
||||
pop ax
|
||||
pop eax
|
||||
mov [postbyte_register],al
|
||||
cmp [operand_size],0
|
||||
je sse_mem_size_ok
|
||||
|
|
@ -6513,7 +6562,7 @@ sse_instruction:
|
|||
call convert_mmx_register
|
||||
cmp ah,16
|
||||
jne invalid_operand_size
|
||||
pop bx
|
||||
pop ebx
|
||||
shl bl,3
|
||||
or bl,al
|
||||
or bl,11000000b
|
||||
|
|
@ -6525,6 +6574,7 @@ sse_instruction:
|
|||
stos byte [edi]
|
||||
cmp [extended_code],0C6h
|
||||
jne instruction_assembled
|
||||
jmp mmx_imm8
|
||||
ps_dq_instruction:
|
||||
mov bl,al
|
||||
lods byte [esi]
|
||||
|
|
@ -6623,7 +6673,7 @@ movhlps_instruction:
|
|||
call convert_mmx_register
|
||||
cmp ah,16
|
||||
jne invalid_operand_size
|
||||
push ax
|
||||
push eax
|
||||
lods byte [esi]
|
||||
cmp al,','
|
||||
jne invalid_operand
|
||||
|
|
@ -6724,7 +6774,7 @@ sse_cmp_instruction:
|
|||
call convert_mmx_register
|
||||
cmp ah,16
|
||||
jne invalid_operand_size
|
||||
push ax
|
||||
push eax
|
||||
lods byte [esi]
|
||||
cmp al,','
|
||||
jne invalid_operand
|
||||
|
|
@ -6736,7 +6786,7 @@ sse_cmp_instruction:
|
|||
jne invalid_operand
|
||||
mov [operand_size],0
|
||||
call get_address
|
||||
pop ax
|
||||
pop eax
|
||||
mov [postbyte_register],al
|
||||
cmp [operand_size],0
|
||||
je sse_cmp_xmmreg_mem_store
|
||||
|
|
@ -6770,7 +6820,7 @@ sse_cmp_instruction:
|
|||
call convert_mmx_register
|
||||
cmp ah,16
|
||||
jne invalid_operand_size
|
||||
pop bx
|
||||
pop ebx
|
||||
shl bl,3
|
||||
or bl,al
|
||||
or bl,11000000b
|
||||
|
|
@ -6796,7 +6846,7 @@ cvtpi2pd_instruction:
|
|||
call convert_mmx_register
|
||||
cmp ah,16
|
||||
jne invalid_operand_size
|
||||
push ax
|
||||
push eax
|
||||
mov [operand_size],0
|
||||
lods byte [esi]
|
||||
cmp al,','
|
||||
|
|
@ -6808,7 +6858,7 @@ cvtpi2pd_instruction:
|
|||
cmp al,'['
|
||||
jne invalid_operand
|
||||
call get_address
|
||||
pop ax
|
||||
pop eax
|
||||
mov [postbyte_register],al
|
||||
cmp [operand_size],0
|
||||
je cvtpi_size_ok
|
||||
|
|
@ -6822,7 +6872,7 @@ cvtpi2pd_instruction:
|
|||
call convert_mmx_register
|
||||
cmp ah,8
|
||||
jne invalid_operand_size
|
||||
pop bx
|
||||
pop ebx
|
||||
shl bl,3
|
||||
or bl,al
|
||||
or bl,11000000b
|
||||
|
|
@ -6848,7 +6898,7 @@ cvtsi2sd_instruction:
|
|||
call convert_mmx_register
|
||||
cmp ah,16
|
||||
jne invalid_operand_size
|
||||
push ax
|
||||
push eax
|
||||
mov [operand_size],0
|
||||
lods byte [esi]
|
||||
cmp al,','
|
||||
|
|
@ -6860,7 +6910,7 @@ cvtsi2sd_instruction:
|
|||
cmp al,'['
|
||||
jne invalid_operand
|
||||
call get_address
|
||||
pop ax
|
||||
pop eax
|
||||
mov [postbyte_register],al
|
||||
cmp [operand_size],0
|
||||
je cvtsi_size_ok
|
||||
|
|
@ -6874,7 +6924,7 @@ cvtsi2sd_instruction:
|
|||
call convert_register
|
||||
cmp [operand_size],4
|
||||
jne invalid_operand_size
|
||||
pop bx
|
||||
pop ebx
|
||||
shl bl,3
|
||||
or bl,al
|
||||
or bl,11000000b
|
||||
|
|
@ -6973,7 +7023,7 @@ maskmovdqu_instruction:
|
|||
call convert_mmx_register
|
||||
cmp ah,cl
|
||||
jne invalid_operand_size
|
||||
push ax
|
||||
push eax
|
||||
lods byte [esi]
|
||||
cmp al,','
|
||||
jne invalid_operand
|
||||
|
|
@ -6982,7 +7032,7 @@ maskmovdqu_instruction:
|
|||
jne invalid_operand
|
||||
lods byte [esi]
|
||||
call convert_mmx_register
|
||||
pop bx
|
||||
pop ebx
|
||||
shl bl,3
|
||||
or bl,al
|
||||
or bl,11000000b
|
||||
|
|
@ -7231,8 +7281,6 @@ store_instruction:
|
|||
address_bp:
|
||||
mov al,110b
|
||||
postbyte_16bit:
|
||||
cmp ch,1
|
||||
je address_8bit_value
|
||||
cmp ch,2
|
||||
je address_16bit_value
|
||||
or ch,ch
|
||||
|
|
@ -7308,8 +7356,6 @@ store_instruction:
|
|||
or ah,bl
|
||||
and bh,111b
|
||||
or ah,bh
|
||||
cmp ch,1
|
||||
je sib_address_8bit_value
|
||||
test ch,4
|
||||
jnz sib_address_32bit_value
|
||||
cmp ch,2
|
||||
|
|
@ -7372,8 +7418,6 @@ store_instruction:
|
|||
and al,111b
|
||||
cmp al,4
|
||||
je zero_index_register
|
||||
cmp ch,1
|
||||
je simple_address_8bit_value
|
||||
test ch,4
|
||||
jnz simple_address_32bit_value
|
||||
cmp ch,2
|
||||
|
|
@ -7434,8 +7478,11 @@ store_instruction:
|
|||
jz address_relocation_ok
|
||||
mov al,2
|
||||
xchg [value_type],al
|
||||
mov ebx,[address_symbol]
|
||||
xchg ebx,[symbol_identifier]
|
||||
call mark_relocation
|
||||
mov [value_type],al
|
||||
mov [symbol_identifier],ebx
|
||||
address_relocation_ok:
|
||||
mov eax,edx
|
||||
stos dword [edi]
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@ start:
|
|||
je information
|
||||
inc eax
|
||||
mov [output_file],eax
|
||||
movzx ecx,byte [eax-1]
|
||||
add eax,ecx
|
||||
cmp byte [eax],0
|
||||
jne information
|
||||
|
||||
mov di,characters
|
||||
mov cx,100h
|
||||
|
|
@ -190,10 +194,13 @@ macro_block dd ?
|
|||
macro_block_line_number dd ?
|
||||
struc_name dd ?
|
||||
current_locals_prefix dd ?
|
||||
anonymous_reverse dd ?
|
||||
anonymous_forward dd ?
|
||||
labels_list dd ?
|
||||
label_hash dd ?
|
||||
org_start dd ?
|
||||
org_origin dd ?
|
||||
org_sib dd ?
|
||||
org_start dd ?
|
||||
undefined_data_start dd ?
|
||||
undefined_data_end dd ?
|
||||
counter dd ?
|
||||
|
|
@ -207,6 +214,7 @@ current_offset dd ?
|
|||
value dq ?
|
||||
fp_value rd 8
|
||||
symbol_identifier dd ?
|
||||
address_symbol dd ?
|
||||
format_flags dd ?
|
||||
number_of_relocations dd ?
|
||||
number_of_sections dd ?
|
||||
|
|
@ -217,6 +225,7 @@ current_section dd ?
|
|||
machine dw ?
|
||||
subsystem dw ?
|
||||
subsystem_version dd ?
|
||||
image_base dd ?
|
||||
|
||||
macro_status db ?
|
||||
parenthesis_stack db ?
|
||||
|
|
|
|||
|
|
@ -247,35 +247,100 @@ xms_call dd ? ; XMS driver pointer
|
|||
xms_handle dw ? ; handle of XMS memory block
|
||||
|
||||
open:
|
||||
push edx esi di
|
||||
mov esi,edx
|
||||
mov di,buffer
|
||||
.name:
|
||||
lods byte [esi]
|
||||
stos byte [di]
|
||||
or al,al
|
||||
jnz .name
|
||||
mov dx,buffer
|
||||
push esi di
|
||||
call convert_path
|
||||
mov ax,3D00h
|
||||
int 21h
|
||||
mov bx,ax
|
||||
pop di esi edx
|
||||
pop di esi
|
||||
ret
|
||||
create:
|
||||
push edx esi di
|
||||
convert_path:
|
||||
mov esi,edx
|
||||
mov di,buffer
|
||||
.name:
|
||||
copy_path:
|
||||
lods byte [esi]
|
||||
stos byte [es:di]
|
||||
cmp al,'%'
|
||||
je environment_variable
|
||||
cmp al,'/'
|
||||
jne path_char_ok
|
||||
mov al,'\'
|
||||
path_char_ok:
|
||||
stos byte [di]
|
||||
or al,al
|
||||
jnz .name
|
||||
jnz copy_path
|
||||
sub di,buffer
|
||||
cmp di,4000h
|
||||
ja out_of_memory
|
||||
mov dx,buffer
|
||||
ret
|
||||
environment_variable:
|
||||
mov ebx,esi
|
||||
find_variable_end:
|
||||
lods byte [esi]
|
||||
or al,al
|
||||
jz not_environment_variable
|
||||
cmp al,'%'
|
||||
jne find_variable_end
|
||||
push esi
|
||||
mov si,cs
|
||||
neg si
|
||||
add si,[2Ch]
|
||||
movsx esi,si
|
||||
sal esi,4
|
||||
compare_variable_names:
|
||||
mov edx,ebx
|
||||
compare_character:
|
||||
lods byte [esi]
|
||||
mov ah,[edx]
|
||||
inc edx
|
||||
cmp al,'='
|
||||
je end_of_variable_name
|
||||
cmp ah,'%'
|
||||
je next_variable
|
||||
sub ah,al
|
||||
jz compare_character
|
||||
cmp ah,20h
|
||||
jne next_variable
|
||||
cmp al,41h
|
||||
jb next_variable
|
||||
cmp al,5Ah
|
||||
jna compare_character
|
||||
next_variable:
|
||||
lods byte [esi]
|
||||
or al,al
|
||||
jnz next_variable
|
||||
cmp byte [esi],0
|
||||
jne compare_variable_names
|
||||
pop esi
|
||||
jmp copy_path
|
||||
end_of_variable_name:
|
||||
cmp ah,'%'
|
||||
jne next_variable
|
||||
copy_variable_value:
|
||||
lods byte [esi]
|
||||
cmp al,'/'
|
||||
jne value_char_ok
|
||||
mov al,'\'
|
||||
value_char_ok:
|
||||
stos byte [di]
|
||||
or al,al
|
||||
jnz copy_variable_value
|
||||
dec di
|
||||
pop esi
|
||||
jmp copy_path
|
||||
not_environment_variable:
|
||||
mov al,'%'
|
||||
stos byte [di]
|
||||
mov esi,ebx
|
||||
jmp copy_path
|
||||
create:
|
||||
push esi di
|
||||
call convert_path
|
||||
mov ah,3Ch
|
||||
xor cx,cx
|
||||
int 21h
|
||||
mov bx,ax
|
||||
pop di esi edx
|
||||
pop di esi
|
||||
ret
|
||||
write:
|
||||
push edx esi edi ebp
|
||||
|
|
@ -510,7 +575,91 @@ assembler_error:
|
|||
int 21h
|
||||
jmp exit_program
|
||||
|
||||
times 12 nop
|
||||
make_timestamp:
|
||||
mov ah,2Ah
|
||||
int 21h
|
||||
push dx cx
|
||||
movzx ecx,cx
|
||||
mov eax,ecx
|
||||
sub eax,1970
|
||||
mov ebx,365
|
||||
mul ebx
|
||||
mov ebp,eax
|
||||
mov eax,ecx
|
||||
sub eax,1969
|
||||
shr eax,2
|
||||
add ebp,eax
|
||||
mov eax,ecx
|
||||
sub eax,1901
|
||||
mov ebx,100
|
||||
div ebx
|
||||
sub ebp,eax
|
||||
mov eax,ecx
|
||||
xor edx,edx
|
||||
sub eax,1601
|
||||
mov ebx,400
|
||||
div ebx
|
||||
add ebp,eax
|
||||
movzx ecx,byte [esp+3]
|
||||
mov eax,ecx
|
||||
dec eax
|
||||
mov ebx,30
|
||||
mul ebx
|
||||
add ebp,eax
|
||||
cmp ecx,8
|
||||
jbe months_correction
|
||||
mov eax,ecx
|
||||
sub eax,7
|
||||
shr eax,1
|
||||
add ebp,eax
|
||||
mov ecx,8
|
||||
months_correction:
|
||||
mov eax,ecx
|
||||
shr eax,1
|
||||
add ebp,eax
|
||||
sub ebp,2
|
||||
cmp ecx,2
|
||||
jbe day_correction_ok
|
||||
pop cx
|
||||
test ecx,11b
|
||||
jnz day_correction_ok
|
||||
xor edx,edx
|
||||
mov eax,ecx
|
||||
mov ebx,100
|
||||
div ebx
|
||||
or edx,edx
|
||||
jnz day_correction
|
||||
mov eax,ecx
|
||||
mov ebx,400
|
||||
div ebx
|
||||
or edx,edx
|
||||
jnz day_correction_ok
|
||||
day_correction:
|
||||
inc ebp
|
||||
day_correction_ok:
|
||||
pop dx
|
||||
movzx eax,dl
|
||||
dec eax
|
||||
add eax,ebp
|
||||
mov ebx,24
|
||||
mul ebx
|
||||
push eax
|
||||
mov ah,2Ch
|
||||
int 21h
|
||||
pop eax
|
||||
push dx
|
||||
movzx ebx,ch
|
||||
add eax,ebx
|
||||
mov ebx,60
|
||||
mul ebx
|
||||
movzx ebx,cl
|
||||
add eax,ebx
|
||||
mov ebx,60
|
||||
mul ebx
|
||||
pop dx
|
||||
movzx ebx,dh
|
||||
add eax,ebx
|
||||
ret
|
||||
|
||||
character db ?,0
|
||||
bytes_count dd ?
|
||||
|
|
|
|||
|
|
@ -36,17 +36,17 @@ convert_expression:
|
|||
and bh,0F0h
|
||||
cmp bl,bh
|
||||
ja push_operator
|
||||
pop bx
|
||||
pop ebx
|
||||
mov byte [edi],bl
|
||||
inc edi
|
||||
jmp operators_loop
|
||||
push_operator:
|
||||
push ax
|
||||
push eax
|
||||
jmp expression_loop
|
||||
expression_end:
|
||||
cmp esp,ebp
|
||||
je expression_converted
|
||||
pop ax
|
||||
pop eax
|
||||
stos byte [edi]
|
||||
jmp expression_end
|
||||
expression_converted:
|
||||
|
|
@ -382,6 +382,10 @@ get_fp_value:
|
|||
je fp_character_exp
|
||||
cmp al,'e'
|
||||
je fp_character_exp
|
||||
cmp al,'F'
|
||||
je fp_last_character
|
||||
cmp al,'f'
|
||||
je fp_last_character
|
||||
cmp al,'0'
|
||||
jb not_fp_value
|
||||
cmp al,'9'
|
||||
|
|
@ -395,13 +399,18 @@ get_fp_value:
|
|||
fp_character_exp:
|
||||
cmp ah,1
|
||||
ja not_fp_value
|
||||
mov ah,2
|
||||
or ah,2
|
||||
cmp ecx,1
|
||||
jne fp_character_ok
|
||||
cmp byte [esi],'+'
|
||||
je fp_exp_sign
|
||||
cmp byte [esi],'-'
|
||||
jne fp_character_ok
|
||||
fp_last_character:
|
||||
cmp cl,1
|
||||
jne not_fp_value
|
||||
or ah,4
|
||||
jmp fp_character_ok
|
||||
fp_exp_sign:
|
||||
inc esi
|
||||
cmp byte [esi],1Ah
|
||||
|
|
@ -442,6 +451,10 @@ get_fp_value:
|
|||
je fp_exponent
|
||||
cmp al,'e'
|
||||
je fp_exponent
|
||||
cmp al,'F'
|
||||
je fp_done
|
||||
cmp al,'f'
|
||||
je fp_done
|
||||
sub al,30h
|
||||
mov edi,fp_value+16
|
||||
xor edx,edx
|
||||
|
|
@ -476,6 +489,10 @@ get_fp_value:
|
|||
je fp_exponent
|
||||
cmp al,'e'
|
||||
je fp_exponent
|
||||
cmp al,'F'
|
||||
je fp_done
|
||||
cmp al,'f'
|
||||
je fp_done
|
||||
inc [fp_format]
|
||||
cmp [fp_format],80h
|
||||
jne fp_counter_ok
|
||||
|
|
@ -524,11 +541,14 @@ get_fp_value:
|
|||
movzx eax,byte [esi]
|
||||
inc esi
|
||||
sub al,30h
|
||||
cmp al,10
|
||||
jae exponent_ok
|
||||
imul edx,10
|
||||
cmp edx,8000h
|
||||
jae value_out_of_range
|
||||
add edx,eax
|
||||
loop get_exponent
|
||||
exponent_ok:
|
||||
mov edi,fp_value
|
||||
or edx,edx
|
||||
jz fp_done
|
||||
|
|
@ -773,9 +793,12 @@ calculate_expression:
|
|||
je calculate_add
|
||||
cmp al,81h
|
||||
je calculate_sub
|
||||
cmp [next_pass_needed],0
|
||||
jne absolute_values_calculation
|
||||
mov ah,[ebx+12]
|
||||
or ah,[edi+12]
|
||||
jnz invalid_use_of_symbol
|
||||
absolute_values_calculation:
|
||||
cmp al,90h
|
||||
je calculate_mul
|
||||
cmp al,91h
|
||||
|
|
@ -910,7 +933,7 @@ calculate_expression:
|
|||
mov [edi+16],eax
|
||||
get_current_offset:
|
||||
mov eax,[current_offset]
|
||||
sub eax,[org_start]
|
||||
sub eax,[org_origin]
|
||||
cdq
|
||||
stos dword [edi]
|
||||
mov eax,edx
|
||||
|
|
@ -937,12 +960,12 @@ calculate_expression:
|
|||
add edi,0Ch
|
||||
jmp calculation_loop
|
||||
calculate_add:
|
||||
cmp [next_pass_needed],0
|
||||
jne add_values
|
||||
mov ecx,[ebx+16]
|
||||
cmp byte [edi+12],0
|
||||
je add_values
|
||||
mov ecx,[edi+16]
|
||||
cmp [next_pass_needed],0
|
||||
jne add_values
|
||||
cmp byte [ebx+12],0
|
||||
jne invalid_use_of_symbol
|
||||
add_values:
|
||||
|
|
@ -1001,14 +1024,12 @@ calculate_expression:
|
|||
ret
|
||||
calculate_sub:
|
||||
xor ah,ah
|
||||
cmp [next_pass_needed],0
|
||||
jne sub_values
|
||||
mov ah,[ebx+12]
|
||||
mov al,[edi+12]
|
||||
or al,al
|
||||
jz sub_values
|
||||
cmp al,ah
|
||||
jne invalid_use_of_symbol
|
||||
jne invalid_sub
|
||||
xor ah,ah
|
||||
cmp [output_format],4
|
||||
jne sub_values
|
||||
|
|
@ -1016,7 +1037,7 @@ calculate_expression:
|
|||
cmp ecx,[ebx+16]
|
||||
je sub_values
|
||||
cmp ecx,[current_section]
|
||||
jne invalid_use_of_symbol
|
||||
jne invalid_sub
|
||||
mov ah,3
|
||||
sub_values:
|
||||
mov [ebx+12],ah
|
||||
|
|
@ -1036,6 +1057,10 @@ calculate_expression:
|
|||
call sub_register
|
||||
pop esi
|
||||
jmp calculation_loop
|
||||
invalid_sub:
|
||||
cmp [next_pass_needed],0
|
||||
jne sub_values
|
||||
jmp invalid_use_of_symbol
|
||||
sub_register:
|
||||
or cl,cl
|
||||
jz add_register_done
|
||||
|
|
@ -1059,19 +1084,19 @@ calculate_expression:
|
|||
xchg eax,[edi+12]
|
||||
mov [ebx+12],eax
|
||||
mul_start:
|
||||
push esi dx
|
||||
push esi edx
|
||||
mov esi,ebx
|
||||
xor bl,bl
|
||||
test dword [esi+4],1 shl 31
|
||||
jz mul_first_sign_ok
|
||||
bt dword [esi+4],31
|
||||
jnc mul_first_sign_ok
|
||||
not dword [esi]
|
||||
not dword [esi+4]
|
||||
add dword [esi],1
|
||||
adc dword [esi+4],0
|
||||
not bl
|
||||
mul_first_sign_ok:
|
||||
test dword [edi+4],1 shl 31
|
||||
jz mul_second_sign_ok
|
||||
bt dword [edi+4],31
|
||||
jnc mul_second_sign_ok
|
||||
not dword [edi]
|
||||
not dword [edi+4]
|
||||
add dword [edi],1
|
||||
|
|
@ -1107,7 +1132,7 @@ calculate_expression:
|
|||
add dword [esi],1
|
||||
adc dword [esi+4],0
|
||||
mul_ok:
|
||||
pop dx
|
||||
pop edx
|
||||
or dx,dx
|
||||
jz mul_calculated
|
||||
cmp word [edi+8],0
|
||||
|
|
@ -1149,10 +1174,10 @@ calculate_expression:
|
|||
pop esi
|
||||
jmp calculation_loop
|
||||
calculate_div:
|
||||
push esi dx
|
||||
push esi edx
|
||||
mov esi,ebx
|
||||
call div_64
|
||||
pop dx
|
||||
pop edx
|
||||
or dx,dx
|
||||
jz div_calculated
|
||||
cmp byte [esi+8],0
|
||||
|
|
@ -1260,8 +1285,8 @@ calculate_expression:
|
|||
jmp calculation_loop
|
||||
calculate_shl:
|
||||
mov eax,dword [edi+4]
|
||||
test eax,1 shl 31
|
||||
jnz shl_negative
|
||||
bt eax,31
|
||||
jc shl_negative
|
||||
or eax,eax
|
||||
jnz zero_value
|
||||
mov ecx,[edi]
|
||||
|
|
@ -1290,8 +1315,8 @@ calculate_expression:
|
|||
adc dword [edi+4],0
|
||||
calculate_shr:
|
||||
mov eax,dword [edi+4]
|
||||
test eax,1 shl 31
|
||||
jnz shr_negative
|
||||
bt eax,31
|
||||
jc shr_negative
|
||||
or eax,eax
|
||||
jnz zero_value
|
||||
mov ecx,[edi]
|
||||
|
|
@ -1324,10 +1349,13 @@ calculate_expression:
|
|||
mov dword [ebx+4],0
|
||||
jmp calculation_loop
|
||||
calculate_not:
|
||||
cmp [next_pass_needed],0
|
||||
jne not_ok
|
||||
cmp word [edi+8],0
|
||||
jne invalid_expression
|
||||
cmp byte [edi+12],0
|
||||
jne invalid_use_of_symbol
|
||||
not_ok:
|
||||
cmp [value_size],1
|
||||
je not_byte
|
||||
cmp [value_size],2
|
||||
|
|
@ -1373,10 +1401,13 @@ calculate_expression:
|
|||
add edi,14h
|
||||
jmp calculation_loop
|
||||
calculate_neg:
|
||||
cmp [next_pass_needed],0
|
||||
jne neg_ok
|
||||
cmp word [edi+8],0
|
||||
jne invalid_expression
|
||||
cmp byte [edi+12],0
|
||||
jne invalid_use_of_symbol
|
||||
neg_ok:
|
||||
mov eax,[edi]
|
||||
mov edx,[edi+4]
|
||||
mov dword [edi],0
|
||||
|
|
@ -1386,17 +1417,14 @@ calculate_expression:
|
|||
add edi,14h
|
||||
jmp calculation_loop
|
||||
calculate_rva:
|
||||
cmp [next_pass_needed],0
|
||||
jne rva_ok
|
||||
cmp word [edi+8],0
|
||||
jne invalid_expression
|
||||
cmp [output_format],3
|
||||
jne invalid_use_of_symbol
|
||||
mov al,[edi+12]
|
||||
cmp al,2
|
||||
je rva_ok
|
||||
or al,al
|
||||
jnz invalid_use_of_symbol
|
||||
cmp [next_pass_needed],0
|
||||
je invalid_use_of_symbol
|
||||
cmp byte [edi+12],2
|
||||
jne invalid_use_of_symbol
|
||||
rva_ok:
|
||||
mov byte [edi+12],0
|
||||
mov eax,[header_data]
|
||||
|
|
@ -1415,16 +1443,16 @@ calculate_expression:
|
|||
je value_out_of_range
|
||||
jmp div_done
|
||||
divider_ok:
|
||||
test dword [esi+4],1 shl 31
|
||||
jz div_first_sign_ok
|
||||
bt dword [esi+4],31
|
||||
jnc div_first_sign_ok
|
||||
not dword [esi]
|
||||
not dword [esi+4]
|
||||
add dword [esi],1
|
||||
adc dword [esi+4],0
|
||||
not bl
|
||||
div_first_sign_ok:
|
||||
test dword [edi+4],1 shl 31
|
||||
jz div_second_sign_ok
|
||||
bt dword [edi+4],31
|
||||
jnc div_second_sign_ok
|
||||
not dword [edi]
|
||||
not dword [edi+4]
|
||||
add dword [edi],1
|
||||
|
|
@ -1498,8 +1526,8 @@ calculate_expression:
|
|||
shr eax,9
|
||||
jnc fp_dword_ok
|
||||
inc eax
|
||||
test eax,1 shl 23
|
||||
jz fp_dword_ok
|
||||
bt eax,23
|
||||
jnc fp_dword_ok
|
||||
and eax,1 shl 23 - 1
|
||||
inc bx
|
||||
shr eax,1
|
||||
|
|
@ -1534,8 +1562,8 @@ calculate_expression:
|
|||
jnc fp_qword_ok
|
||||
add eax,1
|
||||
adc edx,0
|
||||
test edx,1 shl 20
|
||||
jz fp_qword_ok
|
||||
bt edx,20
|
||||
jnc fp_qword_ok
|
||||
and edx,1 shl 20 - 1
|
||||
inc bx
|
||||
shr edx,1
|
||||
|
|
@ -1628,7 +1656,6 @@ get_dword_value:
|
|||
mov [value_size],4
|
||||
mov [forced_size],2
|
||||
call calculate_expression
|
||||
got_dword_value:
|
||||
cmp word [edi+8],0
|
||||
jne invalid_value
|
||||
mov al,[edi+12]
|
||||
|
|
@ -1639,8 +1666,8 @@ get_dword_value:
|
|||
je dword_positive
|
||||
cmp dword [edi+4],-1
|
||||
jne range_exceeded
|
||||
test eax,1 shl 31
|
||||
jz range_exceeded
|
||||
bt eax,31
|
||||
jnc range_exceeded
|
||||
dword_positive:
|
||||
ret
|
||||
get_pword_value:
|
||||
|
|
@ -1730,6 +1757,8 @@ get_address:
|
|||
jne calculate_address
|
||||
lods byte [esi]
|
||||
sub al,70h
|
||||
cmp al,2
|
||||
jb invalid_address_size
|
||||
cmp al,4
|
||||
ja invalid_address_size
|
||||
mov [address_size],al
|
||||
|
|
@ -1741,6 +1770,8 @@ get_address_value:
|
|||
push address_ok
|
||||
calculate_address:
|
||||
call calculate_expression
|
||||
mov eax,[edi+16]
|
||||
mov [address_symbol],eax
|
||||
mov al,[edi+12]
|
||||
mov [value_type],al
|
||||
cmp al,1
|
||||
|
|
@ -1849,28 +1880,43 @@ get_relative_offset:
|
|||
mov word [esi+5],')' shl 8 + 81h
|
||||
call calculation_loop
|
||||
pop esi
|
||||
jmp got_dword_value
|
||||
cmp word [edi+8],0
|
||||
jne invalid_value
|
||||
mov al,[edi+12]
|
||||
mov [value_type],al
|
||||
mov eax,[edi]
|
||||
cmp dword [edi+4],0
|
||||
je offset_positive
|
||||
cmp dword [edi+4],-1
|
||||
jne range_exceeded
|
||||
bt eax,31
|
||||
jnc range_exceeded
|
||||
ret
|
||||
offset_positive:
|
||||
bt eax,31
|
||||
jc range_exceeded
|
||||
ret
|
||||
|
||||
calculate_logical_expression:
|
||||
call get_logical_value
|
||||
logical_loop:
|
||||
push ax
|
||||
push eax
|
||||
lods byte [esi]
|
||||
cmp al,'|'
|
||||
je logical_or
|
||||
cmp al,'&'
|
||||
je logical_and
|
||||
dec esi
|
||||
pop ax
|
||||
pop eax
|
||||
ret
|
||||
logical_or:
|
||||
call get_logical_value
|
||||
pop bx
|
||||
pop ebx
|
||||
or al,bl
|
||||
jmp logical_loop
|
||||
logical_and:
|
||||
call get_logical_value
|
||||
pop bx
|
||||
pop ebx
|
||||
and al,bl
|
||||
jmp logical_loop
|
||||
|
||||
|
|
@ -1881,7 +1927,7 @@ get_logical_value:
|
|||
inc esi
|
||||
or al,-1
|
||||
negation_ok:
|
||||
push ax
|
||||
push eax
|
||||
cmp byte [esi],'{'
|
||||
je logical_expression
|
||||
push esi
|
||||
|
|
@ -2013,11 +2059,11 @@ get_logical_value:
|
|||
pop esi
|
||||
call get_value
|
||||
mov bl,[value_type]
|
||||
push eax edx bx
|
||||
push eax edx ebx
|
||||
lods byte [esi]
|
||||
mov [compare_type],al
|
||||
call get_value
|
||||
pop bx
|
||||
pop ebx
|
||||
cmp [next_pass_needed],0
|
||||
jne values_ok
|
||||
cmp bl,[value_type]
|
||||
|
|
@ -2093,12 +2139,12 @@ get_logical_value:
|
|||
logical_expression:
|
||||
inc esi
|
||||
call calculate_logical_expression
|
||||
push ax
|
||||
push eax
|
||||
lods byte [esi]
|
||||
cmp al,'}'
|
||||
jne invalid_expression
|
||||
pop ax
|
||||
pop eax
|
||||
logical_value_ok:
|
||||
pop bx
|
||||
pop ebx
|
||||
xor al,bl
|
||||
ret
|
||||
|
|
|
|||
|
|
@ -176,6 +176,8 @@ segment_directive:
|
|||
mov edx,edi
|
||||
xor al,al
|
||||
rep stos byte [edi]
|
||||
mov [org_origin],edi
|
||||
mov [org_sib],0
|
||||
mov [org_start],edi
|
||||
mov eax,edx
|
||||
call undefined_data
|
||||
|
|
@ -539,32 +541,24 @@ format_pe:
|
|||
mov [machine],14Ch ; intel 80386
|
||||
mov [subsystem],3 ; console subsystem
|
||||
mov [subsystem_version],3 + 10 shl 16
|
||||
mov [image_base],400000h
|
||||
xor edx,edx
|
||||
pe_settings:
|
||||
cmp byte [esi],84h
|
||||
je get_stub_name
|
||||
cmp byte [esi],80h
|
||||
je get_pe_base
|
||||
cmp byte [esi],1Bh
|
||||
jne pe_settings_ok
|
||||
lods byte [esi]
|
||||
lods byte [esi]
|
||||
test al,80h+40h
|
||||
jz subsystem_setting
|
||||
test al,80h
|
||||
jz machine_setting
|
||||
cmp al,80h
|
||||
je pe_dll
|
||||
jmp pe_settings
|
||||
pe_dll:
|
||||
jne pe_settings
|
||||
bts [format_flags],8
|
||||
jc symbol_already_defined
|
||||
jmp pe_settings
|
||||
machine_setting:
|
||||
bts [format_flags],6
|
||||
jc symbol_already_defined
|
||||
and ax,3Fh
|
||||
add ax,149h
|
||||
mov [machine],ax
|
||||
jmp pe_settings
|
||||
subsystem_setting:
|
||||
bts [format_flags],7
|
||||
jc symbol_already_defined
|
||||
|
|
@ -582,6 +576,23 @@ format_pe:
|
|||
add esi,12
|
||||
mov [subsystem_version],eax
|
||||
jmp pe_settings
|
||||
get_pe_base:
|
||||
bts [format_flags],9
|
||||
jc symbol_already_defined
|
||||
lods word [esi]
|
||||
cmp ah,'('
|
||||
jne invalid_argument
|
||||
cmp byte [esi],'.'
|
||||
je invalid_value
|
||||
push edx edi
|
||||
add edi,[stub_size]
|
||||
call get_dword_value
|
||||
pop edi edx
|
||||
cmp [value_type],0
|
||||
jne invalid_use_of_symbol
|
||||
mov [image_base],eax
|
||||
cmp byte [esi],84h
|
||||
jne pe_settings_ok
|
||||
get_stub_name:
|
||||
lods byte [esi]
|
||||
lods word [esi]
|
||||
|
|
@ -624,10 +635,11 @@ format_pe:
|
|||
mov word [edx+4],ax
|
||||
mov dword [edx+14h],0E0h ; size of optional header
|
||||
mov dword [edx+16h],10B818Eh; flags and magic value
|
||||
mov dword [edx+34h],400000h ; base of image
|
||||
mov dword [edx+38h],1000h ; section alignment
|
||||
mov dword [edx+3Ch],200h ; file alignment
|
||||
mov word [edx+40h],1 ; OS version
|
||||
mov eax,[image_base]
|
||||
mov dword [edx+34h],eax
|
||||
mov ax,[subsystem]
|
||||
mov [edx+5Ch],ax
|
||||
mov eax,[subsystem_version]
|
||||
|
|
@ -660,7 +672,9 @@ format_pe:
|
|||
neg eax
|
||||
add eax,edi
|
||||
sub eax,[edx+34h]
|
||||
mov [org_start],eax
|
||||
mov [org_origin],eax
|
||||
mov [org_sib],0
|
||||
mov [org_start],edi
|
||||
bt [format_flags],8
|
||||
jnc instruction_assembled
|
||||
or dword [edx+16h],2000h
|
||||
|
|
@ -730,7 +744,9 @@ pe_section:
|
|||
mov eax,edi
|
||||
sub eax,[ebx+0Ch]
|
||||
sub eax,[edx+34h]
|
||||
mov [org_start],eax
|
||||
mov [org_origin],eax
|
||||
mov [org_sib],0
|
||||
mov [org_start],edi
|
||||
or [reloc_labels],-1
|
||||
get_section_flags:
|
||||
lods byte [esi]
|
||||
|
|
@ -739,14 +755,6 @@ pe_section:
|
|||
cmp al,19h
|
||||
je section_flag
|
||||
dec esi
|
||||
cmp al,13h
|
||||
jne instruction_assembled
|
||||
lods byte [esi]
|
||||
lods byte [esi]
|
||||
mov [code_type],al
|
||||
cmp al,16
|
||||
jne instruction_assembled
|
||||
or byte [ebx+24h],4
|
||||
jmp instruction_assembled
|
||||
set_directory:
|
||||
movzx eax,byte [esi]
|
||||
|
|
@ -860,11 +868,8 @@ data_directive:
|
|||
jmp remove_structure_data
|
||||
pe_entry:
|
||||
lods byte [esi]
|
||||
call get_size_operator
|
||||
cmp al,'('
|
||||
jne invalid_argument
|
||||
test ah,not 4
|
||||
jnz invalid_address
|
||||
cmp byte [esi],'.'
|
||||
je invalid_value
|
||||
call get_dword_value
|
||||
|
|
@ -882,11 +887,8 @@ pe_entry:
|
|||
jmp instruction_assembled
|
||||
pe_stack:
|
||||
lods byte [esi]
|
||||
call get_size_operator
|
||||
cmp al,'('
|
||||
jne invalid_argument
|
||||
test ah,not 4
|
||||
jnz invalid_address
|
||||
cmp byte [esi],'.'
|
||||
je invalid_value
|
||||
call get_dword_value
|
||||
|
|
@ -898,11 +900,8 @@ pe_stack:
|
|||
jne default_stack_commit
|
||||
lods byte [esi]
|
||||
lods byte [esi]
|
||||
call get_size_operator
|
||||
cmp al,'('
|
||||
jne invalid_argument
|
||||
test ah,not 4
|
||||
jnz invalid_address
|
||||
cmp byte [esi],'.'
|
||||
je invalid_value
|
||||
call get_dword_value
|
||||
|
|
@ -922,11 +921,8 @@ pe_stack:
|
|||
jmp instruction_assembled
|
||||
pe_heap:
|
||||
lods byte [esi]
|
||||
call get_size_operator
|
||||
cmp al,'('
|
||||
jne invalid_argument
|
||||
test ah,not 4
|
||||
jnz invalid_address
|
||||
cmp byte [esi],'.'
|
||||
je invalid_value
|
||||
call get_dword_value
|
||||
|
|
@ -938,11 +934,8 @@ pe_heap:
|
|||
jne default_heap_commit
|
||||
lods byte [esi]
|
||||
lods byte [esi]
|
||||
call get_size_operator
|
||||
cmp al,'('
|
||||
jne invalid_argument
|
||||
test ah,not 4
|
||||
jnz invalid_address
|
||||
cmp byte [esi],'.'
|
||||
je invalid_value
|
||||
call get_dword_value
|
||||
|
|
@ -1018,6 +1011,9 @@ close_pe:
|
|||
call close_pe_section
|
||||
mov edx,[header_data]
|
||||
mov [edx+50h],eax
|
||||
call make_timestamp
|
||||
mov edx,[header_data]
|
||||
mov [edx+8],eax
|
||||
mov eax,[number_of_relocations]
|
||||
cmp eax,0
|
||||
jle pe_flags_ok
|
||||
|
|
@ -1058,7 +1054,12 @@ format_coff:
|
|||
mov [ebx],eax
|
||||
mov [ebx+4],eax
|
||||
mov [ebx+8],edi
|
||||
mov dword [ebx+10h],0E0000060h
|
||||
mov eax,60h
|
||||
bt [format_flags],0
|
||||
jnc flat_section_flags_ok
|
||||
or eax,0E0000000h
|
||||
flat_section_flags_ok:
|
||||
mov dword [ebx+10h],eax
|
||||
mov [current_section],ebx
|
||||
mov [number_of_sections],1
|
||||
mov [code_type],32
|
||||
|
|
@ -1076,6 +1077,8 @@ coff_section:
|
|||
xor eax,eax
|
||||
mov [ebx],al
|
||||
mov [ebx+8],edi
|
||||
mov [org_origin],edi
|
||||
mov [org_sib],0
|
||||
mov [org_start],edi
|
||||
or [reloc_labels],-1
|
||||
mov [ebx+10h],eax
|
||||
|
|
@ -1144,15 +1147,6 @@ public_directive:
|
|||
mov [ebx+8],eax
|
||||
mov eax,[current_line]
|
||||
mov [ebx+0Ch],eax
|
||||
cmp byte [esi],86h
|
||||
jne instruction_assembled
|
||||
inc esi
|
||||
lods word [esi]
|
||||
cmp al,'('
|
||||
jne invalid_argument
|
||||
mov [ebx+4],esi
|
||||
lods dword [esi]
|
||||
lea esi,[esi+eax+1]
|
||||
jmp instruction_assembled
|
||||
extrn_directive:
|
||||
cmp [output_format],4
|
||||
|
|
@ -1240,7 +1234,7 @@ mark_coff_relocation:
|
|||
mov [additional_memory],ebx
|
||||
mov byte [ebx-0Ch],al
|
||||
mov eax,edi
|
||||
sub eax,[org_start]
|
||||
sub eax,[org_origin]
|
||||
mov [ebx-0Ch+4],eax
|
||||
mov eax,[symbol_identifier]
|
||||
mov [ebx-0Ch+8],eax
|
||||
|
|
@ -1280,6 +1274,14 @@ coff_formatter:
|
|||
mov [additional_memory],edi
|
||||
mov word [ebx],14Ch
|
||||
mov word [ebx+12h],104h
|
||||
bt [format_flags],0
|
||||
jnc coff_flags_ok
|
||||
or byte [ebx+12h],80h
|
||||
coff_flags_ok:
|
||||
push ebx
|
||||
call make_timestamp
|
||||
pop ebx
|
||||
mov [ebx+4],eax
|
||||
mov eax,[number_of_sections]
|
||||
mov [ebx+2],ax
|
||||
mov esi,[sections_data]
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
; Copyright (c) 1999-2002, Tomasz Grysztar
|
||||
; All rights reserved.
|
||||
|
||||
program_base = 0x700000
|
||||
program_base = 0x8048000
|
||||
|
||||
org program_base
|
||||
use32
|
||||
|
|
@ -33,6 +33,8 @@ start:
|
|||
pop eax
|
||||
pop [input_file]
|
||||
pop [output_file]
|
||||
pop eax
|
||||
pop [environment]
|
||||
|
||||
call init_memory
|
||||
|
||||
|
|
@ -157,6 +159,7 @@ additional_memory dd ?
|
|||
additional_memory_end dd ?
|
||||
input_file dd ?
|
||||
output_file dd ?
|
||||
environment dd ?
|
||||
source_start dd ?
|
||||
code_start dd ?
|
||||
code_size dd ?
|
||||
|
|
@ -171,10 +174,13 @@ macro_block dd ?
|
|||
macro_block_line_number dd ?
|
||||
struc_name dd ?
|
||||
current_locals_prefix dd ?
|
||||
anonymous_reverse dd ?
|
||||
anonymous_forward dd ?
|
||||
labels_list dd ?
|
||||
label_hash dd ?
|
||||
org_start dd ?
|
||||
org_origin dd ?
|
||||
org_sib dd ?
|
||||
org_start dd ?
|
||||
undefined_data_start dd ?
|
||||
undefined_data_end dd ?
|
||||
counter dd ?
|
||||
|
|
@ -188,6 +194,7 @@ current_offset dd ?
|
|||
value dq ?
|
||||
fp_value rd 8
|
||||
symbol_identifier dd ?
|
||||
address_symbol dd ?
|
||||
format_flags dd ?
|
||||
number_of_relocations dd ?
|
||||
number_of_sections dd ?
|
||||
|
|
@ -198,6 +205,7 @@ current_section dd ?
|
|||
machine dw ?
|
||||
subsystem dw ?
|
||||
subsystem_version dd ?
|
||||
image_base dd ?
|
||||
|
||||
macro_status db ?
|
||||
parenthesis_stack db ?
|
||||
|
|
@ -228,6 +236,6 @@ nextbyte db ?
|
|||
|
||||
characters rb 100h
|
||||
converted rb 100h
|
||||
buffer rb 100h
|
||||
buffer rb 4000h
|
||||
|
||||
program_end:
|
||||
|
|
|
|||
|
|
@ -60,29 +60,105 @@ exit_program:
|
|||
int 0x80
|
||||
|
||||
open:
|
||||
push edx esi edi ebp
|
||||
mov ebx,edx
|
||||
push esi edi ebp
|
||||
call convert_path
|
||||
mov eax,5
|
||||
mov ebx,buffer
|
||||
mov ecx,O_RDONLY
|
||||
xor edx,edx
|
||||
int 0x80
|
||||
pop ebp edi esi edx
|
||||
pop ebp edi esi
|
||||
test eax,eax
|
||||
js file_error
|
||||
mov ebx,eax
|
||||
clc
|
||||
ret
|
||||
file_error:
|
||||
stc
|
||||
convert_path:
|
||||
mov esi,edx
|
||||
mov edi,buffer
|
||||
copy_path:
|
||||
lods byte [esi]
|
||||
cmp al,'%'
|
||||
je environment_variable
|
||||
cmp al,'\'
|
||||
jne path_char_ok
|
||||
mov al,'/'
|
||||
path_char_ok:
|
||||
stos byte [edi]
|
||||
or al,al
|
||||
jnz copy_path
|
||||
cmp edi,buffer+4000h
|
||||
ja out_of_memory
|
||||
ret
|
||||
convert_backslash:
|
||||
mov al,'/'
|
||||
stos byte [edi]
|
||||
jmp copy_path
|
||||
environment_variable:
|
||||
mov ebx,esi
|
||||
find_variable_end:
|
||||
lods byte [esi]
|
||||
or al,al
|
||||
jz not_environment_variable
|
||||
cmp al,'%'
|
||||
jne find_variable_end
|
||||
push esi
|
||||
mov esi,[environment]
|
||||
compare_variable_names:
|
||||
mov edx,ebx
|
||||
compare_character:
|
||||
lods byte [esi]
|
||||
mov ah,[edx]
|
||||
inc edx
|
||||
cmp al,'='
|
||||
je end_of_variable_name
|
||||
cmp ah,'%'
|
||||
je next_variable
|
||||
sub ah,al
|
||||
jz compare_character
|
||||
cmp ah,20h
|
||||
jne next_variable
|
||||
cmp al,41h
|
||||
jb next_variable
|
||||
cmp al,5Ah
|
||||
jna compare_character
|
||||
next_variable:
|
||||
lods byte [esi]
|
||||
or al,al
|
||||
jnz next_variable
|
||||
cmp byte [esi],0
|
||||
jne compare_variable_names
|
||||
pop esi
|
||||
jmp copy_path
|
||||
end_of_variable_name:
|
||||
cmp ah,'%'
|
||||
jne next_variable
|
||||
copy_variable_value:
|
||||
lods byte [esi]
|
||||
cmp al,'\'
|
||||
jne value_char_ok
|
||||
mov al,'/'
|
||||
value_char_ok:
|
||||
stos byte [edi]
|
||||
or al,al
|
||||
jnz copy_variable_value
|
||||
dec di
|
||||
pop esi
|
||||
jmp copy_path
|
||||
not_environment_variable:
|
||||
mov al,'%'
|
||||
stos byte [edi]
|
||||
mov esi,ebx
|
||||
jmp copy_path
|
||||
create:
|
||||
push edx esi edi ebp
|
||||
mov ebx,edx
|
||||
push esi edi ebp
|
||||
call convert_path
|
||||
mov eax,5
|
||||
mov ebx,buffer
|
||||
mov ecx,O_CREAT+O_TRUNC+O_WRONLY
|
||||
mov edx,S_IRUSR+S_IWUSR+S_IRGRP
|
||||
int 0x80
|
||||
pop ebp edi esi edx
|
||||
pop ebp edi esi
|
||||
test eax,eax
|
||||
js file_error
|
||||
mov ebx,eax
|
||||
|
|
@ -104,6 +180,9 @@ read:
|
|||
jne file_error
|
||||
clc
|
||||
ret
|
||||
file_error:
|
||||
stc
|
||||
ret
|
||||
write:
|
||||
push edx esi edi ebp
|
||||
mov eax,4
|
||||
|
|
@ -120,6 +199,8 @@ lseek:
|
|||
mov dl,al
|
||||
mov eax,19
|
||||
int 0x80
|
||||
test eax,eax
|
||||
js file_error
|
||||
clc
|
||||
ret
|
||||
|
||||
|
|
@ -280,6 +361,12 @@ assembler_error:
|
|||
call display_string
|
||||
jmp exit_program
|
||||
|
||||
make_timestamp:
|
||||
mov eax,13
|
||||
xor ebx,ebx
|
||||
int 0x80
|
||||
ret
|
||||
|
||||
character db ?,0
|
||||
|
||||
error_prefix db 'error: ',0
|
||||
|
|
|
|||
|
|
@ -6,7 +6,10 @@
|
|||
parser:
|
||||
mov eax,[memory_end]
|
||||
mov [labels_list],eax
|
||||
mov [current_locals_prefix],0
|
||||
xor eax,eax
|
||||
mov [current_locals_prefix],eax
|
||||
mov [anonymous_reverse],eax
|
||||
mov [anonymous_forward],eax
|
||||
mov esi,[source_start]
|
||||
mov edi,[code_start]
|
||||
push [additional_memory]
|
||||
|
|
@ -24,6 +27,8 @@ parser:
|
|||
jb parser_loop
|
||||
xor al,al
|
||||
stos byte [edi]
|
||||
cmp [anonymous_forward],0
|
||||
jne unexpected_end_of_file
|
||||
pop [additional_memory]
|
||||
mov eax,[code_start]
|
||||
mov [source_start],eax
|
||||
|
|
@ -92,13 +97,13 @@ parse_line:
|
|||
data_label:
|
||||
pop ecx ebx
|
||||
pop edi
|
||||
push ax esi
|
||||
push eax esi
|
||||
mov esi,ebx
|
||||
call identify_label
|
||||
mov byte [edi],2
|
||||
inc edi
|
||||
stos dword [edi]
|
||||
pop esi ax
|
||||
pop esi eax
|
||||
stos byte [edi]
|
||||
push edi
|
||||
jmp data_instruction
|
||||
|
|
@ -119,10 +124,16 @@ parse_line:
|
|||
cmp eax,10h
|
||||
jb label_identified
|
||||
mov ebx,[eax+4]
|
||||
cmp ebx,eax
|
||||
je anonymous_label_name
|
||||
dec ebx
|
||||
mov [current_locals_prefix],ebx
|
||||
label_identified:
|
||||
ret
|
||||
anonymous_label_name:
|
||||
cmp byte [esi-1],'@'
|
||||
jne reserved_word_used_as_symbol
|
||||
ret
|
||||
local_label_name:
|
||||
call get_label_id
|
||||
ret
|
||||
|
|
@ -435,16 +446,11 @@ parse_line:
|
|||
or al,al
|
||||
jz line_parsed
|
||||
cmp al,':'
|
||||
je empty_label
|
||||
je invalid_name
|
||||
cmp al,3Bh
|
||||
je skip_preprocessed_symbol
|
||||
dec esi
|
||||
jmp parse_arguments
|
||||
empty_label:
|
||||
mov eax,_counter
|
||||
call increase_counter
|
||||
mov [current_locals_prefix],eax
|
||||
jmp instruction_start
|
||||
skip_preprocessed_symbol:
|
||||
lods byte [esi]
|
||||
movzx eax,al
|
||||
|
|
|
|||
|
|
@ -244,6 +244,12 @@ preprocess_line:
|
|||
push ecx esi
|
||||
mov esi,[current_line]
|
||||
add esi,12
|
||||
test [macro_status],0C0h
|
||||
jz concatenations_ok
|
||||
call process_concatenations
|
||||
mov esi,[current_line]
|
||||
add esi,12
|
||||
concatenations_ok:
|
||||
mov al,[macro_status]
|
||||
dec al
|
||||
jz find_macro_block
|
||||
|
|
@ -299,9 +305,6 @@ preprocess_line:
|
|||
mov esi,[current_line]
|
||||
add esi,12
|
||||
call process_symbolic_constants
|
||||
mov esi,[current_line]
|
||||
add esi,12
|
||||
call process_concatenations
|
||||
line_preprocessed:
|
||||
pop esi ecx
|
||||
pop [struc_name]
|
||||
|
|
@ -349,11 +352,11 @@ process_symbolic_constants:
|
|||
check_symbol:
|
||||
movzx ecx,byte [esi]
|
||||
inc esi
|
||||
call replace_symbolic_constant
|
||||
jnc process_after_replaced
|
||||
call find_symbolic_constant
|
||||
jnc replace_symbolic_constant
|
||||
add esi,ecx
|
||||
jmp process_symbolic_constants
|
||||
replace_symbolic_constant:
|
||||
find_symbolic_constant:
|
||||
push edi
|
||||
mov ebx,esi
|
||||
mov eax,ecx
|
||||
|
|
@ -377,6 +380,9 @@ process_symbolic_constants:
|
|||
ret
|
||||
symbolic_constant_found:
|
||||
pop edi
|
||||
clc
|
||||
ret
|
||||
replace_symbolic_constant:
|
||||
mov ecx,[edx+8]
|
||||
mov edx,[edx+12]
|
||||
xchg esi,edx
|
||||
|
|
@ -391,8 +397,6 @@ process_symbolic_constants:
|
|||
mov cl,al
|
||||
rep movs byte [edi],[esi]
|
||||
mov esi,edx
|
||||
clc
|
||||
ret
|
||||
process_after_replaced:
|
||||
lods byte [esi]
|
||||
cmp al,1Ah
|
||||
|
|
@ -425,8 +429,8 @@ process_symbolic_constants:
|
|||
symbol_after_replaced:
|
||||
movzx ecx,byte [esi]
|
||||
inc esi
|
||||
call replace_symbolic_constant
|
||||
jnc process_after_replaced
|
||||
call find_symbolic_constant
|
||||
jnc replace_symbolic_constant
|
||||
mov al,1Ah
|
||||
mov ah,cl
|
||||
stos word [edi]
|
||||
|
|
@ -540,6 +544,39 @@ define_symbolic_constant:
|
|||
mov [edx],al
|
||||
mov [edx+4],ebx
|
||||
jmp line_preprocessed
|
||||
restore_symbolic_constant:
|
||||
lods byte [esi]
|
||||
cmp al,1Ah
|
||||
jne invalid_name
|
||||
movzx ecx,byte [esi]
|
||||
inc esi
|
||||
call find_symbolic_constant
|
||||
jc no_symbolic_constant
|
||||
mov ecx,edx
|
||||
sub ecx,[labels_list]
|
||||
add [labels_list],16
|
||||
shr ecx,2
|
||||
jz constant_restored
|
||||
mov ebx,esi
|
||||
mov esi,edx
|
||||
xchg edi,edx
|
||||
add edi,12
|
||||
sub esi,4
|
||||
std
|
||||
rep movs dword [edi],[esi]
|
||||
cld
|
||||
mov esi,ebx
|
||||
mov edi,edx
|
||||
jmp constant_restored
|
||||
no_symbolic_constant:
|
||||
add esi,ecx
|
||||
constant_restored:
|
||||
lods byte [esi]
|
||||
cmp al,','
|
||||
je restore_symbolic_constant
|
||||
or al,al
|
||||
jnz extra_characters_on_line
|
||||
jmp line_preprocessed
|
||||
define_struc:
|
||||
or ah,1
|
||||
define_macro:
|
||||
|
|
@ -650,6 +687,7 @@ purge_macro:
|
|||
use_macro:
|
||||
push [macro_constants] [macro_block] [macro_block_line_number]
|
||||
push [counter] [counter_limit]
|
||||
push dword [macro_status]
|
||||
or [macro_status],80h
|
||||
or byte [ebx+1],80h
|
||||
mov edx,esi
|
||||
|
|
@ -1000,7 +1038,8 @@ use_macro:
|
|||
pop [current_line]
|
||||
mov eax,[macro_constants]
|
||||
mov [additional_memory],eax
|
||||
mov [macro_status],0
|
||||
pop eax
|
||||
mov [macro_status],al
|
||||
pop [counter_limit] [counter]
|
||||
pop [macro_block_line_number] [macro_block] [macro_constants]
|
||||
jmp line_preprocessed
|
||||
|
|
|
|||
|
|
@ -148,6 +148,8 @@ get_instruction:
|
|||
get_label_id:
|
||||
cmp ecx,100h
|
||||
jae name_too_long
|
||||
cmp byte [esi],'@'
|
||||
je anonymous_label
|
||||
cmp byte [esi],'.'
|
||||
jne standard_label
|
||||
cmp byte [esi+1],'.'
|
||||
|
|
@ -182,6 +184,56 @@ get_label_id:
|
|||
call get_label_id
|
||||
pop esi
|
||||
ret
|
||||
anonymous_label:
|
||||
cmp ecx,2
|
||||
jne standard_label
|
||||
mov al,[esi+1]
|
||||
mov ebx,characters
|
||||
xlat byte [ebx]
|
||||
cmp al,'@'
|
||||
je new_anonymous
|
||||
cmp al,'b'
|
||||
je anonymous_back
|
||||
cmp al,'r'
|
||||
je anonymous_back
|
||||
cmp al,'f'
|
||||
jne standard_label
|
||||
add esi,2
|
||||
mov eax,[anonymous_forward]
|
||||
or eax,eax
|
||||
jnz anonymous_ok
|
||||
mov eax,[labels_list]
|
||||
sub eax,16
|
||||
mov [labels_list],eax
|
||||
cmp eax,edi
|
||||
jbe out_of_memory
|
||||
mov dword [eax],0
|
||||
mov [eax+4],eax
|
||||
mov [anonymous_forward],eax
|
||||
anonymous_ok:
|
||||
ret
|
||||
anonymous_back:
|
||||
add esi,2
|
||||
mov eax,[anonymous_reverse]
|
||||
or eax,eax
|
||||
jz invalid_value
|
||||
ret
|
||||
new_anonymous:
|
||||
add esi,2
|
||||
mov eax,[anonymous_forward]
|
||||
or eax,eax
|
||||
jnz new_anonymous_ok
|
||||
mov eax,[labels_list]
|
||||
sub eax,16
|
||||
mov [labels_list],eax
|
||||
cmp eax,edi
|
||||
jbe out_of_memory
|
||||
mov dword [eax],0
|
||||
mov [eax+4],eax
|
||||
new_anonymous_ok:
|
||||
mov [anonymous_reverse],eax
|
||||
mov [anonymous_forward],0
|
||||
ret
|
||||
standard_label:
|
||||
cmp ecx,1
|
||||
jne find_label
|
||||
|
|
@ -296,7 +348,6 @@ single_operand_operators:
|
|||
db 0
|
||||
|
||||
directive_operators:
|
||||
db 2,'as',86h
|
||||
db 2,'at',80h
|
||||
db 2,'eq',81h
|
||||
db 4,'from',82h
|
||||
|
|
@ -419,9 +470,6 @@ formatter_symbols:
|
|||
db 6,'export',1Ah,0
|
||||
db 6,'fixups',1Ah,5
|
||||
db 3,'gui',1Bh,2
|
||||
db 4,'i386',1Bh,43h
|
||||
db 4,'i486',1Bh,44h
|
||||
db 4,'i586',1Bh,45h
|
||||
db 6,'import',1Ah,1
|
||||
db 2,'ms',18h,41h
|
||||
db 2,'mz',18h,2
|
||||
|
|
@ -440,6 +488,8 @@ preprocessor_directives:
|
|||
dw define_macro-preprocessor
|
||||
db 5,'purge'
|
||||
dw purge_macro-preprocessor
|
||||
db 7,'restore'
|
||||
dw restore_symbolic_constant-preprocessor
|
||||
db 5,'struc'
|
||||
dw define_struc-preprocessor
|
||||
db 0
|
||||
|
|
@ -1679,10 +1729,6 @@ instructions_10:
|
|||
dw cmp_ps_instruction-assembler
|
||||
db 'cmpunordss',3
|
||||
dw cmp_ss_instruction-assembler
|
||||
db 'loadall286',5
|
||||
dw simple_extended_instruction-assembler
|
||||
db 'loadall386',7
|
||||
dw simple_extended_instruction-assembler
|
||||
db 'maskmovdqu',0
|
||||
dw maskmovdqu_instruction-assembler
|
||||
db 'prefetcht0',1
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
; flat assembler version 1.39
|
||||
; flat assembler version 1.40
|
||||
; Copyright (c) 1999-2002, Tomasz Grysztar
|
||||
; All rights reserved.
|
||||
;
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
; cannot simply be copied and put under another distribution licence
|
||||
; (including the GNU Public Licence).
|
||||
|
||||
VERSION_STRING equ "1.39"
|
||||
VERSION_STRING equ "1.40"
|
||||
|
||||
VERSION_MAJOR = 1
|
||||
VERSION_MINOR = 39
|
||||
VERSION_MINOR = 40
|
||||
|
|
|
|||
|
|
@ -23,6 +23,10 @@ start:
|
|||
je information
|
||||
inc eax
|
||||
mov [output_file],eax
|
||||
movzx ecx,byte [eax-1]
|
||||
add eax,ecx
|
||||
cmp byte [eax],0
|
||||
jne information
|
||||
|
||||
call init_memory
|
||||
|
||||
|
|
@ -204,11 +208,14 @@ macro_constants dd ?
|
|||
macro_block dd ?
|
||||
macro_block_line_number dd ?
|
||||
struc_name dd ?
|
||||
anonymous_reverse dd ?
|
||||
anonymous_forward dd ?
|
||||
current_locals_prefix dd ?
|
||||
labels_list dd ?
|
||||
label_hash dd ?
|
||||
org_start dd ?
|
||||
org_origin dd ?
|
||||
org_sib dd ?
|
||||
org_start dd ?
|
||||
undefined_data_start dd ?
|
||||
undefined_data_end dd ?
|
||||
counter dd ?
|
||||
|
|
@ -222,6 +229,7 @@ current_offset dd ?
|
|||
value dq ?
|
||||
fp_value rd 8
|
||||
symbol_identifier dd ?
|
||||
address_symbol dd ?
|
||||
format_flags dd ?
|
||||
number_of_relocations dd ?
|
||||
number_of_sections dd ?
|
||||
|
|
@ -232,6 +240,7 @@ current_section dd ?
|
|||
machine dw ?
|
||||
subsystem dw ?
|
||||
subsystem_version dd ?
|
||||
image_base dd ?
|
||||
|
||||
macro_status db ?
|
||||
parenthesis_stack db ?
|
||||
|
|
@ -262,8 +271,8 @@ nextbyte db ?
|
|||
|
||||
characters rb 100h
|
||||
converted rb 100h
|
||||
params rb 100h
|
||||
buffer rb 100h
|
||||
params rb 1000h
|
||||
buffer rb 4000h
|
||||
|
||||
stack 4000h
|
||||
|
||||
|
|
@ -280,9 +289,11 @@ section '.idata' import data readable writeable
|
|||
CloseHandle dd rva _CloseHandle
|
||||
SetFilePointer dd rva _SetFilePointer
|
||||
GetCommandLine dd rva _GetCommandLineA
|
||||
GetEnvironmentVariable dd rva _GetEnvironmentVariable
|
||||
GetStdHandle dd rva _GetStdHandle
|
||||
VirtualAlloc dd rva _VirtualAlloc
|
||||
GetTickCount dd rva _GetTickCount
|
||||
GetSystemTime dd rva _GetSystemTime
|
||||
GlobalMemoryStatus dd rva _GlobalMemoryStatus
|
||||
dd 0
|
||||
|
||||
|
|
@ -302,12 +313,16 @@ section '.idata' import data readable writeable
|
|||
db 'SetFilePointer',0
|
||||
_GetCommandLineA dw 0
|
||||
db 'GetCommandLineA',0
|
||||
_GetEnvironmentVariable dw 0
|
||||
db 'GetEnvironmentVariableA',0
|
||||
_GetStdHandle dw 0
|
||||
db 'GetStdHandle',0
|
||||
_VirtualAlloc dw 0
|
||||
db 'VirtualAlloc',0
|
||||
_GetTickCount dw 0
|
||||
db 'GetTickCount',0
|
||||
_GetSystemTime dw 0
|
||||
db 'GetSystemTime',0
|
||||
_GlobalMemoryStatus dw 0
|
||||
db 'GlobalMemoryStatus',0
|
||||
|
||||
|
|
|
|||
|
|
@ -74,13 +74,14 @@ exit_program:
|
|||
call [ExitProcess]
|
||||
|
||||
open:
|
||||
call convert_path
|
||||
push 0
|
||||
push 0
|
||||
push OPEN_EXISTING
|
||||
push 0
|
||||
push 0
|
||||
push GENERIC_READ
|
||||
push edx
|
||||
push buffer
|
||||
call [CreateFile]
|
||||
cmp eax,-1
|
||||
je file_error
|
||||
|
|
@ -90,14 +91,53 @@ open:
|
|||
file_error:
|
||||
stc
|
||||
ret
|
||||
convert_path:
|
||||
push esi edi
|
||||
mov esi,edx
|
||||
mov edi,buffer
|
||||
copy_path:
|
||||
lods byte [esi]
|
||||
cmp al,'%'
|
||||
je environment_variable
|
||||
stos byte [edi]
|
||||
or al,al
|
||||
jnz copy_path
|
||||
cmp edi,buffer+4000h
|
||||
ja out_of_memory
|
||||
pop edi esi
|
||||
ret
|
||||
environment_variable:
|
||||
mov ebx,esi
|
||||
find_variable_end:
|
||||
lods byte [esi]
|
||||
or al,al
|
||||
jz not_environment_variable
|
||||
cmp al,'%'
|
||||
jne find_variable_end
|
||||
mov byte [esi-1],0
|
||||
mov eax,buffer+4000h
|
||||
sub eax,edi
|
||||
push eax
|
||||
push edi
|
||||
push ebx
|
||||
call [GetEnvironmentVariable]
|
||||
add edi,eax
|
||||
mov byte [esi-1],'%'
|
||||
jmp copy_path
|
||||
not_environment_variable:
|
||||
mov al,'%'
|
||||
stos byte [edi]
|
||||
mov esi,ebx
|
||||
jmp copy_path
|
||||
create:
|
||||
call convert_path
|
||||
push 0
|
||||
push 0
|
||||
push CREATE_ALWAYS
|
||||
push 0
|
||||
push 0
|
||||
push GENERIC_WRITE
|
||||
push edx
|
||||
push buffer
|
||||
call [CreateFile]
|
||||
cmp eax,-1
|
||||
je file_error
|
||||
|
|
@ -140,6 +180,8 @@ lseek:
|
|||
push edx
|
||||
push ebx
|
||||
call [SetFilePointer]
|
||||
cmp eax,-1
|
||||
je file_error
|
||||
ret
|
||||
|
||||
display_string:
|
||||
|
|
@ -175,10 +217,10 @@ display_block:
|
|||
ret
|
||||
display_character:
|
||||
push ebx
|
||||
mov [character],dl
|
||||
push STD_OUTPUT_HANDLE
|
||||
call [GetStdHandle]
|
||||
mov ebx,eax
|
||||
mov [character],dl
|
||||
push 0
|
||||
push bytes_count
|
||||
push 1
|
||||
|
|
@ -205,9 +247,9 @@ display_number:
|
|||
display_digit:
|
||||
mov dl,al
|
||||
add dl,30h
|
||||
push ebx ecx
|
||||
push ecx
|
||||
call display_character
|
||||
pop ecx ebx
|
||||
pop ecx
|
||||
digit_ok:
|
||||
mov eax,ecx
|
||||
xor edx,edx
|
||||
|
|
@ -310,6 +352,84 @@ assembler_error:
|
|||
call display_string
|
||||
jmp exit_program
|
||||
|
||||
make_timestamp:
|
||||
push buffer
|
||||
call [GetSystemTime]
|
||||
movzx ecx,word [buffer]
|
||||
mov eax,ecx
|
||||
sub eax,1970
|
||||
mov ebx,365
|
||||
mul ebx
|
||||
mov ebp,eax
|
||||
mov eax,ecx
|
||||
sub eax,1969
|
||||
shr eax,2
|
||||
add ebp,eax
|
||||
mov eax,ecx
|
||||
sub eax,1901
|
||||
mov ebx,100
|
||||
div ebx
|
||||
sub ebp,eax
|
||||
mov eax,ecx
|
||||
xor edx,edx
|
||||
sub eax,1601
|
||||
mov ebx,400
|
||||
div ebx
|
||||
add ebp,eax
|
||||
movzx ecx,word [buffer+2]
|
||||
mov eax,ecx
|
||||
dec eax
|
||||
mov ebx,30
|
||||
mul ebx
|
||||
add ebp,eax
|
||||
cmp ecx,8
|
||||
jbe months_correction
|
||||
mov eax,ecx
|
||||
sub eax,7
|
||||
shr eax,1
|
||||
add ebp,eax
|
||||
mov ecx,8
|
||||
months_correction:
|
||||
mov eax,ecx
|
||||
shr eax,1
|
||||
add ebp,eax
|
||||
sub ebp,2
|
||||
cmp ecx,2
|
||||
jbe day_correction_ok
|
||||
movzx ecx,word [buffer]
|
||||
test ecx,11b
|
||||
jnz day_correction_ok
|
||||
xor edx,edx
|
||||
mov eax,ecx
|
||||
mov ebx,100
|
||||
div ebx
|
||||
or edx,edx
|
||||
jnz day_correction
|
||||
mov eax,ecx
|
||||
mov ebx,400
|
||||
div ebx
|
||||
or edx,edx
|
||||
jnz day_correction_ok
|
||||
day_correction:
|
||||
inc ebp
|
||||
day_correction_ok:
|
||||
movzx eax,word [buffer+6]
|
||||
dec eax
|
||||
add eax,ebp
|
||||
mov ebx,24
|
||||
mul ebx
|
||||
movzx ecx,word [buffer+8]
|
||||
add eax,ecx
|
||||
mov ebx,60
|
||||
mul ebx
|
||||
movzx ecx,word [buffer+10]
|
||||
add eax,ecx
|
||||
mov ebx,60
|
||||
mul ebx
|
||||
movzx ecx,word [buffer+12]
|
||||
add eax,ecx
|
||||
ret
|
||||
|
||||
character db ?,0
|
||||
bytes_count dd ?
|
||||
|
||||
|
|
|
|||
17
WHATSNEW.TXT
17
WHATSNEW.TXT
|
|
@ -1,6 +1,19 @@
|
|||
|
||||
Visit http://fasm.metro-nt.pl/ for more examples and documentation
|
||||
Questions or comments please send to fasm@metro-nt.pl
|
||||
Visit http://fasm.metro-nt.pl for more examples and tools
|
||||
|
||||
version 1.40
|
||||
[04-08-2002]
|
||||
------------
|
||||
[+] added restore directive
|
||||
[+] concatenations processed before symbolic constants now
|
||||
[+] timestamps generated for COFF and PE
|
||||
[+] custom base of PE image allowed
|
||||
[+] added support for anonymous labels
|
||||
[+] load directive extended for code loading
|
||||
[+] environment variables in paths allowed
|
||||
[-] concatenations allowed in macroinstructions only
|
||||
[-] more fixes
|
||||
|
||||
version 1.39
|
||||
[08-07-2002]
|
||||
|
|
@ -190,7 +203,7 @@ version 1.01
|
|||
version 1.00
|
||||
[19-06-2000]
|
||||
------------
|
||||
[+] first serious release
|
||||
[+] first official release
|
||||
|
||||
version 0.90
|
||||
[04-05-1999]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue