diff --git a/FASM.TXT b/FASM.TXT
deleted file mode 100644
index b1451fa..0000000
--- a/FASM.TXT
+++ /dev/null
@@ -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
' 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 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 & arg2 in
- push arg2
- pop arg1
- else
- mov arg1,arg2 ; here original mov instruction will be used
- end if
- }
- macro mov arg1,arg2,arg3
- {
- if 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 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 ' 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 ' 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 ' 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 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 ' 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)!
diff --git a/LICENSE.TXT b/LICENSE.TXT
index 794e4de..d6edd50 100644
--- a/LICENSE.TXT
+++ b/LICENSE.TXT
@@ -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).
-
diff --git a/SOURCE/ASSEMBLE.INC b/SOURCE/ASSEMBLE.INC
index efc3abc..d4ac21d 100644
--- a/SOURCE/ASSEMBLE.INC
+++ b/SOURCE/ASSEMBLE.INC
@@ -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]
diff --git a/SOURCE/DOS/FASM.ASM b/SOURCE/DOS/FASM.ASM
index 3821dbb..6fcc1d5 100644
--- a/SOURCE/DOS/FASM.ASM
+++ b/SOURCE/DOS/FASM.ASM
@@ -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 ?
diff --git a/SOURCE/DOS/SYSTEM.INC b/SOURCE/DOS/SYSTEM.INC
index 57cfd98..bd127b0 100644
--- a/SOURCE/DOS/SYSTEM.INC
+++ b/SOURCE/DOS/SYSTEM.INC
@@ -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 ?
diff --git a/SOURCE/EXPRESSI.INC b/SOURCE/EXPRESSI.INC
index 00a85dd..82881cb 100644
--- a/SOURCE/EXPRESSI.INC
+++ b/SOURCE/EXPRESSI.INC
@@ -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
diff --git a/SOURCE/FORMATS.INC b/SOURCE/FORMATS.INC
index 95645bf..0a54d25 100644
--- a/SOURCE/FORMATS.INC
+++ b/SOURCE/FORMATS.INC
@@ -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]
diff --git a/SOURCE/LINUX/FASM.ASM b/SOURCE/LINUX/FASM.ASM
index 8dc7b1f..1edae71 100644
--- a/SOURCE/LINUX/FASM.ASM
+++ b/SOURCE/LINUX/FASM.ASM
@@ -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:
diff --git a/SOURCE/LINUX/SYSTEM.INC b/SOURCE/LINUX/SYSTEM.INC
index e1518b7..2d4c944 100644
--- a/SOURCE/LINUX/SYSTEM.INC
+++ b/SOURCE/LINUX/SYSTEM.INC
@@ -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
diff --git a/SOURCE/PARSER.INC b/SOURCE/PARSER.INC
index 3fb9de4..1b9dab8 100644
--- a/SOURCE/PARSER.INC
+++ b/SOURCE/PARSER.INC
@@ -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
diff --git a/SOURCE/PREPROCE.INC b/SOURCE/PREPROCE.INC
index ae8b66f..afc9b18 100644
--- a/SOURCE/PREPROCE.INC
+++ b/SOURCE/PREPROCE.INC
@@ -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
diff --git a/SOURCE/TABLES.INC b/SOURCE/TABLES.INC
index 013e576..975d101 100644
--- a/SOURCE/TABLES.INC
+++ b/SOURCE/TABLES.INC
@@ -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
diff --git a/SOURCE/VERSION.INC b/SOURCE/VERSION.INC
index 54ab134..5594e03 100644
--- a/SOURCE/VERSION.INC
+++ b/SOURCE/VERSION.INC
@@ -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
diff --git a/SOURCE/WIN32/FASM.ASM b/SOURCE/WIN32/FASM.ASM
index 11eb2c4..d05e49d 100644
--- a/SOURCE/WIN32/FASM.ASM
+++ b/SOURCE/WIN32/FASM.ASM
@@ -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
diff --git a/SOURCE/WIN32/SYSTEM.INC b/SOURCE/WIN32/SYSTEM.INC
index 7a2cfc7..9c46b55 100644
--- a/SOURCE/WIN32/SYSTEM.INC
+++ b/SOURCE/WIN32/SYSTEM.INC
@@ -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 ?
diff --git a/WHATSNEW.TXT b/WHATSNEW.TXT
index 519404a..0a746a2 100644
--- a/WHATSNEW.TXT
+++ b/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]