From d42cbbd427bbcc1e4c1b9222a0184ec9aa7d5412 Mon Sep 17 00:00:00 2001 From: Tomasz Grysztar Date: Sun, 12 Sep 2004 12:00:00 +0000 Subject: [PATCH] release 1.55 --- FASM.TXT | 91 +++++++++++++++++++++++++++++--- LICENSE.TXT | 2 +- SOURCE/ASSEMBLE.INC | 124 +++++++++++++++++++++++++------------------- SOURCE/ERRORS.INC | 24 +++++---- SOURCE/FORMATS.INC | 5 +- SOURCE/PARSER.INC | 6 ++- SOURCE/PREPROCE.INC | 13 ++++- SOURCE/VERSION.INC | 6 +-- WHATSNEW.TXT | 7 +++ 9 files changed, 203 insertions(+), 75 deletions(-) diff --git a/FASM.TXT b/FASM.TXT index 553b30b..4b6b856 100644 --- a/FASM.TXT +++ b/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 diff --git a/LICENSE.TXT b/LICENSE.TXT index a84359a..ee5b6c4 100644 --- a/LICENSE.TXT +++ b/LICENSE.TXT @@ -1,5 +1,5 @@ -flat assembler version 1.54 +flat assembler version 1.55 Copyright (c) 1999-2004, Tomasz Grysztar. All rights reserved. diff --git a/SOURCE/ASSEMBLE.INC b/SOURCE/ASSEMBLE.INC index 172e6b0..9f9aa42 100644 --- a/SOURCE/ASSEMBLE.INC +++ b/SOURCE/ASSEMBLE.INC @@ -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 diff --git a/SOURCE/ERRORS.INC b/SOURCE/ERRORS.INC index 7a1cc64..74a6365 100644 --- a/SOURCE/ERRORS.INC +++ b/SOURCE/ERRORS.INC @@ -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" diff --git a/SOURCE/FORMATS.INC b/SOURCE/FORMATS.INC index 2f5782f..6ccab4d 100644 --- a/SOURCE/FORMATS.INC +++ b/SOURCE/FORMATS.INC @@ -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: diff --git a/SOURCE/PARSER.INC b/SOURCE/PARSER.INC index ad75229..2c01891 100644 --- a/SOURCE/PARSER.INC +++ b/SOURCE/PARSER.INC @@ -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 diff --git a/SOURCE/PREPROCE.INC b/SOURCE/PREPROCE.INC index c8d2b8a..17bf9dc 100644 --- a/SOURCE/PREPROCE.INC +++ b/SOURCE/PREPROCE.INC @@ -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 diff --git a/SOURCE/VERSION.INC b/SOURCE/VERSION.INC index 3a4c904..81410b4 100644 --- a/SOURCE/VERSION.INC +++ b/SOURCE/VERSION.INC @@ -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 diff --git a/WHATSNEW.TXT b/WHATSNEW.TXT index e6e4a46..de861c6 100644 --- a/WHATSNEW.TXT +++ b/WHATSNEW.TXT @@ -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] ------------