mirror of
https://github.com/tgrysztar/fasm
synced 2026-08-26 00:23:06 -04:00
release 1.55
This commit is contained in:
parent
01d0d168a4
commit
d42cbbd427
9 changed files with 203 additions and 75 deletions
91
FASM.TXT
91
FASM.TXT
|
|
@ -5,7 +5,7 @@
|
|||
Û ÜßßßßÛ ßßßßÜ Û Û Û
|
||||
Û ßÜÜÜÜÛÜ ÜÜÜÜÜß Û Û Û
|
||||
|
||||
flat assembler 1.54
|
||||
flat assembler 1.55
|
||||
Programmer's Manual
|
||||
|
||||
|
||||
|
|
@ -131,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.54
|
||||
flat assembler version 1.55
|
||||
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.54
|
||||
flat assembler version 1.55
|
||||
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.54
|
||||
flat assembler version 1.55
|
||||
example.asm [3]:
|
||||
mob ax,1
|
||||
error: illegal instruction.
|
||||
|
|
@ -155,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.54
|
||||
flat assembler version 1.55
|
||||
example.asm [6]:
|
||||
stoschar 7
|
||||
example.asm [3] stoschar [1]:
|
||||
|
|
@ -2313,6 +2313,15 @@ itself, which has the highest possible priority, so it allows redefinition of
|
|||
constants defined this way. But when such high priority constants are found
|
||||
inside the value following the "fix" directive, they are replaced with their
|
||||
values before assigning this value to the new constant.
|
||||
The "fix" directive can be used for syntax adjustments related to directives
|
||||
of preprocessor, what cannot be done with "equ" directive. For example:
|
||||
|
||||
incl fix include
|
||||
|
||||
defines a short name for "include" directive, while the similar definition done
|
||||
with "equ" directive wouldn't give such result, as standard symbolic constants
|
||||
are replaced with their values after searching the line for preprocessor
|
||||
directives.
|
||||
|
||||
|
||||
2.3.3 Macroinstructions
|
||||
|
|
@ -2579,6 +2588,74 @@ argument of this macro is some number, label, or variable, the string from
|
|||
that address is displayed, but when the argument is a quoted string, the
|
||||
created code will display that string followed by the carriage return and
|
||||
line feed.
|
||||
It is also possible to put a declaration of macroinstruction inside another
|
||||
macroinstruction, so one macro can define another, but there is a problem
|
||||
with such definitions caused by fact, that "}" character cannot occur inside
|
||||
the macroinstruction, as it always means the end of definition. But it's easy
|
||||
to overcome this problem with use of the "fix" directive. Here is an example:
|
||||
|
||||
macro ext instr
|
||||
{
|
||||
macro instr op1,op2,op3
|
||||
_%
|
||||
if op3 eq
|
||||
instr op1,op2
|
||||
else
|
||||
instr op1,op2
|
||||
instr op2,op3
|
||||
end if
|
||||
%_
|
||||
}
|
||||
|
||||
_% fix {
|
||||
%_ fix }
|
||||
|
||||
ext add
|
||||
ext sub
|
||||
|
||||
The macro "ext" is defined correctly, but when it is used, the "_%" and "%_"
|
||||
are defined as high priority symbolic constants and are replaced with their
|
||||
values before doing anything else. So when the "ext add" is processed, the
|
||||
contents of macro becomes valid definition of a macroinstruction and this way
|
||||
the "add" macro becomes defined. In the same way "ext sub" defines the "sub"
|
||||
macro. The use of "_%" constant instead of "{" wasn't really necessary here,
|
||||
but is done this way to make the definition more clear. Note that the right
|
||||
order of definitions is crucial here.
|
||||
If some directives specific to macroinstructions, like "local" or "common"
|
||||
are needed inside some macro embedded this way, they also have to be replaced
|
||||
with some symbols defined later as a high priority constants with the values
|
||||
being the intended directives. And when the "#" operator is needed in the
|
||||
embedded macro, the help comes from the fact that any sequence of "#" characters
|
||||
inside the macroinstruction is reduced to chain shorter by one character, and
|
||||
only if it was the single "#" character, the concatenation is performed. So
|
||||
to put the concatenation operator inside the embedded macro it is enough to
|
||||
write "##" there.
|
||||
The above techniques can be even applied to create the new ways of defining
|
||||
macroinstructions. For example:
|
||||
|
||||
macro tmacro params
|
||||
{
|
||||
macro params {
|
||||
}
|
||||
|
||||
MACRO fix tmacro
|
||||
ENDM fix }
|
||||
|
||||
defines an alternative syntax for defining macroinstructions, which looks like:
|
||||
|
||||
MACRO stoschar char
|
||||
mov al,char
|
||||
stosb
|
||||
ENDM
|
||||
|
||||
Note that symbol that has such customized definition must be defined with "fix"
|
||||
directive, because only the prioritized symbolic constants are processed before
|
||||
the preprocessor looks for the "}" character while defining the macro. This
|
||||
might be a problem if one needed to perform some additional tasks one the end
|
||||
of such definition, but there is one more feature which helps in such cases.
|
||||
Namely it is possible to put any directive, instruction or macroinstruction
|
||||
just after the "}" character that ends the macroinstruction and it will be
|
||||
processed in the same way as if it was put in the next line.
|
||||
|
||||
|
||||
2.3.4 Structures
|
||||
|
|
@ -2591,8 +2668,8 @@ with dot in the contents of macroinstruction. The macroinstruction defined
|
|||
using the "struc" directive can have the same name as some other
|
||||
macroinstruction defined using the "macro" directive, structure
|
||||
macroinstruction won't prevent the standard macroinstruction being processed
|
||||
when there is no label before it and vice versa. All the rules concerning
|
||||
standard macroinstructions apply to structure macroinstructions.
|
||||
when there is no label before it and vice versa. All the rules and features
|
||||
concerning standard macroinstructions apply to structure macroinstructions.
|
||||
Here is the sample of structure macroinstruction:
|
||||
|
||||
struc point x,y
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
flat assembler version 1.54
|
||||
flat assembler version 1.55
|
||||
Copyright (c) 1999-2004, Tomasz Grysztar.
|
||||
All rights reserved.
|
||||
|
||||
|
|
|
|||
|
|
@ -48,9 +48,14 @@ assembler:
|
|||
pass_loop:
|
||||
call assemble_line
|
||||
jnc pass_loop
|
||||
mov eax,[structures_buffer]
|
||||
cmp eax,[additional_memory_end]
|
||||
jne unexpected_end_of_file
|
||||
mov eax,[additional_memory_end]
|
||||
cmp eax,[structures_buffer]
|
||||
je pass_done
|
||||
sub eax,20h
|
||||
mov eax,[eax+4]
|
||||
mov [current_line],eax
|
||||
jmp missing_end_directive
|
||||
pass_done:
|
||||
call close_pass
|
||||
mov eax,[labels_list]
|
||||
check_symbols:
|
||||
|
|
@ -849,18 +854,20 @@ virtual_directive:
|
|||
neg eax
|
||||
add eax,edi
|
||||
xchg [org_origin],eax
|
||||
mov [ebx+4],eax
|
||||
mov [ebx+8],edx
|
||||
mov [ebx+10h],eax
|
||||
mov [ebx+14h],edx
|
||||
mov al,[virtual_data]
|
||||
mov [ebx+2],al
|
||||
mov al,[reloc_labels]
|
||||
mov [ebx+3],al
|
||||
mov eax,edi
|
||||
xchg eax,[org_start]
|
||||
mov [ebx+0Ch],eax
|
||||
mov [ebx+18h],eax
|
||||
xchg ebp,[org_symbol]
|
||||
mov [ebx+10h],ebp
|
||||
mov [ebx+14h],edi
|
||||
mov [ebx+1Ch],ebp
|
||||
mov [ebx+8],edi
|
||||
mov eax,[current_line]
|
||||
mov [ebx+4],eax
|
||||
or [virtual_data],-1
|
||||
mov [reloc_labels],0
|
||||
cmp [value_type],0
|
||||
|
|
@ -871,7 +878,7 @@ virtual_directive:
|
|||
jmp instruction_assembled
|
||||
allocate_structure_data:
|
||||
mov ebx,[structures_buffer]
|
||||
sub ebx,18h
|
||||
sub ebx,20h
|
||||
cmp ebx,[free_additional_memory]
|
||||
jb out_of_memory
|
||||
mov [structures_buffer],ebx
|
||||
|
|
@ -896,7 +903,7 @@ virtual_directive:
|
|||
cmp word [ebx],repeat_directive-assembler
|
||||
je no_such_structure
|
||||
repeat_structure_ok:
|
||||
add ebx,18h
|
||||
add ebx,20h
|
||||
jmp scan_structures
|
||||
no_such_structure:
|
||||
stc
|
||||
|
|
@ -908,21 +915,21 @@ virtual_directive:
|
|||
mov [virtual_data],al
|
||||
mov al,[ebx+3]
|
||||
mov [reloc_labels],al
|
||||
mov eax,[ebx+4]
|
||||
mov [org_origin],eax
|
||||
mov eax,[ebx+8]
|
||||
mov [org_registers],eax
|
||||
mov eax,[ebx+0Ch]
|
||||
mov [org_start],eax
|
||||
mov eax,[ebx+10h]
|
||||
mov [org_origin],eax
|
||||
mov eax,[ebx+14h]
|
||||
mov [org_registers],eax
|
||||
mov eax,[ebx+18h]
|
||||
mov [org_start],eax
|
||||
mov eax,[ebx+1Ch]
|
||||
mov [org_symbol],eax
|
||||
mov edi,[ebx+14h]
|
||||
mov edi,[ebx+8]
|
||||
remove_structure_data:
|
||||
push esi edi
|
||||
mov esi,[structures_buffer]
|
||||
mov ecx,ebx
|
||||
sub ecx,esi
|
||||
lea edi,[esi+18h]
|
||||
lea edi,[esi+20h]
|
||||
mov [structures_buffer],edi
|
||||
shr ecx,2
|
||||
rep movs dword [edi],[esi]
|
||||
|
|
@ -948,11 +955,13 @@ repeat_directive:
|
|||
call allocate_structure_data
|
||||
mov word [ebx],repeat_directive-assembler
|
||||
xchg eax,[counter_limit]
|
||||
mov [ebx+4],eax
|
||||
mov [ebx+10h],eax
|
||||
mov eax,1
|
||||
xchg eax,[counter]
|
||||
mov [ebx+8],eax
|
||||
mov [ebx+0Ch],esi
|
||||
mov [ebx+14h],eax
|
||||
mov [ebx+8],esi
|
||||
mov eax,[current_line]
|
||||
mov [ebx+4],eax
|
||||
jmp instruction_assembled
|
||||
end_repeat:
|
||||
cmp [times_working],0
|
||||
|
|
@ -963,13 +972,13 @@ repeat_directive:
|
|||
inc [counter]
|
||||
cmp [counter],eax
|
||||
jbe continue_repeating
|
||||
mov eax,[ebx+4]
|
||||
mov eax,[ebx+10h]
|
||||
mov [counter_limit],eax
|
||||
mov eax,[ebx+8]
|
||||
mov eax,[ebx+14h]
|
||||
mov [counter],eax
|
||||
jmp remove_structure_data
|
||||
continue_repeating:
|
||||
mov esi,[ebx+0Ch]
|
||||
mov esi,[ebx+8]
|
||||
jmp instruction_assembled
|
||||
negative_repeat:
|
||||
cmp [error_line],0
|
||||
|
|
@ -980,7 +989,7 @@ repeat_directive:
|
|||
zero_repeat:
|
||||
mov al,[esi]
|
||||
or al,al
|
||||
jz unexpected_end_of_file
|
||||
jz missing_end_directive
|
||||
cmp al,0Fh
|
||||
jne extra_characters_on_line
|
||||
call find_end_repeat
|
||||
|
|
@ -991,10 +1000,14 @@ repeat_directive:
|
|||
jne unexpected_instruction
|
||||
ret
|
||||
find_structure_end:
|
||||
push [error_line]
|
||||
mov eax,[current_line]
|
||||
mov [error_line],eax
|
||||
find_end_directive:
|
||||
call skip_line
|
||||
lods byte [esi]
|
||||
cmp al,0Fh
|
||||
jne unexpected_end_of_file
|
||||
jne no_end_directive
|
||||
lods dword [esi]
|
||||
mov [current_line],eax
|
||||
skip_labels:
|
||||
|
|
@ -1004,10 +1017,10 @@ repeat_directive:
|
|||
jmp skip_labels
|
||||
labels_ok:
|
||||
cmp byte [esi],1
|
||||
jne find_structure_end
|
||||
jne find_end_directive
|
||||
mov ax,[esi+1]
|
||||
cmp ax,prefix_instruction-assembler
|
||||
je find_structure_end
|
||||
je find_end_directive
|
||||
add esi,4
|
||||
cmp ax,repeat_directive-assembler
|
||||
je skip_repeat
|
||||
|
|
@ -1016,20 +1029,37 @@ repeat_directive:
|
|||
cmp ax,else_directive-assembler
|
||||
je structure_end
|
||||
cmp ax,end_directive-assembler
|
||||
jne find_structure_end
|
||||
jne find_end_directive
|
||||
cmp byte [esi],1
|
||||
jne find_structure_end
|
||||
jne find_end_directive
|
||||
mov ax,[esi+1]
|
||||
add esi,4
|
||||
cmp ax,repeat_directive-assembler
|
||||
je structure_end
|
||||
cmp ax,if_directive-assembler
|
||||
jne find_structure_end
|
||||
jne find_end_directive
|
||||
structure_end:
|
||||
pop [error_line]
|
||||
ret
|
||||
no_end_directive:
|
||||
mov eax,[error_line]
|
||||
mov [current_line],eax
|
||||
jmp missing_end_directive
|
||||
skip_repeat:
|
||||
call find_end_repeat
|
||||
jmp find_structure_end
|
||||
jmp find_end_directive
|
||||
skip_if:
|
||||
call find_else
|
||||
jc find_end_directive
|
||||
cmp byte [esi],1
|
||||
jne skip_after_else
|
||||
cmp word [esi+1],if_directive-assembler
|
||||
jne skip_after_else
|
||||
add esi,4
|
||||
jmp skip_if
|
||||
skip_after_else:
|
||||
call find_end_if
|
||||
jmp find_end_directive
|
||||
if_directive:
|
||||
cmp [times_working],0
|
||||
jne unexpected_instruction
|
||||
|
|
@ -1037,7 +1067,7 @@ if_directive:
|
|||
mov dl,al
|
||||
mov al,[esi]
|
||||
or al,al
|
||||
jz unexpected_end_of_file
|
||||
jz missing_end_directive
|
||||
cmp al,0Fh
|
||||
jne extra_characters_on_line
|
||||
or dl,dl
|
||||
|
|
@ -1052,19 +1082,21 @@ if_directive:
|
|||
add esi,4
|
||||
jmp if_directive
|
||||
if_true:
|
||||
xor al,al
|
||||
make_if_structure:
|
||||
call allocate_structure_data
|
||||
mov word [ebx],if_directive-assembler
|
||||
mov byte [ebx+2],0
|
||||
mov byte [ebx+2],al
|
||||
mov eax,[current_line]
|
||||
mov [ebx+4],eax
|
||||
jmp instruction_assembled
|
||||
else_true:
|
||||
or al,al
|
||||
jz unexpected_end_of_file
|
||||
jz missing_end_directive
|
||||
cmp al,0Fh
|
||||
jne extra_characters_on_line
|
||||
call allocate_structure_data
|
||||
mov word [ebx],if_directive-assembler
|
||||
or byte [ebx+2],-1
|
||||
jmp instruction_assembled
|
||||
or al,-1
|
||||
jmp make_if_structure
|
||||
else_directive:
|
||||
cmp [times_working],0
|
||||
jne unexpected_instruction
|
||||
|
|
@ -1085,7 +1117,7 @@ if_directive:
|
|||
jmp remove_structure_data
|
||||
skip_else:
|
||||
or al,al
|
||||
jz unexpected_end_of_file
|
||||
jz missing_end_directive
|
||||
cmp al,0Fh
|
||||
jne extra_characters_on_line
|
||||
call find_end_if
|
||||
|
|
@ -1096,18 +1128,6 @@ if_directive:
|
|||
call find_structure_data
|
||||
jc unexpected_instruction
|
||||
jmp remove_structure_data
|
||||
skip_if:
|
||||
call find_else
|
||||
jc find_structure_end
|
||||
cmp byte [esi],1
|
||||
jne skip_after_else
|
||||
cmp word [esi+1],if_directive-assembler
|
||||
jne skip_after_else
|
||||
add esi,4
|
||||
jmp skip_if
|
||||
skip_after_else:
|
||||
call find_end_if
|
||||
jmp find_structure_end
|
||||
find_else:
|
||||
call find_structure_end
|
||||
cmp ax,else_directive-assembler
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ invalid_file_format:
|
|||
invalid_macro_arguments:
|
||||
call assembler_error
|
||||
dm "invalid macro arguments"
|
||||
incomplete_macro:
|
||||
call assembler_error
|
||||
dm "incomplete macro"
|
||||
unexpected_characters:
|
||||
call assembler_error
|
||||
dm "unexpected characters"
|
||||
|
|
@ -42,9 +45,6 @@ invalid_argument:
|
|||
illegal_instruction:
|
||||
call assembler_error
|
||||
dm "illegal instruction"
|
||||
unexpected_instruction:
|
||||
call assembler_error
|
||||
dm "unexpected instruction"
|
||||
invalid_operand:
|
||||
call assembler_error
|
||||
dm "invalid operand"
|
||||
|
|
@ -96,18 +96,24 @@ reserved_word_used_as_symbol:
|
|||
symbol_already_defined:
|
||||
call assembler_error
|
||||
dm "symbol already defined"
|
||||
setting_already_specified:
|
||||
call assembler_error
|
||||
dm "setting already specified"
|
||||
data_already_defined:
|
||||
call assembler_error
|
||||
dm "data already defined"
|
||||
missing_end_quote:
|
||||
call assembler_error
|
||||
dm "missing end quote"
|
||||
missing_end_directive:
|
||||
call assembler_error
|
||||
dm "missing end directive"
|
||||
unexpected_instruction:
|
||||
call assembler_error
|
||||
dm "unexpected instruction"
|
||||
extra_characters_on_line:
|
||||
call assembler_error
|
||||
dm "extra characters on line"
|
||||
section_not_aligned_enough:
|
||||
call assembler_error
|
||||
dm "section is not aligned enough for this operation"
|
||||
setting_already_specified:
|
||||
call assembler_error
|
||||
dm "setting already specified"
|
||||
data_already_defined:
|
||||
call assembler_error
|
||||
dm "data already defined"
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ formatter:
|
|||
jnz copy_output_path
|
||||
dec edi
|
||||
mov eax,edi
|
||||
dec edi
|
||||
find_extension:
|
||||
dec eax
|
||||
cmp eax,[free_additional_memory]
|
||||
|
|
@ -155,6 +154,8 @@ formatter:
|
|||
format_directive:
|
||||
cmp edi,[code_start]
|
||||
jne unexpected_instruction
|
||||
cmp [virtual_data],0
|
||||
jne unexpected_instruction
|
||||
cmp [output_format],0
|
||||
jne unexpected_instruction
|
||||
lods byte [esi]
|
||||
|
|
@ -1111,6 +1112,8 @@ data_directive:
|
|||
call allocate_structure_data
|
||||
mov word [ebx],data_directive-assembler
|
||||
mov [ebx+2],al
|
||||
mov edx,[current_line]
|
||||
mov [ebx+4],edx
|
||||
call generate_pe_data
|
||||
jmp instruction_assembled
|
||||
end_data:
|
||||
|
|
|
|||
|
|
@ -30,8 +30,10 @@ parser:
|
|||
jb parser_loop
|
||||
xor al,al
|
||||
stos byte [edi]
|
||||
mov eax,[error_line]
|
||||
mov [current_line],eax
|
||||
cmp [anonymous_forward],0
|
||||
jne unexpected_end_of_file
|
||||
jne invalid_value
|
||||
mov [code_start],edi
|
||||
pop [additional_memory_end]
|
||||
ret
|
||||
|
|
@ -755,6 +757,8 @@ get_label_id:
|
|||
mov eax,[anonymous_forward]
|
||||
or eax,eax
|
||||
jnz anonymous_ok
|
||||
mov eax,[current_line]
|
||||
mov [error_line],eax
|
||||
mov eax,[labels_list]
|
||||
sub eax,8
|
||||
mov [labels_list],eax
|
||||
|
|
|
|||
|
|
@ -26,8 +26,10 @@ preprocessor:
|
|||
jc main_file_not_found
|
||||
mov edi,[memory_start]
|
||||
call preprocess_file
|
||||
mov eax,[error_line]
|
||||
mov [current_line],eax
|
||||
cmp [macro_status],0
|
||||
jne unexpected_end_of_file
|
||||
jne incomplete_macro
|
||||
mov [source_start],edi
|
||||
ret
|
||||
|
||||
|
|
@ -764,6 +766,8 @@ process_concatenations:
|
|||
lea esi,[edi+4+eax]
|
||||
jmp before_concatenations
|
||||
concatenation:
|
||||
cmp byte [esi],'#'
|
||||
je reduce_concatenation_symbol
|
||||
cmp dl,1Ah
|
||||
je symbol_concatenation
|
||||
cmp dl,22h
|
||||
|
|
@ -772,6 +776,11 @@ process_concatenations:
|
|||
cmp esi,edi
|
||||
je before_concatenations
|
||||
jmp after_concatenation
|
||||
reduce_concatenation_symbol:
|
||||
movs byte [edi],[esi]
|
||||
cmp byte [esi],'#'
|
||||
je reduce_concatenation_symbol
|
||||
jmp no_concatenation
|
||||
symbol_concatenation:
|
||||
cmp byte [esi],1Ah
|
||||
jne no_concatenation
|
||||
|
|
@ -904,6 +913,8 @@ define_macro:
|
|||
and al,0F0h
|
||||
or al,1
|
||||
mov [macro_status],al
|
||||
mov eax,[current_line]
|
||||
mov [error_line],eax
|
||||
xor bl,bl
|
||||
lods byte [esi]
|
||||
or al,al
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
; flat assembler version 1.54
|
||||
; flat assembler version 1.55
|
||||
; 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.54"
|
||||
VERSION_STRING equ "1.55"
|
||||
|
||||
VERSION_MAJOR = 1
|
||||
VERSION_MINOR = 54
|
||||
VERSION_MINOR = 55
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
|
||||
Visit http://flatassembler.net/ for more information
|
||||
|
||||
version 1.55
|
||||
[12-09-2004]
|
||||
------------
|
||||
[+] support for multiple concatenation symbol added
|
||||
[+] updated documentation (sections concerning preprocessor directives)
|
||||
[+] some error messages improved
|
||||
|
||||
version 1.54
|
||||
[04-08-2004]
|
||||
------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue