release 1.54

This commit is contained in:
Tomasz Grysztar 2004-08-04 12:00:00 +00:00
parent da658ba0e1
commit 01d0d168a4
15 changed files with 684 additions and 351 deletions

View file

@ -5,7 +5,7 @@
Û ÜßßßßÛ ßßßßÜ Û Û Û
Û ßÜÜÜÜÛÜ ÜÜÜÜÜß Û Û Û
flat assembler 1.53
flat assembler 1.54
Programmer's Manual
@ -97,18 +97,26 @@ requires a Win32 console compatible with 3.1 version.
To execute flat assembler from the command line you need to provide two
parameters - first should be name of source file, second should be name of
destination file. After displaying short information about the program name
and version, compiler will read the data from source file and compile it.
When the compilation is successful, compiler will write the generated code
to the destination file and display the summary of compilation process;
otherwise it will display the information about error that occurred.
destination file. If no second parameter is given, the name for output
file will be guessed automatically. After displaying short information about
the program name and version, compiler will read the data from source file and
compile it. When the compilation is successful, compiler will write the
generated code to the destination file and display the summary of compilation
process; otherwise it will display the information about error that occurred.
The source file should be a text file, and can be created in any text
editor. Line breaks are accepted in both DOS and Unix standards, tabulators
are treated as spaces.
In the command line you can also include "-m" option followed by a number,
which specifies how many kilobytes of memory flat assembler should maximally
use. In case of DOS version this options limits only the usage of extended
memory.
memory. The "-p" option followed by a number can be used to specify the limit
for number of passes the assembler performs. If code cannot be generated
within specified amount of passes, the assembly will be terminated with an
error message. The maximum value of this setting is 65536, while the default
limit, used when no such option is included in command line, is 100.
It is also possible to limit the number of passes the assembler
performs, with the "-p" option followed by a number specifying the maximum
number of passes.
There are no command line options that would affect the output of compiler,
flat assembler requires only the source code to include the information it
really needs. For example, to specify output format you specify it by using
@ -123,21 +131,21 @@ done, how much time it took, and how many bytes were written into the
destination file.
The following is an example of the compilation summary:
flat assembler version 1.53
flat assembler version 1.54
38 passes, 5.3 seconds, 77824 bytes.
In case of error during the compilation process, the program will display an
error message. For example, when compiler can't find the input file, it will
display the following message:
flat assembler version 1.53
flat assembler version 1.54
error: source file not found.
If the error is connected with a specific part of source code, the source line
that caused the error will be also displayed. Also placement of this line in
the source is given to help you finding this error, for example:
flat assembler version 1.53
flat assembler version 1.54
example.asm [3]:
mob ax,1
error: illegal instruction.
@ -147,7 +155,7 @@ encountered an unrecognized instruction. When the line that caused error
contains a macroinstruction, also the line in macroinstruction definition
that generated the erroneous instruction is displayed:
flat assembler version 1.53
flat assembler version 1.54
example.asm [6]:
stoschar 7
example.asm [3] stoschar [1]:
@ -2118,7 +2126,8 @@ The "used" operator should be followed by a symbol name, it checks whether the
given symbol is used somewhere (it returns correct result even if symbol is
used only after this check). The "defined" operator can be followed by any
expression, usually just by a single symbol name; it checks whether the given
expression contains only symbols that are defined in the source.
expression contains only symbols that are defined in the source and accessible
from the current position.
The following simple example uses the "count" constant that should be
defined somewhere in source:

View file

@ -1,5 +1,5 @@
flat assembler version 1.53
flat assembler version 1.54
Copyright (c) 1999-2004, Tomasz Grysztar.
All rights reserved.

View file

@ -29,6 +29,8 @@ assembler:
mov esi,[source_start]
mov edi,[code_start]
xor eax,eax
mov dword [adjustment],eax
mov dword [adjustment+4],eax
mov [org_origin],edi
mov [org_start],edi
mov [org_registers],eax
@ -88,8 +90,10 @@ assembler:
use_prediction_ok:
test byte [eax+8],40h
jz check_next_symbol
mov cx,[current_pass]
and byte [eax+8],not 40h
test byte [eax+8],4
jnz define_misprediction
mov cx,[current_pass]
test byte [eax+8],80h
jnz check_define_prediction
cmp cx,[eax+16]
@ -117,7 +121,8 @@ assembler:
jmp near [error]
next_pass:
inc [current_pass]
cmp [current_pass],0
mov ax,[current_pass]
cmp ax,[passes_limit]
je code_cannot_be_generated
jmp assembler_loop
assemble_ok:
@ -170,6 +175,20 @@ assemble_line:
je make_label
mov ch,2
make_label:
cmp [virtual_data],0
jne make_virtual_label
or byte [ebx+9],1
xchg eax,[ebx]
xchg edx,[ebx+4]
sub eax,[ebx]
sbb edx,[ebx+4]
mov dword [adjustment],eax
mov dword [adjustment+4],edx
or eax,edx
setnz ah
jmp finish_label_symbol
make_virtual_label:
and byte [ebx+9],not 1
cmp eax,[ebx]
mov [ebx],eax
setne ah
@ -177,6 +196,7 @@ assemble_line:
mov [ebx+4],edx
setne al
or ah,al
finish_label_symbol:
cmp cl,[ebx+10]
mov [ebx+10],cl
setne al
@ -257,6 +277,7 @@ assemble_line:
cmp ch,3
je invalid_use_of_symbol
make_constant:
and byte [ebx+9],not 1
cmp eax,[ebx]
mov [ebx],eax
setne ah
@ -435,8 +456,15 @@ org_directive:
mov [org_origin],ecx
mov [org_registers],0
mov [org_start],edi
mov eax,[symbol_identifier]
mov [org_symbol],eax
mov edx,[symbol_identifier]
mov [org_symbol],edx
cmp [output_format],1
ja instruction_assembled
cmp edi,[code_start]
jne instruction_assembled
cmp eax,100h
jne instruction_assembled
bts [format_flags],0
jmp instruction_assembled
label_directive:
lods byte [esi]
@ -466,7 +494,27 @@ label_directive:
cdq
mov ebp,[org_registers]
cmp byte [esi],80h
jne define_free_label
je get_free_label_value
xor ch,ch
cmp [reloc_labels],0
je make_adjustable_label
mov ch,2
push [org_symbol]
pop [symbol_identifier]
make_adjustable_label:
cmp [virtual_data],0
jne make_free_label
or byte [ebx+9],1
xchg eax,[ebx]
xchg edx,[ebx+4]
sub eax,[ebx]
sbb edx,[ebx+4]
mov dword [adjustment],eax
mov dword [adjustment+4],edx
or eax,edx
setne ah
jmp finish_label
get_free_label_value:
inc esi
lods byte [esi]
cmp al,'('
@ -492,15 +540,8 @@ label_directive:
jz make_free_label
cmp ch,2
jne invalid_use_of_symbol
jmp make_free_label
define_free_label:
xor ch,ch
cmp [reloc_labels],0
je make_free_label
mov ch,2
push [org_symbol]
pop [symbol_identifier]
make_free_label:
and byte [ebx+9],not 1
cmp eax,[ebx]
mov [ebx],eax
setne ah
@ -508,6 +549,8 @@ label_directive:
mov [ebx+4],edx
setne al
or ah,al
jmp finish_label
finish_label:
cmp cl,[ebx+10]
mov [ebx+10],cl
setne al
@ -680,13 +723,8 @@ display_directive:
cmp edi,[display_buffer]
ja out_of_memory
lods byte [esi]
or al,al
jz do_display
cmp al,0Fh
je do_display
cmp al,','
jne extra_characters_on_line
jmp prepare_display
je prepare_display
do_display:
dec esi
mov ebp,edi
@ -1127,8 +1165,7 @@ data_bytes:
cmp al,0Fh
je data_end
cmp al,','
jne extra_characters_on_line
jmp data_bytes
je data_bytes
data_end:
dec esi
jmp instruction_assembled
@ -1187,8 +1224,8 @@ data_words:
cmp al,0Fh
je data_end
cmp al,','
jne extra_characters_on_line
jmp get_words_data
je get_words_data
jmp data_end
word_string:
inc esi
lods dword [esi]
@ -1256,8 +1293,8 @@ data_dwords:
cmp al,0Fh
je data_end
cmp al,','
jne extra_characters_on_line
jmp data_dwords
je data_dwords
jmp data_end
data_pwords:
lods byte [esi]
cmp al,'('
@ -1313,8 +1350,8 @@ data_pwords:
cmp al,0Fh
je data_end
cmp al,','
jne extra_characters_on_line
jmp data_pwords
je data_pwords
jmp data_end
data_qwords:
lods byte [esi]
cmp al,'('
@ -1343,8 +1380,8 @@ data_qwords:
cmp al,0Fh
je data_end
cmp al,','
jne extra_characters_on_line
jmp data_qwords
je data_qwords
jmp data_end
data_twords:
lods byte [esi]
cmp al,'('
@ -1397,8 +1434,8 @@ data_twords:
cmp al,0Fh
je data_end
cmp al,','
jne extra_characters_on_line
jmp data_twords
je data_twords
jmp data_end
data_file:
lods word [esi]
cmp ax,'('

View file

@ -130,7 +130,7 @@ include '..\x86.inc'
_copyright db 'Copyright (c) 1999-2002, Tomasz Grysztar',0Dh,0Ah,24h
_logo db 'flat assembler version ',VERSION_STRING,0Dh,0Ah,24h
_usage db 'usage: fasm source output',0Dh,0Ah,24h
_usage db 'usage: fasm source [output]',0Dh,0Ah,24h
_passes_suffix db ' passes, ',24h
_seconds_suffix db ' seconds, ',24h
@ -159,6 +159,7 @@ code_size dd ?
real_code_size dd ?
start_time dd ?
written_size dd ?
headers_size dd ?
current_line dd ?
macros_list dd ?
@ -194,6 +195,7 @@ number_start dd ?
current_offset dd ?
value dq ?
fp_value rd 8
adjustment dq ?
symbol_identifier dd ?
address_symbol dd ?
format_flags dd ?
@ -210,6 +212,7 @@ image_base dd ?
resource_data dd ?
resource_size dd ?
passes_limit dw ?
macro_status db ?
parenthesis_stack db ?
output_format db ?

View file

@ -6,176 +6,176 @@
segment modes use16
real32:
mov ax,7202h
push ax
popf
pushf
pop bx
cmp ax,bx
je processor_ok
call init_error
db 'required 80386 or better',24h
mov ax,7202h
push ax
popf
pushf
pop bx
cmp ax,bx
je processor_ok
call init_error
db 'required 80386 or better',24h
processor_ok:
mov eax,ds
shl eax,4
mov [program_base],eax
mov eax,buffer
shl eax,4
sub eax,[program_base]
mov [buffer_address],eax
smsw ax
test al,1
jnz dpmi
mov bx,(400h+(100h*interrupt.size)) shr 4
mov ah,48h
int 21h
jnc mem_ok
mov eax,ds
shl eax,4
mov [program_base],eax
mov eax,buffer
shl eax,4
sub eax,[program_base]
mov [buffer_address],eax
smsw ax
test al,1
jnz dpmi
mov bx,(400h+(100h*interrupt.size)) shr 4
mov ah,48h
int 21h
jnc mem_ok
not_enough_memory:
call init_error
db 'not enough conventional memory',24h
call init_error
db 'not enough conventional memory',24h
mem_ok:
push ds es
mov es,ax
push cs
pop ds
movzx eax,ax
shl eax,4
mov [real32_IDT_base],eax
mov dx,100h
xor bx,bx
mov di,400h
push ds es
mov es,ax
push cs
pop ds
movzx eax,ax
shl eax,4
mov [real32_IDT_base],eax
mov dx,100h
xor bx,bx
mov di,400h
init_interrupts:
mov si,interrupt
mov [si+interrupt.vector],bx
mov word [es:bx],di
mov word [es:bx+2],es
mov cx,interrupt.size
rep movsb
add bx,4
dec dx
jnz init_interrupts
mov eax,cs ; calculate linear address of GDT
shl eax,4
or dword [real32_GDT+10],eax
or dword [real16_GDT+10],eax
add [real32_GDT_address],eax
add [real16_GDT_address],eax
pop es ds
mov [mode],real32
call modes:switch_real32
use32
retfw
use16
mov si,interrupt
mov [si+interrupt.vector],bx
mov word [es:bx],di
mov word [es:bx+2],es
mov cx,interrupt.size
rep movsb
add bx,4
dec dx
jnz init_interrupts
mov eax,cs ; calculate linear address of GDT
shl eax,4
or dword [real32_GDT+10],eax
or dword [real16_GDT+10],eax
add [real32_GDT_address],eax
add [real16_GDT_address],eax
pop es ds
mov [mode],real32
call modes:switch_real32
use32
retfw
use16
init_error:
push cs
pop ds
mov dx,init_error_prefix
mov ah,9
int 21h
pop dx
int 21h
mov dx,init_error_suffix
int 21h
mov ax,04CFFh
int 21h
push cs
pop ds
mov dx,init_error_prefix
mov ah,9
int 21h
pop dx
int 21h
mov dx,init_error_suffix
int 21h
mov ax,04CFFh
int 21h
switch_real32:
pushfw
push eax
push word ds
push word es
push word fs
push word gs
cli
mov eax,ss
mov cr3,eax
lgdt [cs:real32_GDTR] ; load GDT register
mov eax,cr0 ; switch to protected modes
or al,1
mov cr0,eax
jmp 1 shl 3:pm32_start
pushfw
push eax
push word ds
push word es
push word fs
push word gs
cli
mov eax,ss
mov cr3,eax
lgdt [cs:real32_GDTR] ; load GDT register
mov eax,cr0 ; switch to protected modes
or al,1
mov cr0,eax
jmp 1 shl 3:pm32_start
pm32_start:
use32
mov ax,2 shl 3 ; load 32-bit data descriptor
mov ds,ax ; to all data segment registers
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov eax,cr0 ; switch back to real modes
and al,not 1
mov cr0,eax
jmp modes:pm32_end
use32
mov ax,2 shl 3 ; load 32-bit data descriptor
mov ds,ax ; to all data segment registers
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov eax,cr0 ; switch back to real modes
and al,not 1
mov cr0,eax
jmp modes:pm32_end
pm32_end:
mov eax,cr3
mov ss,eax
lidt [cs:real32_IDTR]
pop word gs
pop word fs
pop word es
pop word ds
pop eax
popfw
retfw
mov eax,cr3
mov ss,eax
lidt [cs:real32_IDTR]
pop word gs
pop word fs
pop word es
pop word ds
pop eax
popfw
retfw
switch_real16:
pushfw
push eax
cli
lgdt [cs:real16_GDTR] ; load GDT register
mov eax,cr0 ; switch to protected modes
or al,1
mov cr0,eax
jmp 1 shl 3:pm16_start
pushfw
push eax
cli
lgdt [cs:real16_GDTR] ; load GDT register
mov eax,cr0 ; switch to protected modes
or al,1
mov cr0,eax
jmp 1 shl 3:pm16_start
pm16_start:
use16
mov eax,cr0 ; switch back to real modes
and al,not 1
mov cr0,eax
jmp modes:pm16_end
use16
mov eax,cr0 ; switch back to real modes
and al,not 1
mov cr0,eax
jmp modes:pm16_end
pm16_end:
lidt [cs:real16_IDTR]
pop eax
popfw
retfd
use32
lidt [cs:real16_IDTR]
pop eax
popfw
retfd
use32
interrupt:
call modes:switch_real16
use16
movzx esp,sp
push word [esp+4]
push cs
call .real16
pushfw
pop word [esp+4]
call modes:switch_real32
use32
iretw
call modes:switch_real16
use16
movzx esp,sp
push word [esp+4]
push cs
call .real16
pushfw
pop word [esp+4]
call modes:switch_real32
use32
iretw
.real16:
use16
push eax
push ds
xor ax,ax
mov ds,ax
mov eax,[word 0]
label .vector word at $-2-interrupt
pop ds
xchg eax,[esp]
retfw
use16
push eax
push ds
xor ax,ax
mov ds,ax
mov eax,[word 0]
label .vector word at $-2-interrupt
pop ds
xchg eax,[esp]
retfw
.size = $-interrupt
label real32_GDTR pword
real32_GDT_limit dw 3*8-1 ; limit of GDT
real32_GDT_address dd real32_GDT ; linear address of GDT
real32_GDT rw 4 ; null descriptor
dw 0FFFFh,0,9A00h,0CFh ; 32-bit code descriptor
dw 0FFFFh,0,9200h,08Fh ; 4 GB data descriptor
real32_GDT_limit dw 3*8-1 ; limit of GDT
real32_GDT_address dd real32_GDT ; linear address of GDT
real32_GDT rw 4 ; null descriptor
dw 0FFFFh,0,9A00h,0CFh ; 32-bit code descriptor
dw 0FFFFh,0,9200h,08Fh ; 4 GB data descriptor
label real16_GDTR pword
real16_GDT_limit dw 2*8-1 ; limit of GDT
real16_GDT_address dd real16_GDT ; linear address of GDT
real16_GDT rw 4 ; null descriptor
dw 0FFFFh,0,9A00h,0 ; 16-bit code descriptor
real16_GDT_limit dw 2*8-1 ; limit of GDT
real16_GDT_address dd real16_GDT ; linear address of GDT
real16_GDT rw 4 ; null descriptor
dw 0FFFFh,0,9A00h,0 ; 16-bit code descriptor
label real32_IDTR pword
real32_IDT_limit dw 3FFh
@ -188,75 +188,75 @@ init_error_prefix db 'error: ',24h
init_error_suffix db '.',0Dh,0Ah,24h
dpmi:
mov ax,1687h
int 2Fh
or ax,ax ; DPMI installed?
jnz no_dpmi
test bl,1 ; 32-bit programs supported?
jz no_dpmi
mov word [cs:mode_switch],di
mov word [cs:mode_switch+2],es
mov bx,si ; allocate memory for DPMI data
mov ah,48h
int 21h
jc not_enough_memory
mov ds,[environment_segment]
mov es,ax
mov ax,1
call far [cs:mode_switch] ; switch to protected mode
jc no_dpmi
mov cx,1
xor ax,ax
int 31h ; allocate descriptor for code
mov si,ax
xor ax,ax
int 31h ; allocate descriptor for data
mov di,ax
mov dx,cs
lar cx,dx
shr cx,8
or cx,0C000h
mov bx,si
mov ax,9
int 31h ; set code descriptor access rights
mov dx,ds
lar cx,dx
shr cx,8
or cx,0C000h
mov bx,di
int 31h ; set data descriptor access rights
mov ecx,main
shl ecx,4
mov dx,cx
shr ecx,16
mov ax,7
int 31h ; set data descriptor base address
movzx ecx,word [esp+2]
shl ecx,4
mov dx,cx
shr ecx,16
mov bx,si
int 31h ; set code descriptor base address
mov cx,0FFFFh
mov dx,0FFFFh
mov ax,8 ; set segment limit to 4 GB
int 31h
mov bx,di
int 31h
mov ax,ds
mov ds,di
mov [psp_segment],es
mov [environment_segment],ax
mov es,di
mov [mode],dpmi
pop ebx
movzx ebx,bx
push esi
push ebx
retfd
mov ax,1687h
int 2Fh
or ax,ax ; DPMI installed?
jnz no_dpmi
test bl,1 ; 32-bit programs supported?
jz no_dpmi
mov word [cs:mode_switch],di
mov word [cs:mode_switch+2],es
mov bx,si ; allocate memory for DPMI data
mov ah,48h
int 21h
jc not_enough_memory
mov ds,[environment_segment]
mov es,ax
mov ax,1
call far [cs:mode_switch] ; switch to protected mode
jc no_dpmi
mov cx,1
xor ax,ax
int 31h ; allocate descriptor for code
mov si,ax
xor ax,ax
int 31h ; allocate descriptor for data
mov di,ax
mov dx,cs
lar cx,dx
shr cx,8
or cx,0C000h
mov bx,si
mov ax,9
int 31h ; set code descriptor access rights
mov dx,ds
lar cx,dx
shr cx,8
or cx,0C000h
mov bx,di
int 31h ; set data descriptor access rights
mov ecx,main
shl ecx,4
mov dx,cx
shr ecx,16
mov ax,7
int 31h ; set data descriptor base address
movzx ecx,word [esp+2]
shl ecx,4
mov dx,cx
shr ecx,16
mov bx,si
int 31h ; set code descriptor base address
mov cx,0FFFFh
mov dx,0FFFFh
mov ax,8 ; set segment limit to 4 GB
int 31h
mov bx,di
int 31h
mov ax,ds
mov ds,di
mov [psp_segment],es
mov [environment_segment],ax
mov es,di
mov [mode],dpmi
pop ebx
movzx ebx,bx
push esi
push ebx
retfd
no_dpmi:
call init_error
db 'system is in protected mode without DPMI services',24h
call init_error
db 'system is in protected mode without DPMI services',24h
mode_switch dd ?

View file

@ -349,6 +349,7 @@ xms_handle dw ? ; handle of XMS memory block
get_params:
mov [memory_setting],0
mov [passes_limit],100
push ds
mov ds,[psp_segment]
mov esi,81h
@ -396,10 +397,41 @@ get_params:
je memory_option
cmp al,'M'
je memory_option
cmp al,'p'
je passes_option
cmp al,'P'
je passes_option
invalid_option:
pop ds
stc
ret
get_option_value:
xor eax,eax
mov edx,eax
get_option_digit:
lodsb
cmp al,20h
je option_value_ok
cmp al,0Dh
je option_value_ok
or al,al
jz option_value_ok
sub al,30h
jc bad_params_value
cmp al,9
ja bad_params_value
imul edx,10
jo bad_params_value
add edx,eax
jc bad_params_value
jmp get_option_digit
option_value_ok:
dec esi
clc
ret
bad_params_value:
stc
ret
memory_option:
lodsb
cmp al,20h
@ -409,32 +441,30 @@ get_params:
or al,al
jz invalid_option
dec esi
xor eax,eax
mov edx,eax
get_memory_setting:
lodsb
cmp al,20h
je memory_setting_ok
cmp al,0Dh
je memory_setting_ok
or al,al
jz memory_setting_ok
sub al,30h
call get_option_value
jc invalid_option
cmp al,9
ja invalid_option
imul edx,10
jo invalid_option
add edx,eax
jc invalid_option
jmp get_memory_setting
memory_setting_ok:
or edx,edx
jz invalid_option
cmp edx,1 shl (32-10)
jae invalid_option
mov [es:memory_setting],edx
jmp find_param
passes_option:
lodsb
cmp al,20h
je passes_option
cmp al,0Dh
je invalid_option
or al,al
jz invalid_option
dec esi
call get_option_value
jc bad_params
or edx,edx
jz invalid_option
cmp edx,10000h
ja invalid_option
mov [es:passes_limit],dx
jmp find_param
param_end:
dec esi
@ -453,16 +483,18 @@ get_params:
je bad_params
lea eax,[params+1]
mov [input_file],eax
mov [output_file],0
movzx ecx,byte [eax-1]
add eax,ecx
cmp byte [eax],0
je bad_params
je params_ok
inc eax
mov [output_file],eax
movzx ecx,byte [eax-1]
add eax,ecx
cmp byte [eax],0
jne bad_params
params_ok:
clc
ret
bad_params:

View file

@ -949,21 +949,35 @@ calculate_expression:
or byte [ebx+8],8
test byte [ebx+8],1
jz label_undefined
test byte [ebx+8],4
jz label_defined
cmp ax,[ebx+16]
jne label_undefined
je label_defined
test byte [ebx+8],4
jnz label_undefined
test byte [ebx+9],1
jz label_defined
mov eax,[ebx]
sub eax,dword [adjustment]
stos dword [edi]
mov eax,[ebx+4]
sbb eax,dword [adjustment+4]
stos dword [edi]
mov eax,dword [adjustment]
or eax,dword [adjustment+4]
jz got_label
or [next_pass_needed],-1
jmp got_label
label_defined:
mov al,[ebx+11]
mov [edi+12],al
mov eax,[ebx+12]
mov [edi+8],eax
mov eax,[ebx+20]
mov [edi+16],eax
mov eax,[ebx]
stos dword [edi]
mov eax,[ebx+4]
stos dword [edi]
got_label:
mov al,[ebx+11]
mov [edi-8+12],al
mov eax,[ebx+12]
mov [edi-8+8],eax
mov eax,[ebx+20]
mov [edi-8+16],eax
add edi,0Ch
mov al,[ebx+10]
or al,al
@ -1019,15 +1033,15 @@ calculate_expression:
cmp eax,2
je timestamp_label
label_undefined:
cmp [current_pass],0
je force_second_pass
cmp [current_pass],1
jbe force_next_pass
cmp [error_line],0
jne undefined_value
mov eax,[current_line]
mov [error_line],eax
mov [error],undefined_symbol
jmp undefined_value
force_second_pass:
force_next_pass:
or [next_pass_needed],-1
undefined_value:
mov byte [edi+12],0
@ -2335,18 +2349,28 @@ get_logical_value:
cmp eax,0Fh
jb check_expression
je reserved_word_used_as_symbol
test byte [eax+8],4
jnz no_prediction
test byte [eax+8],1
jz symbol_predicted_undefined
mov cx,[current_pass]
sub cx,[eax+16]
jz check_expression
cmp cx,1
ja symbol_predicted_undefined
or byte [eax+8],40h+80h
jmp check_expression
no_prediction:
test byte [eax+8],1
jz symbol_undefined
mov cx,[current_pass]
sub cx,[eax+16]
jz check_expression
cmp cx,1
ja symbol_undefined
or byte [eax+8],40h+80h
jmp check_expression
symbol_undefined:
jz check_expression
jmp symbol_undefined
symbol_predicted_undefined:
or byte [eax+8],40h
and byte [eax+8],not 80h
symbol_undefined:
xor bl,bl
jmp check_expression
expression_checked:

View file

@ -4,6 +4,109 @@
; All rights reserved.
formatter:
cmp [output_file],0
jne output_path_ok
push edi
mov esi,[input_file]
mov edi,[free_additional_memory]
copy_output_path:
lods byte [esi]
cmp edi,[structures_buffer]
jae out_of_memory
stos byte [edi]
or al,al
jnz copy_output_path
dec edi
mov eax,edi
dec edi
find_extension:
dec eax
cmp eax,[free_additional_memory]
jb extension_found
cmp byte [eax],'\'
je extension_found
cmp byte [eax],'/'
je extension_found
cmp byte [eax],'.'
jne find_extension
mov edi,eax
extension_found:
lea eax,[edi+9]
cmp eax,[structures_buffer]
jae out_of_memory
cmp [output_format],2
je exe_extension
jb bin_extension
cmp [output_format],4
je obj_extension
cmp [output_format],5
je o_extension
cmp [output_format],3
jne no_extension
cmp [subsystem],1
je sys_extension
bt [format_flags],8
jnc exe_extension
mov eax,'.dll'
jmp make_extension
sys_extension:
mov eax,'.sys'
jmp make_extension
bin_extension:
mov eax,'.bin'
bt [format_flags],0
jnc make_extension
mov eax,'.com'
jmp make_extension
obj_extension:
mov eax,'.obj'
jmp make_extension
o_extension:
mov eax,'.o'
bt [format_flags],0
jnc make_extension
no_extension:
xor eax,eax
jmp make_extension
exe_extension:
mov eax,'.exe'
make_extension:
xchg eax,[edi]
scas dword [edi]
mov byte [edi],0
scas byte [edi]
mov esi,edi
stos dword [edi]
sub edi,9
xor eax,eax
mov ebx,characters
adapt_case:
mov al,[esi]
or al,al
jz adapt_next
xlat byte [ebx]
cmp al,[esi]
je adapt_ok
sub byte [edi],20h
adapt_ok:
inc esi
adapt_next:
inc edi
cmp byte [edi],0
jne adapt_case
mov esi,edi
lea ecx,[esi+1]
sub ecx,[free_additional_memory]
mov edi,[structures_buffer]
dec edi
std
rep movs byte [edi],[esi]
cld
inc edi
mov [structures_buffer],edi
mov [output_file],edi
pop edi
output_path_ok:
cmp [output_format],4
je coff_formatter
cmp [output_format],5
@ -41,6 +144,8 @@ formatter:
call close
ret
write_code:
mov eax,[written_size]
mov [headers_size],eax
mov edx,[code_start]
mov ecx,[code_size]
add [written_size],ecx
@ -506,7 +611,7 @@ make_stub:
int 21h
mov ax,4C01h
int 21h
stub_message db 'this program cannot be run in DOS mode.',0Dh,0Ah,24h
stub_message db 'This program cannot be run in DOS mode.',0Dh,0Ah,24h
rq 1
default_stub_end:
use32
@ -2020,16 +2125,23 @@ coff_formatter:
shl edx,8
mov dl,80h
mov [esi],edx
inc eax
mov edx,[esi+8]
add esi,10h
inc eax
cmp byte [edx+11],2
jne enumerate_symbols
mov edx,[edx+20]
cmp byte [edx],81h
jne enumerate_symbols
inc eax
jmp enumerate_symbols
enumerate_extrn:
mov edx,eax
shl edx,8
mov dl,81h
mov [esi],edx
inc eax
add esi,0Ch
inc eax
jmp enumerate_symbols
prepare_default_section:
mov ebx,[symbols_stream]
@ -2262,6 +2374,8 @@ coff_formatter:
jne invalid_use_of_symbol
mov ecx,[eax+20]
mov ecx,[ecx]
cmp cl,81h
je alias_symbol
or cl,cl
jnz invalid_use_of_symbol
shr ecx,8
@ -2281,6 +2395,23 @@ coff_formatter:
add esi,10h
add ebx,12h
jmp make_symbols_table
alias_symbol:
bt [format_flags],0
jnc invalid_use_of_symbol
mov ecx,[eax]
or ecx,[eax+4]
jnz invalid_use_of_symbol
mov byte [ebx+10h],69h
mov byte [ebx+11h],1
add ebx,12h
mov ecx,[eax+20]
mov ecx,[ecx]
shr ecx,8
mov [ebx],ecx
mov byte [ebx+4],3
add esi,10h
add ebx,12h
jmp make_symbols_table
public_constant:
mov word [ebx+0Ch],0FFFFh
jmp public_symbol_section_ok

View file

@ -125,7 +125,7 @@ include '..\x86.inc'
_copyright db 'Copyright (c) 1999-2002, Tomasz Grysztar',0xA,0
_logo db 'flat assembler version ',VERSION_STRING,0xA,0
_usage db 'usage: fasm source output',0xA,0
_usage db 'usage: fasm source [output]',0xA,0
_passes_suffix db ' passes, ',0
_seconds_suffix db ' seconds, ',0
@ -154,6 +154,7 @@ code_size dd ?
real_code_size dd ?
start_time dd ?
written_size dd ?
headers_size dd ?
current_line dd ?
macros_list dd ?
@ -189,6 +190,7 @@ number_start dd ?
current_offset dd ?
value dq ?
fp_value rd 8
adjustment dq ?
symbol_identifier dd ?
address_symbol dd ?
format_flags dd ?
@ -205,6 +207,7 @@ image_base dd ?
resource_data dd ?
resource_size dd ?
passes_limit dw ?
macro_status db ?
parenthesis_stack db ?
output_format db ?

View file

@ -74,6 +74,7 @@ get_params:
mov [input_file],0
mov [output_file],0
mov [memory_setting],0
mov [passes_limit],100
mov ecx,[ebx]
add ebx,8
dec ecx
@ -99,12 +100,14 @@ get_params:
je memory_option
cmp al,'M'
je memory_option
cmp al,'p'
je passes_option
cmp al,'P'
je passes_option
bad_params:
stc
ret
memory_option:
xor eax,eax
mov edx,eax
cmp byte [esi],0
jne get_memory_setting
dec ecx
@ -112,33 +115,62 @@ get_params:
add ebx,4
mov esi,[ebx]
get_memory_setting:
lodsb
or al,al
jz memory_setting_ok
sub al,30h
jc bad_params
cmp al,9
ja bad_params
imul edx,10
jo bad_params
add edx,eax
jc bad_params
jmp get_memory_setting
memory_setting_ok:
call get_option_value
or edx,edx
jz bad_params
cmp edx,1 shl (32-10)
jae bad_params
mov [memory_setting],edx
jmp next_param
passes_option:
cmp byte [esi],0
jne get_passes_setting
dec ecx
jz bad_params
add ebx,4
mov esi,[ebx]
get_passes_setting:
call get_option_value
or edx,edx
jz bad_params
cmp edx,10000h
ja bad_params
mov [passes_limit],dx
next_param:
add ebx,4
loop get_param
dec ecx
jnz get_param
cmp [input_file],0
je bad_params
cmp [output_file],0
je bad_params
clc
ret
get_option_value:
xor eax,eax
mov edx,eax
get_option_digit:
lodsb
cmp al,20h
je option_value_ok
cmp al,0Dh
je option_value_ok
or al,al
jz option_value_ok
sub al,30h
jc invalid_option_value
cmp al,9
ja invalid_option_value
imul edx,10
jo invalid_option_value
add edx,eax
jc invalid_option_value
jmp get_option_digit
option_value_ok:
dec esi
clc
ret
invalid_option_value:
stc
ret
get_environment_variable:
mov ebx,esi

View file

@ -248,6 +248,7 @@ convert_line:
preprocess_line:
push [struc_name]
push ecx esi
preprocess_current_line:
mov esi,[current_line]
add esi,16
lods byte [esi]
@ -969,11 +970,30 @@ define_macro:
jz line_preprocessed
cmp al,'}'
jne skip_macro_block
and [macro_status],0F0h
lods byte [esi]
or al,al
jnz extra_characters_on_line
and [macro_status],0F0h
jmp line_preprocessed
jz line_preprocessed
dec esi
mov ecx,edi
sub ecx,esi
mov edx,esi
lea esi,[esi+ecx-1]
lea edi,[edi+1+16]
mov ebx,edi
dec edi
std
rep movs byte [edi],[esi]
cld
mov edi,edx
xor al,al
stos byte [edi]
mov esi,[current_line]
mov [current_line],edi
mov ecx,4
rep movs dword [edi],[esi]
mov edi,ebx
jmp preprocess_current_line
skip_macro_symbol:
movzx eax,byte [esi]
inc esi

View file

@ -1,5 +1,5 @@
; flat assembler version 1.53
; flat assembler version 1.54
; Copyright (c) 1999-2004, 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.53"
VERSION_STRING equ "1.54"
VERSION_MAJOR = 1
VERSION_MINOR = 53
VERSION_MINOR = 54

View file

@ -96,7 +96,7 @@ include '..\x86.inc'
_copyright db 'Copyright (c) 1999-2002, Tomasz Grysztar',0Dh,0Ah,0
_logo db 'flat assembler version ',VERSION_STRING,0Dh,0Ah,0
_usage db 'usage: fasm source output',0Dh,0Ah,0
_usage db 'usage: fasm source [output]',0Dh,0Ah,0
_passes_suffix db ' passes, ',0
_seconds_suffix db ' seconds, ',0
@ -123,6 +123,7 @@ code_size dd ?
real_code_size dd ?
start_time dd ?
written_size dd ?
headers_size dd ?
current_line dd ?
macros_list dd ?
@ -158,6 +159,7 @@ number_start dd ?
current_offset dd ?
value dq ?
fp_value rd 8
adjustment dq ?
symbol_identifier dd ?
address_symbol dd ?
format_flags dd ?
@ -174,6 +176,7 @@ image_base dd ?
resource_data dd ?
resource_size dd ?
passes_limit dw ?
macro_status db ?
parenthesis_stack db ?
output_format db ?

View file

@ -84,6 +84,7 @@ exit_program:
get_params:
mov [memory_setting],0
mov [passes_limit],100
call [GetCommandLine]
mov esi,eax
mov edi,params
@ -150,9 +151,40 @@ get_params:
je memory_option
cmp al,'M'
je memory_option
cmp al,'p'
je passes_option
cmp al,'P'
je passes_option
bad_params:
stc
ret
get_option_value:
xor eax,eax
mov edx,eax
get_option_digit:
lodsb
cmp al,20h
je option_value_ok
cmp al,0Dh
je option_value_ok
or al,al
jz option_value_ok
sub al,30h
jc invalid_option_value
cmp al,9
ja invalid_option_value
imul edx,10
jo invalid_option_value
add edx,eax
jc invalid_option_value
jmp get_option_digit
option_value_ok:
dec esi
clc
ret
invalid_option_value:
stc
ret
memory_option:
lodsb
cmp al,20h
@ -162,32 +194,28 @@ get_params:
or al,al
jz bad_params
dec esi
xor eax,eax
mov edx,eax
get_memory_setting:
lodsb
cmp al,20h
je memory_setting_ok
cmp al,0Dh
je memory_setting_ok
or al,al
jz memory_setting_ok
sub al,30h
jc bad_params
cmp al,9
ja bad_params
imul edx,10
jo bad_params
add edx,eax
jc bad_params
jmp get_memory_setting
memory_setting_ok:
call get_option_value
or edx,edx
jz bad_params
cmp edx,1 shl (32-10)
jae bad_params
mov [memory_setting],edx
jmp find_param
passes_option:
lodsb
cmp al,20h
je passes_option
cmp al,0Dh
je bad_params
or al,al
jz bad_params
dec esi
call get_option_value
or edx,edx
jz bad_params
cmp edx,10000h
ja bad_params
mov [passes_limit],dx
jmp find_param
param_end:
dec esi
@ -205,16 +233,18 @@ get_params:
je bad_params
lea eax,[params+1]
mov [input_file],eax
mov [output_file],0
movzx ecx,byte [eax-1]
add eax,ecx
cmp byte [eax],0
je bad_params
je params_ok
inc eax
mov [output_file],eax
movzx ecx,byte [eax-1]
add eax,ecx
cmp byte [eax],0
jne bad_params
params_ok:
clc
ret

View file

@ -1,6 +1,15 @@
Visit http://flatassembler.net/ for more information
version 1.54
[04-08-2004]
------------
[+] commands allowed in the same line after end of macro definition
[+] automatic generation of output file name addded to formatter
[+] allowed public aliases of external symbols with MS COFF format
[-] fixed "defined" to return true only for accessible symbols
[-] improved label resolving algorithms
version 1.53
[22-07-2004]
------------