From e9e710ec4b0c7df88a9bbbe9a53bd61440b6b17f Mon Sep 17 00:00:00 2001 From: Tomasz Grysztar Date: Fri, 10 Jan 2003 12:00:00 +0000 Subject: [PATCH] release 1.43 --- FASM.TXT | 68 ++- LICENSE.TXT | 4 +- SOURCE/ASSEMBLE.INC | 112 +++- SOURCE/DOS/FASM.ASM | 48 +- SOURCE/DOS/SYSTEM.INC | 42 +- SOURCE/ERRORS.INC | 34 +- SOURCE/EXPRESSI.INC | 36 +- SOURCE/FORMATS.INC | 1142 +++++++++++++++++++++++++++++++-------- SOURCE/LINUX/FASM.ASM | 34 +- SOURCE/LINUX/SYSTEM.INC | 4 +- SOURCE/PARSER.INC | 100 +++- SOURCE/PREPROCE.INC | 174 ++++-- SOURCE/VERSION.INC | 8 +- SOURCE/WIN32/FASM.ASM | 81 +-- SOURCE/WIN32/SYSTEM.INC | 73 ++- SOURCE/X86.INC | 287 +++++++--- WHATSNEW.TXT | 11 + 17 files changed, 1642 insertions(+), 616 deletions(-) diff --git a/FASM.TXT b/FASM.TXT index 132967d..27d238e 100644 --- a/FASM.TXT +++ b/FASM.TXT @@ -5,7 +5,7 @@ Û ÜßßßßÛ ßßßßÜ Û Û Û Û ßÜÜÜÜÛÜ ÜÜÜÜÜß Û Û Û - flat assembler 1.42 + flat assembler 1.43 Programmer's Manual @@ -64,6 +64,7 @@ Chapter 2 Instruction set 2.4.1 MZ executable 2.4.2 Portable Executable 2.4.3 Common Object File Format + 2.4.4 Executable and Linkable Format Chapter 1 Introduction @@ -445,7 +446,9 @@ for signed 8-bit values. It also can be overridden by putting the "word" or is by default treated as a word value if assembler is in 16-bit mode and as a double word value if assembler is in 32-bit mode, shorter 8-bit form of this instruction is used if possible, "word" or "dword" size operator forces the -"push" instruction to be generated in longer form for specified size. +"push" instruction to be generated in longer form for specified size. "pushw" +and "pushd" mnemonics force assembler to generate 16-bit or 32-bit code +without forcing it to use the longer form of instruction. Chapter 2 Instruction set @@ -468,6 +471,11 @@ the destination operand and second is the source operand. Each operand can be register, memory or immediate value (see 1.2 for details about syntax of operands). After description of each instruction there are provided examples of different combinations of operands (if the instruction has any). + Some instructions act as prefixes and can be followed by other instruction +in the same line, and there can be more than one prefix in a line. Each name +of the segment register is also a mnemonic of instruction prefix, altough it +is recommended to use segment overrides inside the square brackets instead of +these prefixes. 2.1.1 Data movement instructions @@ -508,10 +516,11 @@ the operand to the top of stack indicated by ESP. The operand can be memory, general register, segment register or immediate value of word or double word size. If operand is an immediate value and no size is specified, it is by default treated as a word value if assembler is in 16-bit mode and as a double -word value if assembler is in 32-bit mode. If more operands follow in the same -line (separated only with spaces, not commas), compiler will assemble chain of -the "push" instructions with these operands. The examples are with single -operands: +word value if assembler is in 32-bit mode. "pushw" and "pushd" mnemonics are +variants of this instruction that store the values of word or double word size +respectively. If more operands follow in the same line (separated only with +spaces, not commas), compiler will assemble chain of the "push" instructions +with these operands. The examples are with single operands: push ax ; store general register push es ; store segment register @@ -529,9 +538,11 @@ BP, SI and DI. The 32-bit version pushes equivalent 32-bit general registers in the same order. "pop" transfers the word or double word at the current top of stack to the destination operand, and then increments ESP to point to the new top of stack. -The operand can be memory, general register or segment register. If more -operands separated with spaces follow in the same line, compiler will -assemble chain of the "pop" instructions with these operands. +The operand can be memory, general register or segment register. "popw" and +"popd" mnemonics are variants of this instruction for restoring the values of +word or double word size respectively. If more operands separated with spaces +follow in the same line, compiler will assemble chain of the "pop" +instructions with these operands. pop bx ; restore general register pop ds ; restore segment register @@ -741,8 +752,8 @@ complement. The first operand can be word or double word. and store the index of this bit into destination operand, which must be general register. The bit string being scanned is specified by source operand, it may be either general register or memory. The ZF flag is set if the entire -string is zero (no set bits are found); otherwise it is set. If no set bit is -found, the value of the destination register is undefined. "bsf" scans from +string is zero (no set bits are found); otherwise it is cleared. If no set bit +is found, the value of the destination register is undefined. "bsf" scans from low order to high order (starting from bit index zero). "bsr" scans from high order to low order (starting from bit index 15 of a word or index 31 of a double word). @@ -1507,7 +1518,7 @@ can be also a MMX register or 64-bit memory location. "movd" copies a double word from the source operand to the destination operand. One of the operands must be a MMX register, the second one can be a -general register or 32-bit memory location. Only low double word of MMX +general register or 32-bit memory location. Only lo double word of MMX register is used. All general MMX operations have two operands, the destination operand should be a MMX register, the source operand can be a MMX register or 64-bit memory @@ -1867,7 +1878,7 @@ operand. "cvtpd2dq" and "cvttpd2dq" convert packed double precision floating point values to packed two double word integers, storing the result in the low quad word of the destination operand. "cvtdq2ps" converts packed four double word integers to packed single precision floating point values. -"cvtdq2pd" converts packed two double word integers from the low quad word +"cvtdq2pd" converts packed tw double word integers from the low quad word of the source operand to packed double precision floating point values. For all these instruction destination operand must be a SSE register, the source operand can be a 128-bit memory location or SSE register. @@ -2043,7 +2054,7 @@ logical operators are "~" for logical negation, "&" for logical and, "|" for logical or. The negation has the highest priority. Logical value can be a numerical expression, it will be false if it is equal to zero, otherwise it will be true. Two numerical expression can be compared using one of the -following operators to make the logical value: "=" (equal), "<" (less), +following operators to make the looical value: "=" (equal), "<" (less), ">" (greater), "<=" (less or equal), ">=" (greater or equal), "<>" (not equal). The "eq" compares any two symbol whether they are exactly the same. The "in" operator checks whether given symbol is a member of the @@ -2310,6 +2321,8 @@ needs, the rest of arguments will have empty values. When three operands are given, this macroinstruction will become two macroinstructions of the previous definition, so "mov es,ds,dx" will be assembled as "push ds", "pop es" and "mov ds,dx". + When it's needed to provide macroinstruction with argument that contains +some commas, such argument should be enclosed between "<" and ">" characters. "purge" directive allows removing the last definition of specified macroinstruction. It should be followed by one or more names of macroinstructions, separated with commas. If such macroinstruction has not @@ -2607,9 +2620,30 @@ follow. Available flags are: "code" and "data" for both COFF variants, Microsoft COFF variant. The origin of section is aligned to page (4096 bytes). "extrn" directive defines the external symbol, it should be followed by the name of symbol and optionally the size operator specifying the size of data -labelled by this symbol. +labelled by this symbol. The name of symbol can be also preceded by quoted +string containing name of the external symbol and the "as" operator. "public" directive declares the existing symbol as public, it should be -followed by the name of symbol. +followed by the name of symbol, optionally it can be followed by the "as" +operator and the quoted string containing name under which symbol should be +available as public. -EOF \ No newline at end of file +2.4.4 Executable and Linkable Format + +To select ELF output format, use "format ELF" directive. The default code +setting for this format is 32-bit. + "section" directive defines a new section, it should be followed by quoted +string defining the name of section, then can follow one or both of the +"executable" and "writeable" flags. The origin of section is aligned to +double word (4 bytes). + "extrn" and "public" directives have the same meaning and syntax as when the +COFF output format is selected (described in previous section). + To create executable file, use "format ELF executable" directive. It allows +to use "entry" directive followed by the value to set as entry point of +program. On the other hand it makes "extrn" and "public" directives +unavailable. "section" directive in this case can be followed only by one or +more section flags and its origin is aligned to page (4096 bytes). Available +flags for section are: "readable", "writeable" and "executable". + + +EOF \ No newline at end of file diff --git a/LICENSE.TXT b/LICENSE.TXT index baebfb8..e7a606b 100644 --- a/LICENSE.TXT +++ b/LICENSE.TXT @@ -1,6 +1,6 @@ -flat assembler version 1.42 -Copyright (c) 1999-2002, Tomasz Grysztar. +flat assembler version 1.43 +Copyright (c) 1999-2003, Tomasz Grysztar. All rights reserved. This program is free for commercial and non-commercial use as long as diff --git a/SOURCE/ASSEMBLE.INC b/SOURCE/ASSEMBLE.INC index 18dd73c..b8f1f15 100644 --- a/SOURCE/ASSEMBLE.INC +++ b/SOURCE/ASSEMBLE.INC @@ -1,6 +1,6 @@ -; flat assembler source -; Copyright (c) 1999-2002, Tomasz Grysztar. +; flat assembler core +; Copyright (c) 1999-2003, Tomasz Grysztar. ; All rights reserved. assembler: @@ -11,14 +11,14 @@ assembler: xor eax,eax rep stos dword [edi] mov [stub_size],eax - mov eax,[code_start] - mov [real_code_start],eax - mov [current_pass],0 - mov [number_of_sections],0 - mov [times_working],0 + mov [number_of_sections],eax + mov [current_pass],al + mov [times_working],al assembler_loop: mov eax,[labels_list] mov [display_buffer],eax + mov eax,[additional_memory] + mov [free_additional_memory],eax mov eax,[additional_memory_end] mov [structures_buffer],eax mov [next_pass_needed],0 @@ -26,13 +26,11 @@ assembler: mov [reloc_labels],0 mov [virtual_data],0 mov esi,[source_start] - mov edi,[real_code_start] - xor al,al - xchg [output_format],al - mov [selected_format],al + mov edi,[code_start] + xor eax,eax + mov [output_format],al mov [org_origin],edi mov [org_start],edi - xor eax,eax mov [org_sib],eax mov [error_line],eax mov [counter],eax @@ -135,6 +133,9 @@ assemble_line: new_line: lods dword [esi] mov [current_line],eax + continue_line: + cmp byte [esi],0Fh + je line_assembled jmp assemble_line define_label: lods dword [esi] @@ -166,7 +167,7 @@ assemble_line: mov ebp,[org_sib] xchg [ebx+12],ebp cmp [current_pass],0 - je assemble_line + je continue_line cmp eax,[ebx] jne changed_label cmp edx,[ebx+4] @@ -175,10 +176,18 @@ assemble_line: jne changed_label cmp ch,[ebx+11] jne changed_label - jmp assemble_line + shr ecx,16 + cmp cl,[ebx+10] + je continue_line + mov [ebx+10],cl changed_label: + test byte [ebx+8],8 + jz continue_line + mov al,[current_pass] + cmp al,[ebx+16] + jne continue_line or [next_pass_needed],-1 - jmp assemble_line + jmp continue_line new_label: or byte [ebx+8],1 mov [ebx+9],cl @@ -188,7 +197,7 @@ assemble_line: mov dword [ebx+4],edx mov eax,[org_sib] mov [ebx+12],eax - jmp assemble_line + jmp continue_line define_constant: lods dword [esi] mov edx,[eax+8] @@ -226,37 +235,48 @@ assemble_line: jne value_out_of_range mov edx,[symbol_identifier] make_constant: - mov [ebx+11],cl - mov cl,[current_pass] test byte [ebx+8],1 jz new_constant - cmp cl,[ebx+9] + mov ch,[current_pass] + cmp ch,[ebx+9] jne redefine_constant test byte [ebx+8],2 jz symbol_already_defined or byte [ebx+8],4 redefine_constant: - mov [ebx+9],cl + mov [ebx+9],ch + xchg [ebx+11],cl xchg [ebx],eax xchg [ebx+4],edx cmp [current_pass],0 - je assemble_line + je continue_line cmp eax,[ebx] jne changed_constant cmp edx,[ebx+4] jne changed_constant - jmp assemble_line + cmp cl,[ebx+11] + jne changed_constant + cmp byte [ebx+10],0 + je continue_line + mov byte [ebx+10],0 changed_constant: test byte [ebx+8],4 - jnz assemble_line + jnz continue_line + test byte [ebx+8],8 + jz continue_line + mov al,[current_pass] + cmp al,[ebx+16] + jne continue_line or [next_pass_needed],-1 - jmp assemble_line + jmp continue_line new_constant: or byte [ebx+8],1+2 + mov [ebx+11],cl + mov cl,[current_pass] mov word [ebx+9],cx mov [ebx],eax mov [ebx+4],edx - jmp assemble_line + jmp continue_line assemble_instruction: mov [operand_size],0 mov [forced_size],0 @@ -275,6 +295,7 @@ assemble_line: clc ret source_end: + dec esi stc ret skip_line: @@ -475,8 +496,16 @@ label_directive: jne changed_free_label cmp ch,[ebx+11] jne changed_free_label - jmp instruction_assembled + shr ecx,16 + cmp cl,[ebx+10] + je instruction_assembled + mov [ebx+10],cl changed_free_label: + test byte [ebx+8],8 + jz instruction_assembled + mov al,[current_pass] + cmp al,[ebx+16] + jne instruction_assembled or [next_pass_needed],-1 jmp instruction_assembled new_free_label: @@ -555,8 +584,11 @@ load_directive: je invalid_value call get_relative_offset neg eax + cmp [next_pass_needed],0 + jne load_address_ok cmp [value_type],0 jne invalid_use_of_symbol + load_address_ok: push esi edi mov esi,edi sub esi,eax @@ -644,8 +676,11 @@ times_directive: cmp byte [esi],'.' je invalid_value call get_dword_value + cmp [next_pass_needed],0 + jne times_value_ok cmp [value_type],0 jne invalid_use_of_symbol + times_value_ok: cmp eax,0 je zero_times jl negative_times @@ -659,7 +694,7 @@ times_directive: times_loop: push esi or [times_working],-1 - call assemble_line + call continue_line mov eax,[counter_limit] cmp [counter],eax je times_done @@ -738,7 +773,7 @@ virtual_directive: allocate_structure_data: mov ebx,[structures_buffer] sub ebx,14h - cmp ebx,[additional_memory] + cmp ebx,[free_additional_memory] jb out_of_memory mov [structures_buffer],ebx ret @@ -801,8 +836,11 @@ repeat_directive: cmp byte [esi],'.' je invalid_value call get_dword_value + cmp [next_pass_needed],0 + jne repeat_value_ok cmp [value_type],0 jne invalid_use_of_symbol + repeat_value_ok: cmp eax,0 je zero_repeat jl negative_repeat @@ -1373,8 +1411,11 @@ reserve_bytes: cmp byte [esi],'.' je invalid_value call get_dword_value + cmp [next_pass_needed],0 + jne rb_value_ok cmp [value_type],0 jne invalid_use_of_symbol + rb_value_ok: cmp eax,0 jl reserve_negative mov ecx,eax @@ -1417,8 +1458,11 @@ reserve_words: cmp byte [esi],'.' je invalid_value call get_dword_value + cmp [next_pass_needed],0 + jne rw_value_ok cmp [value_type],0 jne invalid_use_of_symbol + rw_value_ok: cmp eax,0 jl reserve_negative mov ecx,eax @@ -1449,8 +1493,11 @@ reserve_dwords: cmp byte [esi],'.' je invalid_value call get_dword_value + cmp [next_pass_needed],0 + jne rd_value_ok cmp [value_type],0 jne invalid_use_of_symbol + rd_value_ok: cmp eax,0 jl reserve_negative mov ecx,eax @@ -1479,8 +1526,11 @@ reserve_pwords: cmp byte [esi],'.' je invalid_value call get_dword_value + cmp [next_pass_needed],0 + jne rp_value_ok cmp [value_type],0 jne invalid_use_of_symbol + rp_value_ok: cmp eax,0 jl reserve_negative mov ecx,eax @@ -1506,8 +1556,11 @@ reserve_qwords: cmp byte [esi],'.' je invalid_value call get_dword_value + cmp [next_pass_needed],0 + jne rq_value_ok cmp [value_type],0 jne invalid_use_of_symbol + rq_value_ok: cmp eax,0 jl reserve_negative mov ecx,eax @@ -1534,8 +1587,11 @@ reserve_twords: cmp byte [esi],'.' je invalid_value call get_dword_value + cmp [next_pass_needed],0 + jne rt_value_ok cmp [value_type],0 jne invalid_use_of_symbol + rt_value_ok: cmp eax,0 jl reserve_negative mov ecx,eax diff --git a/SOURCE/DOS/FASM.ASM b/SOURCE/DOS/FASM.ASM index 15dd2ad..67fa074 100644 --- a/SOURCE/DOS/FASM.ASM +++ b/SOURCE/DOS/FASM.ASM @@ -1,6 +1,6 @@ -; flat assembler source -; Copyright (c) 1999-2002, Tomasz Grysztar. +; flat assembler interface for DOS +; Copyright (c) 1999-2003, Tomasz Grysztar. ; All rights reserved. org 100h @@ -113,42 +113,6 @@ information: mov al,1 jmp exit_program -get_params: - mov si,81h - mov di,params - find_param: - lodsb - cmp al,20h - je find_param - cmp al,0Dh - je all_params - or al,al - jz all_params - inc di - mov bx,di - copy_param: - stosb - lodsb - cmp al,20h - je param_end - cmp al,0Dh - je param_end - or al,al - jz param_end - jmp copy_param - param_end: - dec si - xor al,al - stosb - mov ax,di - sub ax,bx - mov [bx-1],al - jmp find_param - all_params: - xor al,al - stosb - ret - include 'system.inc' include '..\version.inc' @@ -178,12 +142,12 @@ memory_start dd ? memory_end dd ? additional_memory dd ? additional_memory_end dd ? +free_additional_memory dd ? input_file dd ? output_file dd ? source_start dd ? code_start dd ? code_size dd ? -real_code_start dd ? real_code_size dd ? start_time dd ? written_size dd ? @@ -217,11 +181,11 @@ fp_value rd 8 symbol_identifier dd ? address_symbol dd ? format_flags dd ? +symbols_stream dd ? number_of_relocations dd ? number_of_sections dd ? stub_size dd ? -header_data dd ? -sections_data dd ? +stub_file dd ? current_section dd ? machine dw ? subsystem dw ? @@ -231,7 +195,6 @@ image_base dd ? macro_status db ? parenthesis_stack db ? output_format db ? -selected_format db ? code_type db ? current_pass db ? next_pass_needed db ? @@ -259,6 +222,7 @@ nextbyte db ? characters rb 100h params rb 100h +converted rb 100h buffer rb 1000h rb 400h diff --git a/SOURCE/DOS/SYSTEM.INC b/SOURCE/DOS/SYSTEM.INC index b979f10..e361712 100644 --- a/SOURCE/DOS/SYSTEM.INC +++ b/SOURCE/DOS/SYSTEM.INC @@ -1,6 +1,6 @@ -; flat assembler source -; Copyright (c) 1999-2002, Tomasz Grysztar. +; flat assembler interface for DOS +; Copyright (c) 1999-2003, Tomasz Grysztar. ; All rights reserved. init_flatrm: @@ -246,6 +246,42 @@ exit_program: xms_call dd ? ; XMS driver pointer xms_handle dw ? ; handle of XMS memory block +get_params: + mov si,81h + mov di,params + find_param: + lodsb + cmp al,20h + je find_param + cmp al,0Dh + je all_params + or al,al + jz all_params + inc di + mov bx,di + copy_param: + stosb + lodsb + cmp al,20h + je param_end + cmp al,0Dh + je param_end + or al,al + jz param_end + jmp copy_param + param_end: + dec si + xor al,al + stosb + mov ax,di + sub ax,bx + mov [bx-1],al + jmp find_param + all_params: + xor al,al + stosb + ret + open: push esi di call convert_path @@ -434,7 +470,7 @@ display_block: mov dl,al mov ah,2 int 21h - loop display_block + loopd display_block ret display_number: push ebx diff --git a/SOURCE/ERRORS.INC b/SOURCE/ERRORS.INC index 5175fbc..9e9860f 100644 --- a/SOURCE/ERRORS.INC +++ b/SOURCE/ERRORS.INC @@ -1,6 +1,6 @@ -; flat assembler source -; Copyright (c) 1999-2002, Tomasz Grysztar. +; flat assembler core +; Copyright (c) 1999-2003, Tomasz Grysztar. ; All rights reserved. out_of_memory: @@ -9,12 +9,15 @@ out_of_memory: main_file_not_found: call fatal_error dm "source file not found" -code_cannot_be_generated: - call fatal_error - dm "code cannot be generated" unexpected_end_of_file: call fatal_error dm "unexpected end of file" +code_cannot_be_generated: + call fatal_error + dm "code cannot be generated" +format_limitations_exceeded: + call fatal_error + dm "format limitations exceeded" write_failed: call fatal_error dm "write failed" @@ -57,6 +60,9 @@ invalid_address_size: address_sizes_do_not_agree: call assembler_error dm "address sizes do not agree" +relative_jump_out_of_range: + call assembler_error + dm "relative jump out of range" invalid_expression: call assembler_error dm "invalid expression" @@ -69,15 +75,12 @@ invalid_value: value_out_of_range: call assembler_error dm "value out of range" +undefined_symbol: + call assembler_error + dm "undefined symbol" invalid_use_of_symbol: call assembler_error dm "invalid use of symbol" -relative_jump_out_of_range: - call assembler_error - dm "relative jump out of range" -extra_characters_on_line: - call assembler_error - dm "extra characters on line" name_too_long: call assembler_error dm "name too long" @@ -90,6 +93,15 @@ 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" +extra_characters_on_line: + call assembler_error + dm "extra characters on line" diff --git a/SOURCE/EXPRESSI.INC b/SOURCE/EXPRESSI.INC index c253425..ee269e2 100644 --- a/SOURCE/EXPRESSI.INC +++ b/SOURCE/EXPRESSI.INC @@ -1,6 +1,6 @@ -; flat assembler source -; Copyright (c) 1999-2002, Tomasz Grysztar. +; flat assembler core +; Copyright (c) 1999-2003, Tomasz Grysztar. ; All rights reserved. convert_expression: @@ -905,8 +905,10 @@ calculate_expression: add edi,0Ch jmp calculation_loop get_label: - mov word [edi+8],0 - mov byte [edi+12],0 + xor eax,eax + mov [edi+8],ax + mov [edi+12],al + mov [edi+16],eax lods dword [esi] or eax,eax jz current_offset_label @@ -927,18 +929,12 @@ calculate_expression: cmp al,[ebx+9] jne label_undefined label_defined: + mov edx,[ebx+4] mov al,[ebx+11] - cmp [next_pass_needed],0 - je label_type_ok - cmp [current_pass],0 - jne label_type_ok - xor al,al - label_type_ok: mov [edi+12],al mov eax,[ebx+12] mov [edi+8],eax mov eax,[ebx] - mov edx,[ebx+4] cmp byte [ebx+11],0 je label_value_ok mov [edi+16],edx @@ -992,7 +988,7 @@ calculate_expression: jmp calculation_loop label_undefined: cmp [current_pass],0 - jne invalid_value + jne undefined_symbol or [next_pass_needed],-1 mov byte [edi+12],0 or [value_undefined],-1 @@ -1073,8 +1069,6 @@ calculate_expression: cmp al,ah jne invalid_sub xor ah,ah - cmp [output_format],4 - jne sub_values mov ecx,[edi+16] cmp ecx,[ebx+16] je sub_values @@ -1459,13 +1453,8 @@ calculate_expression: add edi,14h jmp calculation_loop calculate_rva: - cmp [selected_format],3 - je rva_available - cmp [current_pass],0 - jne invalid_use_of_symbol - xor eax,eax - jmp rva_base_ok - rva_available: + cmp [output_format],3 + jne invalid_expression cmp [next_pass_needed],0 jne rva_ok cmp word [edi+8],0 @@ -1474,9 +1463,8 @@ calculate_expression: jne invalid_use_of_symbol rva_ok: mov byte [edi+12],0 - mov eax,[header_data] + mov eax,[code_start] mov eax,[eax+34h] - rva_base_ok: sub [edi],eax sbb dword [edi+4],0 add edi,14h @@ -2087,6 +2075,8 @@ get_logical_value: jz invalid_expression cmp al,0Fh je invalid_expression + cmp al,'<' + je invalid_expression cmp al,'>' je list_return_false cmp al,',' diff --git a/SOURCE/FORMATS.INC b/SOURCE/FORMATS.INC index 649129b..dc4a178 100644 --- a/SOURCE/FORMATS.INC +++ b/SOURCE/FORMATS.INC @@ -1,11 +1,21 @@ -; flat assembler source -; Copyright (c) 1999-2002, Tomasz Grysztar. +; flat assembler core +; Copyright (c) 1999-2003, Tomasz Grysztar. ; All rights reserved. formatter: cmp [output_format],4 je coff_formatter + cmp [output_format],5 + jne common_formatter + bt [format_flags],0 + jnc elf_formatter + common_formatter: + cmp [output_format],3 + jne prepare_code + mov eax,[stub_size] + sub [code_start],eax + prepare_code: mov eax,edi sub eax,[code_start] mov [real_code_size],eax @@ -31,7 +41,7 @@ formatter: call close ret format_directive: - cmp edi,[real_code_start] + cmp edi,[code_start] jne unexpected_instruction cmp [output_format],0 jne unexpected_instruction @@ -42,11 +52,6 @@ format_directive: test al,0F0h jnz complex_format select_format: - cmp [current_pass],0 - je format_ok - cmp al,[selected_format] - jne unexpected_instruction - format_ok: mov [output_format],al cmp al,2 je format_mz @@ -54,6 +59,8 @@ format_directive: je format_pe cmp al,4 je format_coff + cmp al,5 + je format_elf jmp instruction_assembled complex_format: mov bl,al @@ -69,16 +76,20 @@ format_directive: jmp select_format entry_directive: bts [format_flags],1 - jc symbol_already_defined + jc setting_already_specified mov al,[output_format] cmp al,2 je mz_entry cmp al,3 je pe_entry + cmp al,5 + jne illegal_instruction + bt [format_flags],0 + jc elf_entry jmp illegal_instruction stack_directive: bts [format_flags],2 - jc symbol_already_defined + jc setting_already_specified mov al,[output_format] cmp al,2 je mz_stack @@ -87,7 +98,7 @@ stack_directive: jmp illegal_instruction heap_directive: bts [format_flags],3 - jc symbol_already_defined + jc setting_already_specified mov al,[output_format] cmp al,2 je mz_heap @@ -102,7 +113,113 @@ section_directive: je pe_section cmp al,4 je coff_section + cmp al,5 + je elf_section jmp illegal_instruction +public_directive: + mov al,[output_format] + cmp al,4 + je public_allowed + cmp al,5 + jne illegal_instruction + bt [format_flags],0 + jnz illegal_instruction + public_allowed: + lods byte [esi] + cmp al,2 + jne invalid_argument + lods dword [esi] + cmp eax,0Fh + jb invalid_use_of_symbol + je reserved_word_used_as_symbol + inc esi + mov ebx,[free_additional_memory] + lea edx,[ebx+10h] + cmp edx,[structures_buffer] + jae out_of_memory + mov [free_additional_memory],edx + mov [ebx+8],eax + mov eax,[current_line] + mov [ebx+0Ch],eax + lods byte [esi] + cmp al,86h + jne invalid_argument + lods word [esi] + cmp ax,'(' + jne invalid_argument + mov [ebx+4],esi + lods dword [esi] + lea esi,[esi+eax+1] + mov byte [ebx],80h + jmp instruction_assembled +extrn_directive: + mov al,[output_format] + cmp al,4 + je extrn_allowed + cmp al,5 + jne illegal_instruction + bt [format_flags],0 + jnz illegal_instruction + extrn_allowed: + lods word [esi] + cmp ax,'(' + jne invalid_argument + mov ebx,esi + lods dword [esi] + lea esi,[esi+eax+1] + mov edx,[free_additional_memory] + lea eax,[edx+0Ch] + cmp eax,[structures_buffer] + jae out_of_memory + mov [free_additional_memory],eax + mov byte [edx],81h + mov [edx+4],ebx + lods byte [esi] + cmp al,86h + jne invalid_argument + lods byte [esi] + cmp al,2 + jne invalid_argument + lods dword [esi] + cmp eax,0Fh + jb invalid_use_of_symbol + je reserved_word_used_as_symbol + inc esi + mov ebx,eax + xor ah,ah + lods byte [esi] + cmp al,':' + je get_extrn_size + dec esi + cmp al,11h + jne extrn_size_ok + get_extrn_size: + lods word [esi] + cmp al,11h + jne invalid_argument + extrn_size_ok: + mov [ebx+10],ah + movzx eax,ah + mov [edx+8],eax + mov byte [ebx+11],2 + mov cl,[current_pass] + test byte [ebx+8],1 + jz new_extrn + cmp cl,[ebx+9] + je symbol_already_defined + mov [ebx+9],cl + xchg [ebx+4],edx + cmp [current_pass],0 + je instruction_assembled + cmp edx,[ebx+4] + je instruction_assembled + or [next_pass_needed],-1 + jmp instruction_assembled + new_extrn: + or byte [ebx+8],1 + mov [ebx+9],cl + mov dword [ebx+4],edx + jmp instruction_assembled mark_relocation: cmp [value_type],0 je relocation_ok @@ -114,6 +231,8 @@ mark_relocation: je mark_pe_relocation cmp [output_format],4 je mark_coff_relocation + cmp [output_format],5 + je mark_elf_relocation relocation_ok: ret close_pass: @@ -122,17 +241,18 @@ close_pass: je close_pe cmp al,4 je close_coff + cmp al,5 + je close_elf ret format_mz: mov edx,[additional_memory] - mov [header_data],edx push edi mov edi,edx mov ecx,1Ch shr 2 xor eax,eax rep stos dword [edi] - mov [additional_memory],edi + mov [free_additional_memory],edi pop edi mov word [edx+0Ch],0FFFFh mov word [edx+10h],1000h @@ -141,7 +261,7 @@ format_mz: mark_mz_relocation: push eax ebx inc [number_of_relocations] - mov ebx,[additional_memory] + mov ebx,[free_additional_memory] mov eax,edi sub eax,[code_start] mov [ebx],ax @@ -156,7 +276,7 @@ mark_mz_relocation: add ebx,4 cmp ebx,[structures_buffer] jae out_of_memory - mov [additional_memory],ebx + mov [free_additional_memory],ebx pop ebx eax ret segment_directive: @@ -205,8 +325,17 @@ segment_directive: jne changed_segment or edx,edx jnz changed_segment - jmp segment_ok + cmp byte [ebx+11],1 + jne changed_segment + cmp byte [ebx+10],0 + je segment_ok changed_segment: + mov word [ebx+10],0100h + test byte [ebx+8],8 + jz segment_ok + mov al,[current_pass] + cmp al,[ebx+16] + jne segment_ok or [next_pass_needed],-1 jmp segment_ok new_segment: @@ -231,14 +360,11 @@ mz_entry: jne invalid_argument call get_word_value cmp [next_pass_needed],0 - je check_initial_cs - cmp [current_pass],0 - je initial_cs_ok - check_initial_cs: + jne initial_cs_ok cmp [value_type],1 jne invalid_address initial_cs_ok: - mov edx,[header_data] + mov edx,[additional_memory] mov [edx+16h],ax lods byte [esi] cmp al,':' @@ -250,7 +376,7 @@ mz_entry: call get_word_value cmp [value_type],0 jne invalid_use_of_symbol - mov edx,[header_data] + mov edx,[additional_memory] mov [edx+14h],ax jmp instruction_assembled mz_stack: @@ -264,19 +390,16 @@ mz_stack: jb invalid_value cmp [value_type],0 jne invalid_use_of_symbol - mov edx,[header_data] + mov edx,[additional_memory] mov [edx+10h],ax jmp instruction_assembled stack_pointer: cmp [next_pass_needed],0 - je check_initial_ss - cmp [current_pass],0 - je initial_ss_ok - check_initial_ss: + jne initial_ss_ok cmp [value_type],1 jne invalid_address initial_ss_ok: - mov edx,[header_data] + mov edx,[additional_memory] mov [edx+0Eh],ax lods byte [esi] cmp al,':' @@ -287,7 +410,7 @@ mz_stack: call get_word_value cmp [value_type],0 jne invalid_use_of_symbol - mov edx,[header_data] + mov edx,[additional_memory] mov [edx+10h],ax bts [format_flags],4 jmp instruction_assembled @@ -305,11 +428,11 @@ mz_heap: call get_word_value cmp [value_type],0 jne invalid_use_of_symbol - mov edx,[header_data] + mov edx,[additional_memory] mov [edx+0Ch],ax jmp instruction_assembled write_mz_header: - mov edx,[header_data] + mov edx,[additional_memory] bt [format_flags],4 jc mz_stack_ok mov eax,[real_code_size] @@ -322,19 +445,19 @@ write_mz_header: add eax,ecx mov [real_code_size],eax mz_stack_ok: - mov edi,[additional_memory] + mov edi,[free_additional_memory] mov eax,[number_of_relocations] shl eax,2 add eax,1Ch sub edi,eax - xchg edi,[additional_memory] + xchg edi,[free_additional_memory] mov ecx,0Fh add eax,0Fh and eax,1111b sub ecx,eax xor al,al rep stos byte [edi] - sub edi,[additional_memory] + sub edi,[free_additional_memory] mov ecx,edi shr edi,4 mov word [edx],'MZ' ; signature @@ -375,6 +498,7 @@ write_mz_header: ret make_stub: + mov [stub_file],edx or edx,edx jnz stub_from_file push esi @@ -564,11 +688,11 @@ format_pe: cmp al,80h jne pe_settings bts [format_flags],8 - jc symbol_already_defined + jc setting_already_specified jmp pe_settings subsystem_setting: bts [format_flags],7 - jc symbol_already_defined + jc setting_already_specified and ax,3Fh mov [subsystem],ax cmp byte [esi],'(' @@ -585,7 +709,7 @@ format_pe: jmp pe_settings get_pe_base: bts [format_flags],9 - jc symbol_already_defined + jc setting_already_specified lods word [esi] cmp ah,'(' jne invalid_argument @@ -610,15 +734,20 @@ format_pe: add esi,eax inc esi pe_settings_ok: - cmp [current_pass],0 - jne pe_stub_ok + mov eax,[stub_size] + or eax,eax + jz make_pe_stub + cmp edx,[stub_file] + je pe_stub_ok + sub edi,[stub_size] + mov [code_start],edi + make_pe_stub: call make_stub - mov [real_code_start],edi - pe_stub_ok: mov eax,edi sub eax,[code_start] mov [stub_size],eax - mov [header_data],edi + mov [code_start],edi + pe_stub_ok: mov edx,edi imul ecx,[number_of_sections],28h add ecx,18h+0E0h @@ -652,6 +781,7 @@ format_pe: mov word [edx+1Ah],VERSION_MAJOR + VERSION_MINOR shl 8 mov eax,edi sub eax,[code_start] + add eax,[stub_size] mov [edx+54h],eax ; size of headers mov dword [edx+60h],1000h ; stack reserve mov dword [edx+64h],1000h ; stack commit @@ -666,7 +796,6 @@ format_pe: mov [code_type],32 or [reloc_labels],-1 mov [number_of_sections],0 - mov [sections_data],edi lea ebx,[edx+18h+0E0h] mov [current_section],ebx mov dword [ebx],'.fla' @@ -720,7 +849,10 @@ pe_section: call close_pe_section bts [format_flags],5 lea ecx,[ebx+28h] - cmp ecx,[sections_data] + mov edx,[code_start] + add edx,[edx+54h] + sub edx,[stub_size] + cmp ecx,edx jbe new_section sub ebx,28h or [next_pass_needed],-1 @@ -745,7 +877,7 @@ pe_section: mov [code_type],32 mov dword [ebx+24h],0 mov [ebx+14h],edi - mov edx,[header_data] + mov edx,[code_start] mov eax,edi sub eax,[ebx+0Ch] sub eax,[edx+34h] @@ -767,7 +899,7 @@ pe_section: mov ecx,ebx xchg ecx,[edx+78h+eax*8] or ecx,ecx - jnz symbol_already_defined + jnz data_already_defined mov dword [edx+78h+eax*8+4],-1 cmp al,5 jne get_section_flags @@ -778,6 +910,8 @@ pe_section: mov cl,al mov eax,1 shl eax,cl + test dword [ebx+24h],eax + jnz setting_already_specified or dword [ebx+24h],eax jmp get_section_flags close_pe_section: @@ -808,6 +942,7 @@ pe_section: xor al,al rep stos byte [edi] mov eax,[code_start] + sub eax,[stub_size] sub [ebx+14h],eax mov eax,[ebx+8] or eax,eax @@ -824,7 +959,7 @@ pe_section: add ebx,28h mov [current_section],ebx inc word [number_of_sections] - jz illegal_instruction + jz format_limitations_exceeded ret data_directive: cmp [output_format],3 @@ -846,10 +981,10 @@ data_directive: mov ecx,edi sub ecx,[ebx+14h] add ecx,[ebx+0Ch] - mov edx,[header_data] + mov edx,[code_start] xchg ecx,[edx+78h+eax*8] or ecx,ecx - jnz symbol_already_defined + jnz data_already_defined call allocate_structure_data mov word [ebx],data_directive-assembler mov [ebx+2],al @@ -867,7 +1002,7 @@ data_directive: mov ecx,edi sub ecx,[edx+14h] add ecx,[edx+0Ch] - mov edx,[header_data] + mov edx,[code_start] sub ecx,[edx+78h+eax*8] mov [edx+78h+eax*8+4],ecx jmp remove_structure_data @@ -879,14 +1014,11 @@ pe_entry: je invalid_value call get_dword_value cmp [next_pass_needed],0 - je check_pe_entry - cmp [current_pass],0 - je pe_entry_ok - check_pe_entry: + jne pe_entry_ok cmp [value_type],2 jne invalid_address pe_entry_ok: - mov edx,[header_data] + mov edx,[code_start] sub eax,[edx+34h] mov [edx+28h],eax jmp instruction_assembled @@ -899,7 +1031,7 @@ pe_stack: call get_dword_value cmp [value_type],0 jne invalid_use_of_symbol - mov edx,[header_data] + mov edx,[code_start] mov [edx+60h],eax cmp byte [esi],',' jne default_stack_commit @@ -912,7 +1044,7 @@ pe_stack: call get_dword_value cmp [value_type],0 jne invalid_use_of_symbol - mov edx,[header_data] + mov edx,[code_start] mov [edx+64h],eax cmp eax,[edx+60h] ja value_out_of_range @@ -933,7 +1065,7 @@ pe_heap: call get_dword_value cmp [value_type],0 jne invalid_use_of_symbol - mov edx,[header_data] + mov edx,[code_start] mov [edx+68h],eax cmp byte [esi],',' jne default_heap_commit @@ -946,7 +1078,7 @@ pe_heap: call get_dword_value cmp [value_type],0 jne invalid_use_of_symbol - mov edx,[header_data] + mov edx,[code_start] mov [edx+6Ch],eax cmp eax,[edx+68h] ja value_out_of_range @@ -960,25 +1092,25 @@ mark_pe_relocation: mov eax,edi sub eax,[ebx+14h] add eax,[ebx+0Ch] - mov ebx,[additional_memory] + mov ebx,[free_additional_memory] inc [number_of_relocations] jz invalid_use_of_symbol mov [ebx],eax add ebx,4 cmp ebx,[structures_buffer] jae out_of_memory - mov [additional_memory],ebx + mov [free_additional_memory],ebx pop ebx eax ret make_pe_fixups: push ebx edx esi mov ecx,[number_of_relocations] jecxz fixups_done - mov esi,[additional_memory] + mov esi,[free_additional_memory] mov eax,ecx shl eax,2 sub esi,eax - mov [additional_memory],esi + mov [free_additional_memory],esi or [number_of_relocations],-1 mov edx,1000h mov ebp,edi @@ -1014,21 +1146,31 @@ make_pe_fixups: ret close_pe: call close_pe_section - mov edx,[header_data] + mov edx,[code_start] mov [edx+50h],eax call make_timestamp - mov edx,[header_data] + mov edx,[code_start] mov [edx+8],eax mov eax,[number_of_relocations] cmp eax,0 jle pe_flags_ok or word [edx+16h],1 shl eax,2 - sub [additional_memory],eax + sub [free_additional_memory],eax pe_flags_ok: + xor ecx,ecx mov eax,[number_of_sections] mov [edx+6],ax - xor ecx,ecx + imul eax,28h + add eax,18h+0E0h + add eax,[stub_size] + dec eax + shr eax,9 + inc eax + shl eax,9 + cmp eax,[edx+54h] + je process_directories + or [next_pass_needed],-1 process_directories: mov eax,[edx+78h+ecx*8] or eax,eax @@ -1049,14 +1191,14 @@ close_pe: format_coff: mov eax,[additional_memory] - mov [sections_data],eax + mov [symbols_stream],eax mov ebx,eax add eax,14h cmp eax,[structures_buffer] jae out_of_memory - mov [additional_memory],eax + mov [free_additional_memory],eax xor eax,eax - mov [ebx],eax + mov [ebx],al mov [ebx+4],eax mov [ebx+8],edi mov eax,60h @@ -1066,17 +1208,20 @@ format_coff: flat_section_flags_ok: mov dword [ebx+10h],eax mov [current_section],ebx - mov [number_of_sections],1 + mov [number_of_sections],0 + mov [org_origin],edi + mov [org_sib],0 + mov [org_start],edi mov [code_type],32 or [reloc_labels],-1 jmp instruction_assembled coff_section: call close_coff_section - mov ebx,[additional_memory] + mov ebx,[free_additional_memory] lea eax,[ebx+14h] cmp eax,[structures_buffer] jae out_of_memory - mov [additional_memory],eax + mov [free_additional_memory],eax mov [current_section],ebx inc [number_of_sections] xor eax,eax @@ -1108,6 +1253,8 @@ coff_section: mov cl,al mov eax,1 shl eax,cl + test dword [ebx+10h],eax + jnz setting_already_specified or dword [ebx+10h],eax jmp coff_section_flags close_coff_section: @@ -1123,103 +1270,16 @@ coff_section: cmp edx,[undefined_data_start] jne coff_section_ok mov edi,edx - or dword [ebx+10h],80h + or byte [ebx+10h],80h coff_section_ok: ret -public_directive: - cmp [output_format],4 - jne illegal_instruction - lods word [esi] - cmp ax,'(' - jne invalid_argument - mov edx,esi - lods dword [esi] - lea esi,[esi+eax+1] - mov ebx,[additional_memory] - lea eax,[ebx+10h] - cmp eax,[structures_buffer] - jae out_of_memory - mov [additional_memory],eax - mov byte [ebx],2 - mov [ebx+4],edx - lods byte [esi] - cmp al,2 - jne invalid_argument - lods dword [esi] - cmp eax,0Fh - jb invalid_use_of_symbol - je reserved_word_used_as_symbol - inc esi - mov [ebx+8],eax - mov eax,[current_line] - mov [ebx+0Ch],eax - jmp instruction_assembled -extrn_directive: - cmp [output_format],4 - jne illegal_instruction - lods word [esi] - cmp ax,'(' - jne invalid_argument - mov ebx,esi - lods dword [esi] - lea esi,[esi+eax+1] - mov edx,[additional_memory] - lea eax,[edx+0Ch] - cmp eax,[structures_buffer] - jae out_of_memory - mov [additional_memory],eax - mov byte [edx],1 - mov [edx+4],ebx - lods byte [esi] - cmp al,2 - jne invalid_argument - lods dword [esi] - cmp eax,0Fh - jb invalid_use_of_symbol - je reserved_word_used_as_symbol - inc esi - mov ebx,eax - xor ah,ah - lods byte [esi] - cmp al,':' - je get_extrn_size - dec esi - cmp al,11h - jne extrn_size_ok - get_extrn_size: - lods word [esi] - cmp al,11h - jne invalid_argument - extrn_size_ok: - mov [ebx+10],ah - movzx eax,ah - mov [edx+8],eax - mov byte [ebx+11],2 - mov cl,[current_pass] - test byte [ebx+8],1 - jz new_extrn - cmp cl,[ebx+9] - je symbol_already_defined - mov [ebx+9],cl - xchg [ebx+4],edx - cmp [current_pass],0 - je instruction_assembled - cmp edx,[ebx+4] - je instruction_assembled - or [next_pass_needed],-1 - jmp instruction_assembled - new_extrn: - or byte [ebx+8],1 - mov [ebx+9],cl - mov dword [ebx+4],edx - jmp instruction_assembled mark_coff_relocation: cmp [value_type],3 - je relative + je coff_relocation_relative push ebx eax mov al,6 jmp coff_relocation - relative: + coff_relocation_relative: cmp [reloc_labels],-1 jne invalid_use_of_symbol push ebx @@ -1234,11 +1294,11 @@ mark_coff_relocation: push eax mov al,20 coff_relocation: - mov ebx,[additional_memory] + mov ebx,[free_additional_memory] add ebx,0Ch cmp ebx,[structures_buffer] jae out_of_memory - mov [additional_memory],ebx + mov [free_additional_memory],ebx mov byte [ebx-0Ch],al mov eax,edi sub eax,[org_origin] @@ -1251,25 +1311,16 @@ close_coff: call close_coff_section cmp [next_pass_needed],0 je coff_closed - mov eax,[sections_data] - mov [additional_memory],eax + mov eax,[symbols_stream] + mov [free_additional_memory],eax coff_closed: ret coff_formatter: sub edi,[code_start] mov [code_size],edi - mov ebx,[sections_data] - cmp dword [ebx+0Ch],0 - jne sections_count_ok - cmp [number_of_sections],1 - je sections_count_ok - add ebx,14h - mov [sections_data],ebx - dec [number_of_sections] - sections_count_ok: - mov edi,[additional_memory] + call prepare_default_section + mov edi,[free_additional_memory] mov ebx,edi - mov [header_data],edi mov ecx,28h shr 2 imul ecx,[number_of_sections] add ecx,14h shr 2 @@ -1278,7 +1329,6 @@ coff_formatter: jae out_of_memory xor eax,eax rep stos dword [edi] - mov [additional_memory],edi mov word [ebx],14Ch mov word [ebx+12h],104h bt [format_flags],0 @@ -1291,18 +1341,17 @@ coff_formatter: mov [ebx+4],eax mov eax,[number_of_sections] mov [ebx+2],ax - mov esi,[sections_data] + mov esi,[symbols_stream] xor ecx,ecx enumerate_symbols: - cmp esi,[header_data] + cmp esi,[free_additional_memory] je symbols_enumerated mov dl,[esi] or dl,dl jz enumerate_section - cmp dl,1 - je enumerate_extrn - cmp dl,2 + cmp dl,80h je enumerate_public + ja enumerate_extrn add esi,0Ch jmp enumerate_symbols enumerate_section: @@ -1312,37 +1361,78 @@ coff_formatter: inc ecx add esi,14h jmp enumerate_symbols - enumerate_extrn: - mov edx,eax - shl edx,8 - mov dl,1 - mov [esi],edx - inc eax - add esi,0Ch - jmp enumerate_symbols enumerate_public: mov edx,eax shl edx,8 - mov dl,2 + mov dl,80h mov [esi],edx inc eax add esi,10h jmp enumerate_symbols + enumerate_extrn: + mov edx,eax + shl edx,8 + mov dl,81h + mov [esi],edx + inc eax + add esi,0Ch + jmp enumerate_symbols + prepare_default_section: + mov ebx,[symbols_stream] + cmp dword [ebx+0Ch],0 + jne default_section_ok + cmp [number_of_sections],0 + je default_section_ok + mov edx,ebx + find_references_to_default_section: + cmp ebx,[free_additional_memory] + jne check_reference + add [symbols_stream],14h + ret + check_reference: + mov al,[ebx] + or al,al + jz skip_other_section + cmp al,80h + je check_public_reference + ja next_reference + cmp edx,[ebx+8] + je default_section_ok + next_reference: + add ebx,0Ch + jmp find_references_to_default_section + check_public_reference: + mov eax,[ebx+8] + add ebx,10h + test byte [eax+8],1 + jz find_references_to_default_section + mov cl,[current_pass] + cmp cl,[eax+9] + jne find_references_to_default_section + cmp edx,[eax+4] + je default_section_ok + jmp find_references_to_default_section + skip_other_section: + add ebx,14h + jmp find_references_to_default_section + default_section_ok: + inc [number_of_sections] + ret symbols_enumerated: mov [ebx+0Ch],eax - mov ebp,[additional_memory] - sub ebp,[header_data] - mov edi,[header_data] - add edi,14h - mov esi,[sections_data] + mov ebp,edi + sub ebp,ebx + push ebp + lea edi,[ebx+14h] + mov esi,[symbols_stream] find_section: - cmp esi,[header_data] + cmp esi,[free_additional_memory] je sections_finished mov al,[esi] or al,al jz section_found add esi,0Ch - cmp al,2 + cmp al,80h jne find_section add esi,4 jmp find_section @@ -1380,14 +1470,14 @@ coff_formatter: xor ecx,ecx add esi,14h find_relocations: - cmp esi,[header_data] + cmp esi,[free_additional_memory] je section_relocations_done mov al,[esi] or al,al jz section_relocations_done - cmp al,2 - ja add_relocation - jb next_relocation + cmp al,80h + jb add_relocation + ja next_relocation add esi,10h jmp find_relocations add_relocation: @@ -1409,7 +1499,7 @@ coff_formatter: jmp find_relocations section_relocations_done: cmp ecx,10000h - jae out_of_memory ; not honest, it's a COFF limitation + jae format_limitations_exceeded mov [edi+20h],cx jcxz section_relocations_ok mov [edi+18h],edx @@ -1419,7 +1509,7 @@ coff_formatter: add edi,28h jmp find_section sections_finished: - mov edx,[header_data] + mov edx,[free_additional_memory] mov ebx,[code_size] add ebp,ebx mov [edx+8],ebp @@ -1435,15 +1525,15 @@ coff_formatter: rep stos dword [edi] mov edx,edi stos dword [edi] - mov esi,[sections_data] + mov esi,[symbols_stream] make_section_symbols: - cmp esi,[header_data] + cmp esi,[free_additional_memory] je section_symbols_ok mov al,[esi] or al,al jz add_section_symbol add esi,0Ch - cmp al,2 + cmp al,80h jne make_section_symbols add esi,4 jmp make_section_symbols @@ -1458,15 +1548,14 @@ coff_formatter: add ebx,12h jmp make_section_symbols section_symbols_ok: - mov esi,[sections_data] + mov esi,[symbols_stream] make_symbols_table: - cmp esi,[header_data] + cmp esi,[free_additional_memory] je symbols_table_ok mov al,[esi] - cmp al,1 - je add_extrn_symbol - cmp al,2 + cmp al,80h je add_public_symbol + ja add_extrn_symbol add esi,0Ch or al,al jnz make_symbols_table @@ -1483,6 +1572,11 @@ coff_formatter: mov eax,[esi+0Ch] mov [current_line],eax mov eax,[esi+8] + test byte [eax+8],1 + jz undefined_symbol + mov cl,[current_pass] + cmp cl,[eax+9] + jne undefined_symbol mov cl,[eax+11] or cl,cl jz public_constant @@ -1504,11 +1598,12 @@ coff_formatter: jmp make_symbols_table public_constant: mov word [ebx+0Ch],0FFFFh - mov ecx,[eax] - shr ecx,31 - neg ecx - cmp ecx,[eax+4] + cmp dword [eax+4],0 + je store_public_symbol + cmp dword [eax+4],-1 jne value_out_of_range + bt dword [eax],31 + jnc value_out_of_range jmp store_public_symbol symbols_table_ok: mov eax,edi @@ -1520,9 +1615,8 @@ coff_formatter: mov edx,[output_file] call create jc write_failed - mov edx,[header_data] - mov ecx,[additional_memory] - sub ecx,edx + mov edx,[free_additional_memory] + pop ecx add [written_size],ecx call write jc write_failed @@ -1561,6 +1655,611 @@ coff_formatter: pop esi ret +format_elf: + mov edx,edi + mov ecx,34h shr 2 + lea eax,[edi+ecx*4] + cmp eax,[display_buffer] + jae out_of_memory + xor eax,eax + rep stos dword [edi] + mov dword [edx],7Fh + 'ELF' shl 8 + mov al,1 + mov [edx+4],al + mov [edx+5],al + mov [edx+6],al + mov [edx+14h],al + mov byte [edx+12h],3 + mov byte [edx+28h],34h + mov [code_type],32 + cmp word [esi],1D19h + je format_elf_exe + mov byte [edx+10h],1 + mov byte [edx+2Eh],28h + mov eax,[additional_memory] + mov [symbols_stream],eax + mov ebx,eax + add eax,14h + cmp eax,[structures_buffer] + jae out_of_memory + mov [free_additional_memory],eax + xor eax,eax + mov [ebx],al + mov [ebx+4],eax + mov [ebx+8],edi + mov dword [ebx+10h],111b + mov [current_section],ebx + mov [number_of_sections],0 + mov [org_origin],edi + mov [org_sib],0 + mov [org_start],edi + mov [code_type],32 + or [reloc_labels],-1 + jmp instruction_assembled +elf_section: + bt [format_flags],0 + jc elf_exe_section + call close_coff_section + mov ebx,[free_additional_memory] + lea eax,[ebx+14h] + cmp eax,[structures_buffer] + jae out_of_memory + mov [free_additional_memory],eax + mov [current_section],ebx + inc word [number_of_sections] + jz format_limitations_exceeded + 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 al,10b + mov [ebx+10h],eax + lods word [esi] + cmp ax,'(' + jne invalid_argument + mov [ebx+4],esi + mov ecx,[esi] + lea esi,[esi+4+ecx+1] + elf_section_flags: + cmp byte [esi],19h + jne instruction_assembled + inc esi + lods byte [esi] + sub al,28 + xor al,11b + test al,not 10b + jnz invalid_argument + mov cl,al + mov al,1 + shl al,cl + test byte [ebx+10h],al + jnz setting_already_specified + or byte [ebx+10h],al + jmp elf_section_flags +mark_elf_relocation: + cmp [value_type],3 + je elf_relocation_relative + push ebx eax + mov al,1 + jmp coff_relocation + elf_relocation_relative: + cmp [reloc_labels],-1 + jne invalid_use_of_symbol + push ebx + mov ebx,[current_section] + mov ebx,[ebx+8] + sub ebx,edi + sub eax,ebx + push eax + mov al,2 + jmp coff_relocation +close_elf: + bt [format_flags],0 + jc close_elf_exe + call close_coff_section + cmp [next_pass_needed],0 + je elf_closed + mov eax,[symbols_stream] + mov [free_additional_memory],eax + elf_closed: + ret +elf_formatter: + push edi + call prepare_default_section + mov edi,[free_additional_memory] + xor eax,eax + mov ecx,4 + rep stos dword [edi] + mov esi,[symbols_stream] + find_first_section: + mov al,[esi] + or al,al + jz first_section_found + cmp al,80h + jne skip_other_symbol + add esi,4 + skip_other_symbol: + add esi,0Ch + jmp find_first_section + first_section_found: + mov ebx,esi + mov ebp,esi + add esi,14h + xor ecx,ecx + xor edx,edx + find_next_section: + cmp esi,[free_additional_memory] + je make_section_symbol + mov al,[esi] + or al,al + jz make_section_symbol + cmp al,80h + je skip_public + ja skip_extrn + or byte [ebx+10h],40h + skip_extrn: + add esi,0Ch + jmp find_next_section + skip_public: + add esi,10h + jmp find_next_section + make_section_symbol: + mov eax,edi + xchg eax,[ebx+4] + stos dword [edi] + xor eax,eax + stos dword [edi] + stos dword [edi] + inc ecx + mov eax,ecx + shl eax,8 + mov [ebx],eax + inc dx + jz format_limitations_exceeded + mov eax,edx + shl eax,16 + mov al,3 + test byte [ebx+10h],40h + jz section_symbol_ok + or ah,-1 + inc dx + jz format_limitations_exceeded + section_symbol_ok: + stos dword [edi] + mov ebx,esi + add esi,14h + cmp ebx,[free_additional_memory] + jne find_next_section + inc dx + jz format_limitations_exceeded + mov [current_section],edx + mov esi,[symbols_stream] + find_other_symbols: + cmp esi,[free_additional_memory] + je elf_symbol_table_ok + mov al,[esi] + or al,al + jz skip_section + cmp al,80h + je make_public_symbol + ja make_extrn_symbol + add esi,0Ch + jmp find_other_symbols + skip_section: + add esi,14h + jmp find_other_symbols + make_public_symbol: + mov eax,[esi+0Ch] + mov [current_line],eax + mov ebx,[esi+8] + test byte [ebx+8],1 + jz undefined_symbol + mov al,[current_pass] + cmp al,[ebx+9] + jne undefined_symbol + mov al,[ebx+11] + or al,al + jz public_absolute + cmp al,2 + jne invalid_use_of_symbol + mov eax,[ebx+4] + cmp byte [eax],0 + jne invalid_use_of_symbol + mov eax,[eax+4] + mov dx,[eax+0Eh] + jmp section_for_public_ok + public_absolute: + mov dx,0FFF1h + cmp dword [ebx+4],0 + je section_for_public_ok + cmp dword [ebx+4],-1 + jne value_out_of_range + bt dword [ebx],31 + jnc value_out_of_range + section_for_public_ok: + mov eax,[esi+4] + stos dword [edi] + mov eax,[ebx] + stos dword [edi] + xor eax,eax + mov al,[ebx+10] + stos dword [edi] + mov eax,edx + shl eax,16 + mov al,10h + stos dword [edi] + inc ecx + mov eax,ecx + shl eax,8 + mov al,80h + mov [esi],eax + add esi,10h + jmp find_other_symbols + make_extrn_symbol: + mov eax,[esi+4] + stos dword [edi] + xor eax,eax + stos dword [edi] + mov eax,[esi+8] + stos dword [edi] + mov eax,10h + stos dword [edi] + inc ecx + mov eax,ecx + shl eax,8 + mov al,81h + mov [esi],eax + add esi,0Ch + jmp find_other_symbols + elf_symbol_table_ok: + mov edx,edi + mov ebx,[free_additional_memory] + add ebx,10h + xor al,al + stos byte [edi] + add edi,16 + mov [edx+1],edx + make_string_table: + cmp ebx,edx + je elf_string_table_ok + cmp byte [ebx+0Dh],0 + je rel_prefix_ok + mov byte [ebx+0Dh],0 + mov eax,'.rel' + stos dword [edi] + rel_prefix_ok: + mov esi,edi + sub esi,edx + xchg esi,[ebx] + add ebx,10h + or esi,esi + jz default_string + lods dword [esi] + mov ecx,eax + rep movs byte [edi],[esi] + xor al,al + stos byte [edi] + jmp make_string_table + default_string: + mov eax,'.fla' + stos dword [edi] + mov ax,'t' + stos word [edi] + jmp make_string_table + elf_string_table_ok: + mov [edx+1+8],edi + mov ebx,[code_start] + mov eax,[current_section] + inc ax + jz format_limitations_exceeded + mov [ebx+32h],ax + inc ax + jz format_limitations_exceeded + mov [ebx+30h],ax + mov eax,edi + sub eax,[free_additional_memory] + mov [ebx+20h],eax + xor eax,eax + mov ecx,10 + rep stos dword [edi] + mov esi,ebp + xor ecx,ecx + make_section_entry: + mov ebx,edi + mov eax,[esi+4] + mov eax,[eax] + stos dword [edi] + mov eax,1 + cmp dword [esi+0Ch],0 + je bss_section + test byte [esi+10h],80h + jz section_type_ok + bss_section: + mov al,8 + section_type_ok: + stos dword [edi] + mov eax,[esi+10h] + and al,3Fh + stos dword [edi] + xor eax,eax + stos dword [edi] + mov eax,[esi+8] + sub eax,[code_start] + stos dword [edi] + mov eax,[esi+0Ch] + stos dword [edi] + xor eax,eax + stos dword [edi] + stos dword [edi] + mov al,4 + stos dword [edi] + xor al,al + stos dword [edi] + inc ecx + add esi,14h + xchg edi,[esp] + mov ebp,edi + convert_relocations: + cmp esi,[free_additional_memory] + je relocations_converted + mov al,[esi] + or al,al + jz relocations_converted + cmp al,80h + jb make_relocation_entry + ja relocation_entry_ok + add esi,10h + jmp convert_relocations + make_relocation_entry: + mov eax,[esi+4] + stos dword [edi] + mov eax,[esi+8] + mov eax,[eax] + mov al,[esi] + stos dword [edi] + relocation_entry_ok: + add esi,0Ch + jmp convert_relocations + relocations_converted: + cmp edi,ebp + xchg edi,[esp] + je rel_section_ok + mov eax,[ebx] + sub eax,4 + stos dword [edi] + mov eax,9 + stos dword [edi] + xor al,al + stos dword [edi] + stos dword [edi] + mov eax,ebp + sub eax,[code_start] + stos dword [edi] + mov eax,[esp] + sub eax,ebp + stos dword [edi] + mov eax,[current_section] + stos dword [edi] + mov eax,ecx + stos dword [edi] + mov eax,4 + stos dword [edi] + mov al,8 + stos dword [edi] + inc ecx + rel_section_ok: + cmp esi,[free_additional_memory] + jne make_section_entry + pop eax + mov ebx,[code_start] + sub eax,ebx + mov [code_size],eax + add [ebx+20h],eax + mov eax,1 + stos dword [edi] + mov al,2 + stos dword [edi] + xor al,al + stos dword [edi] + stos dword [edi] + mov eax,[code_size] + stos dword [edi] + mov eax,[edx+1] + sub eax,[free_additional_memory] + stos dword [edi] + mov eax,[current_section] + inc eax + stos dword [edi] + mov eax,[number_of_sections] + inc eax + stos dword [edi] + mov eax,4 + stos dword [edi] + mov al,10h + stos dword [edi] + mov al,1+8 + stos dword [edi] + mov al,3 + stos dword [edi] + xor al,al + stos dword [edi] + stos dword [edi] + mov eax,[edx+1] + sub eax,[free_additional_memory] + add eax,[code_size] + stos dword [edi] + mov eax,[edx+1+8] + sub eax,[edx+1] + stos dword [edi] + xor eax,eax + stos dword [edi] + stos dword [edi] + mov al,1 + stos dword [edi] + xor eax,eax + stos dword [edi] + mov eax,'tab' + mov dword [edx+1],'.sym' + mov [edx+1+4],eax + mov dword [edx+1+8],'.str' + mov [edx+1+8+4],eax + mov [written_size],0 + mov edx,[output_file] + call create + jc write_failed + mov edx,[code_start] + mov ecx,[code_size] + add [written_size],ecx + call write + jc write_failed + mov ecx,edi + mov edx,[free_additional_memory] + sub ecx,edx + add [written_size],ecx + call write + jc write_failed + call close + ret + +format_elf_exe: + add esi,2 + or [format_flags],1 + mov byte [edx+10h],2 + mov byte [edx+2Ah],20h + push edi + mov edi,[additional_memory] + mov ebx,edi + mov ecx,20h shr 2 + lea eax,[edi+ecx*4] + cmp eax,[structures_buffer] + ja out_of_memory + xor eax,eax + rep stos dword [edi] + mov [free_additional_memory],edi + pop edi + mov [number_of_sections],1 + mov byte [ebx],1 + mov word [ebx+1Ch],1000h + mov byte [ebx+18h],111b + mov eax,34h + mov [ebx+4],eax + add eax,8048000h + mov [ebx+8],eax + mov [ebx+0Ch],eax + mov [edx+18h],eax + neg eax + add eax,edi + mov [org_origin],eax + mov [org_sib],0 + mov [org_start],edi + jmp instruction_assembled +elf_entry: + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + call get_dword_value + cmp [value_type],0 + jne invalid_use_of_symbol + mov edx,[code_start] + mov [edx+18h],eax + jmp instruction_assembled +elf_exe_section: + call close_elf_exe_section + push edi + mov edi,[free_additional_memory] + mov ebx,edi + mov ecx,20h shr 2 + lea eax,[edi+ecx*4] + cmp eax,[structures_buffer] + ja out_of_memory + xor eax,eax + rep stos dword [edi] + mov [free_additional_memory],edi + pop edi + inc [number_of_sections] + mov byte [ebx],1 + mov word [ebx+1Ch],1000h + elf_exe_section_flags: + cmp byte [esi],19h + jne elf_exe_section_flags_ok + lods word [esi] + sub ah,28 + jbe invalid_argument + cmp ah,1 + je mark_elf_exe_section_flag + cmp ah,3 + ja invalid_argument + xor ah,1 + cmp ah,2 + je mark_elf_exe_section_flag + inc ah + mark_elf_exe_section_flag: + test [ebx+18h],ah + jnz setting_already_specified + or [ebx+18h],ah + jmp elf_exe_section_flags + elf_exe_section_flags_ok: + mov eax,edi + sub eax,[code_start] + mov [ebx+4],eax + mov eax,edi + sub eax,[org_origin] + shrd edx,eax,12 + add eax,0FFFh + shr eax,12 + shld eax,edx,12 + mov [ebx+8],eax + mov [ebx+0Ch],eax + neg eax + add eax,edi + mov [org_origin],eax + mov [org_sib],0 + mov [org_start],edi + jmp instruction_assembled + close_elf_exe_section: + mov ebx,[number_of_sections] + dec ebx + shl ebx,5 + add ebx,[additional_memory] + mov eax,edi + sub eax,[code_start] + sub eax,[ebx+4] + mov edx,edi + cmp edi,[undefined_data_end] + jne elf_exe_section_size_ok + mov edi,[undefined_data_start] + elf_exe_section_size_ok: + sub edx,edi + mov [ebx+14h],eax + sub eax,edx + mov [ebx+10h],eax + ret +close_elf_exe: + call close_elf_exe_section + mov esi,[additional_memory] + mov ecx,[number_of_sections] + cmp dword [esi+14h],0 + jne make_elf_program_header + add esi,20h + dec ecx + make_elf_program_header: + mov eax,edi + mov edx,[code_start] + sub eax,edx + mov [edx+1Ch],eax + mov [edx+2Ch],cx + shl ecx,5-2 + lea eax,[edi+ecx*4] + cmp eax,[display_buffer] + ja out_of_memory + rep movs dword [edi],[esi] + ret + formatter_symbols: db 6,'binary',18h,1 db 4,'code',19h,5 @@ -1569,6 +2268,7 @@ formatter_symbols: db 4,'data',19h,6 db 11,'discardable',19h,25 db 3,'dll',1Bh,80h + db 3,'elf',18h,5 db 10,'executable',19h,29 db 6,'export',1Ah,0 db 6,'fixups',1Ah,5 diff --git a/SOURCE/LINUX/FASM.ASM b/SOURCE/LINUX/FASM.ASM index 9d63d45..6412779 100644 --- a/SOURCE/LINUX/FASM.ASM +++ b/SOURCE/LINUX/FASM.ASM @@ -1,27 +1,13 @@ -; flat assembler source -; Copyright (c) 1999-2002, Tomasz Grysztar. +; flat assembler interface for Linux +; Copyright (c) 1999-2003, Tomasz Grysztar. ; All rights reserved. - program_base = 0x8048000 - - org program_base - use32 + format ELF executable + entry start macro align value { rb (value-1) - ($ + value-1) mod value } -file_header: - db 0x7F,'ELF',1,1,1,3 - rb file_header+0x10-$ - dw 2,3 - dd 1,start - dd program_header-file_header,0,0 - dw program_header-file_header,0x20,1,0,0,0 - -program_header: - dd 1,0,program_base,0 - dd bss-program_base,program_end-program_base,7,0x1000 - start: mov esi,_logo @@ -148,21 +134,19 @@ _bytes_suffix db ' bytes.',0xA,0 _counter db 8,'00000000' -bss: - align 4 memory_start dd ? memory_end dd ? additional_memory dd ? additional_memory_end dd ? +free_additional_memory dd ? input_file dd ? output_file dd ? environment dd ? source_start dd ? code_start dd ? code_size dd ? -real_code_start dd ? real_code_size dd ? start_time dd ? written_size dd ? @@ -196,11 +180,11 @@ fp_value rd 8 symbol_identifier dd ? address_symbol dd ? format_flags dd ? +symbols_stream dd ? number_of_relocations dd ? number_of_sections dd ? stub_size dd ? -header_data dd ? -sections_data dd ? +stub_file dd ? current_section dd ? machine dw ? subsystem dw ? @@ -210,7 +194,6 @@ image_base dd ? macro_status db ? parenthesis_stack db ? output_format db ? -selected_format db ? code_type db ? current_pass db ? next_pass_needed db ? @@ -237,6 +220,5 @@ mmx_prefix db ? nextbyte db ? characters rb 100h +converted rb 100h buffer rb 1000h - -program_end: diff --git a/SOURCE/LINUX/SYSTEM.INC b/SOURCE/LINUX/SYSTEM.INC index 73bcc9b..59e2ed9 100644 --- a/SOURCE/LINUX/SYSTEM.INC +++ b/SOURCE/LINUX/SYSTEM.INC @@ -1,6 +1,6 @@ -; flat assembler source -; Copyright (c) 1999-2002, Tomasz Grysztar. +; flat assembler interface for Linux +; Copyright (c) 1999-2003, Tomasz Grysztar. ; All rights reserved. O_ACCMODE = 00003 diff --git a/SOURCE/PARSER.INC b/SOURCE/PARSER.INC index 5c0fd4e..3d3a2c0 100644 --- a/SOURCE/PARSER.INC +++ b/SOURCE/PARSER.INC @@ -1,18 +1,19 @@ -; flat assembler source -; Copyright (c) 1999-2002, Tomasz Grysztar. +; flat assembler core +; Copyright (c) 1999-2003, Tomasz Grysztar. ; All rights reserved. parser: mov eax,[memory_end] mov [labels_list],eax + mov eax,[additional_memory] + mov [free_additional_memory],eax 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] parser_loop: mov [current_line],esi cmp edi,[labels_list] @@ -29,7 +30,6 @@ parser: stos byte [edi] cmp [anonymous_forward],0 jne unexpected_end_of_file - pop [additional_memory] mov eax,[code_start] mov [source_start],eax mov [code_start],edi @@ -182,7 +182,7 @@ parse_line: cmp bx,segment_directive-assembler je parse_label_directive cmp bx,extrn_directive-assembler - je parse_public_directive + je parse_extrn_directive cmp bx,public_directive-assembler je parse_public_directive parse_arguments: @@ -217,6 +217,8 @@ parse_line: je unallowed_character cmp al,'#' je unallowed_character + cmp al,'`' + je unallowed_character dec esi cmp al,1Ah jne expression_argument @@ -259,7 +261,42 @@ parse_line: jmp argument_parsed parse_public_directive: cmp byte [esi],1Ah - jne invalid_argument + jne parse_arguments + inc esi + push esi + movzx ecx,byte [esi] + lods byte [esi] + mov al,2 + stos byte [edi] + call get_label_id + stos dword [edi] + mov ax,8600h + stos word [edi] + pop ebx + push ebx esi edi + mov edi,directive_operators + call get_operator + pop edi edx ebx + cmp al,86h + je argument_parsed + mov esi,edx + xchg esi,ebx + movzx ecx,byte [esi] + inc esi + mov ax,'(' + stos word [edi] + mov eax,ecx + stos dword [edi] + rep movs byte [edi],[esi] + xor al,al + stos byte [edi] + xchg esi,ebx + jmp argument_parsed + parse_extrn_directive: + cmp byte [esi],22h + je parse_quoted_extrn + cmp byte [esi],1Ah + jne parse_arguments push esi movzx ecx,byte [esi+1] add esi,2 @@ -268,17 +305,15 @@ parse_line: mov eax,ecx stos dword [edi] rep movs byte [edi],[esi] - xor al,al - stos byte [edi] + mov ax,8600h + stos word [edi] pop esi parse_label_operator: cmp byte [esi],1Ah jne argument_parsed - push edi inc esi movzx ecx,byte [esi] lods byte [esi] - pop edi mov al,2 stos byte [edi] call get_label_id @@ -286,6 +321,26 @@ parse_line: xor al,al stos byte [edi] jmp argument_parsed + parse_quoted_extrn: + inc esi + mov ax,'(' + stos word [edi] + lods dword [esi] + mov ecx,eax + stos dword [edi] + rep movs byte [edi],[esi] + xor al,al + stos byte [edi] + push esi edi + mov edi,directive_operators + call get_operator + mov edx,esi + pop edi esi + cmp al,86h + jne argument_parsed + stos byte [edi] + mov esi,edx + jmp parse_label_operator ptr_argument: call parse_address mov al,']' @@ -518,7 +573,7 @@ get_operator: call lower_case pop edi check_operator: - mov esi,buffer + mov esi,converted movzx ecx,byte [edi] jecxz no_operator inc edi @@ -545,6 +600,8 @@ get_operator: ret simple_operator: mov al,[esi] + cmp al,22h + je no_simple_operator simple_check_operator: cmp byte [edi],1 jb no_simple_operator @@ -567,7 +624,7 @@ get_symbol: call lower_case pop edi scan_symbols: - mov esi,buffer + mov esi,converted movzx eax,byte [edi] or al,al jz no_symbol @@ -611,7 +668,7 @@ get_instruction: movzx edi,word [instructions+ecx*2] add edi,instructions scan_instructions: - mov esi,buffer + mov esi,converted mov al,[edi] or al,al jz no_instruction @@ -631,7 +688,7 @@ get_instruction: stc ret lower_case: - mov edi,buffer + mov edi,converted mov ebx,characters convert_case: lods byte [esi] @@ -660,7 +717,7 @@ get_label_id: je standard_label push edi push ecx esi - mov edi,[additional_memory] + mov edi,[free_additional_memory] xor al,al stos byte [edi] mov esi,[current_locals_prefix] @@ -678,7 +735,7 @@ get_label_id: cmp ebp,[additional_memory_end] jae out_of_memory rep movs byte [edi],[esi] - mov [additional_memory],edi + mov [free_additional_memory],edi pop edi push esi movzx ecx,al @@ -758,11 +815,16 @@ get_label_id: xor ebp,ebp hash_label: movzx eax,byte [esi+ebx] + rol ebp,12 + mov edx,ebp + shr ebp,8 + and edx,1111b + or ebp,edx add ebp,eax inc bl cmp bl,cl jb hash_label - shl ebx,20 + shl ebx,24 or ebp,ebx mov [label_hash],ebp push edi @@ -833,9 +895,6 @@ get_label_id: pop edi ret -symbol_characters db 26 - db 9,0Ah,0Dh,1Ah,20h,'+-/*:=|&~()[]<>{},;\#' - operators: db 1,'+',80h db 1,'-',81h @@ -857,6 +916,7 @@ single_operand_operators: db 0 directive_operators: + db 2,'as',86h db 2,'at',80h db 7,'defined',88h db 2,'eq',81h diff --git a/SOURCE/PREPROCE.INC b/SOURCE/PREPROCE.INC index 12273d9..7a97148 100644 --- a/SOURCE/PREPROCE.INC +++ b/SOURCE/PREPROCE.INC @@ -1,13 +1,13 @@ -; flat assembler source -; Copyright (c) 1999-2002, Tomasz Grysztar. +; flat assembler core +; Copyright (c) 1999-2003, Tomasz Grysztar. ; All rights reserved. preprocessor: mov eax,[memory_start] mov [source_start],eax - push [additional_memory] mov eax,[additional_memory] + mov [free_additional_memory],eax mov [macros_list],eax mov eax,[additional_memory_end] mov [labels_list],eax @@ -19,7 +19,6 @@ preprocessor: jc main_file_not_found cmp [macro_status],0 jne unexpected_end_of_file - pop [additional_memory] mov [code_start],edi ret @@ -78,8 +77,8 @@ preprocess_file: convert_line: push ecx - cmp [macro_status],0 - jle convert_line_data + test [macro_status],0Fh + jz convert_line_data mov ax,3Bh stos word [edi] convert_line_data: @@ -246,13 +245,14 @@ preprocess_line: push ecx esi mov esi,[current_line] add esi,12 - test [macro_status],0C0h + test [macro_status],0F0h jz concatenations_ok call process_concatenations mov esi,[current_line] add esi,12 concatenations_ok: mov al,[macro_status] + and al,0Fh dec al jz find_macro_block dec al @@ -318,7 +318,7 @@ preprocess_line: get_macro: mov edx,esi mov ebp,edi - mov ebx,[additional_memory] + mov ebx,[free_additional_memory] check_macro: mov cl,al cmp ebx,[macros_list] @@ -443,6 +443,8 @@ process_concatenations: je first_concatenation cmp al,1Ah je symbol_before_concatenations + cmp al,3Bh + je symbol_before_concatenations xor dl,dl cmp al,22h je string_before_concatenations @@ -529,7 +531,7 @@ define_symbolic_constant: pop ebx mov edx,[labels_list] sub edx,16 - cmp edx,[additional_memory] + cmp edx,[free_additional_memory] jb out_of_memory mov [labels_list],edx mov ecx,edi @@ -585,13 +587,13 @@ define_macro: cmp al,1Ah jne invalid_name lods byte [esi] - mov ebx,[additional_memory] + mov ebx,[free_additional_memory] mov [ebx],ax mov [ebx+4],esi add ebx,8 cmp ebx,[labels_list] jae out_of_memory - mov [additional_memory],ebx + mov [free_additional_memory],ebx movzx eax,al add esi,eax mov [macro_status],1 @@ -640,7 +642,7 @@ define_macro: cmp al,'{' jne unexpected_characters found_macro_block: - mov ebx,[additional_memory] + mov ebx,[free_additional_memory] sub ebx,8 mov eax,[ebx+4] mov ebx,[current_line] @@ -692,13 +694,13 @@ use_macro: push [macro_constants] [macro_block] [macro_block_line_number] push [counter] [counter_limit] push dword [macro_status] - or [macro_status],80h + or [macro_status],10h or byte [ebx+1],80h mov edx,esi movzx esi,byte [ebx] add esi,[ebx+4] push edi - mov edi,[additional_memory] + mov edi,[memory_end] mov [macro_constants],edi mov [counter],0 process_macro_arguments: @@ -713,6 +715,9 @@ use_macro: inc esi inc [counter] get_macro_argument: + sub edi,16 + cmp edi,[esp] + jb out_of_memory movzx eax,byte [esi] inc esi mov [edi+4],esi @@ -723,6 +728,49 @@ use_macro: mov [edi],eax xchg esi,edx mov [edi+12],esi + cmp byte [esi],'<' + jne get_argument_value + inc esi + mov [edi+12],esi + mov ecx,1 + enclosed_argument: + lods byte [esi] + or al,al + jz invalid_macro_arguments + cmp al,'#' + je invalid_macro_arguments + cmp al,1Ah + je enclosed_symbol + cmp al,22h + je enclosed_string + cmp al,'>' + je enclosed_argument_end + cmp al,'<' + jne enclosed_argument + inc ecx + jmp enclosed_argument + enclosed_symbol: + movzx eax,byte [esi] + inc esi + add esi,eax + jmp enclosed_argument + enclosed_string: + lods dword [esi] + add esi,eax + jmp enclosed_argument + enclosed_argument_end: + loop enclosed_argument + mov al,[esi] + or al,al + jz enclosed_argument_ok + cmp al,',' + jne invalid_macro_arguments + enclosed_argument_ok: + mov eax,esi + sub eax,[edi+12] + dec eax + mov [edi+8],eax + jmp argument_value_ok get_argument_value: lods byte [esi] or al,al @@ -748,10 +796,8 @@ use_macro: mov eax,esi sub eax,[edi+12] mov [edi+8],eax + argument_value_ok: xchg esi,edx - add edi,16 - cmp edi,[labels_list] - jae out_of_memory lods byte [esi] cmp al,',' je next_argument @@ -785,7 +831,7 @@ use_macro: macro_instructions_start: cmp byte [edx],0 jne invalid_macro_arguments - mov [additional_memory],edi + mov [memory_end],edi pop edi mov ecx,80000000h push [current_line] @@ -806,8 +852,12 @@ use_macro: stos dword [edi] mov eax,[esp] stos dword [edi] - or [macro_status],40h + or [macro_status],20h push ebx ecx + test [macro_status],0Fh + jz process_macro + mov ax,3Bh + stos word [edi] process_macro: lods byte [esi] cmp al,'}' @@ -816,7 +866,7 @@ use_macro: jz macro_line_processed cmp al,1Ah je process_macro_symbol - and [macro_status],not 40h + and [macro_status],not 20h stos byte [edi] cmp al,22h jne process_macro @@ -827,7 +877,7 @@ use_macro: jmp process_macro process_macro_symbol: push esi edi - test [macro_status],40h + test [macro_status],20h jz not_macro_directive movzx ecx,byte [esi] inc esi @@ -845,7 +895,7 @@ use_macro: pop ecx ebx jmp near edx not_macro_directive: - and [macro_status],not 40h + and [macro_status],not 20h mov eax,[counter] or eax,eax jnz check_for_macro_constant @@ -858,20 +908,19 @@ use_macro: mov edx,[macro_constants] mov ebx,esi scan_macro_constants: - cmp edx,[additional_memory] + cmp edx,[memory_end] je not_macro_constant + sub edx,16 cmp eax,[edx] je try_macro_constant cmp ebp,[edx] - jne next_macro_constant + jne scan_macro_constants try_macro_constant: mov ecx,ebp mov edi,[edx+4] repe cmps byte [esi],[edi] je macro_constant_found mov esi,ebx - next_macro_constant: - add edx,16 jmp scan_macro_constants macro_constant_found: cmp [counter],0 @@ -941,55 +990,61 @@ use_macro: lods byte [esi] cmp al,1Ah jne invalid_argument - push edi ecx + mov byte [edi-1],3Bh + xor al,al + stos byte [edi] + make_local_symbol: + push ecx movzx ecx,byte [esi] inc esi - mov edx,[additional_memory] + mov edx,[memory_end] + sub edx,16 + cmp edx,edi + jb out_of_memory + mov [memory_end],edx mov eax,[counter] shl eax,8 mov al,cl mov [edx],eax mov [edx+4],esi - movzx eax,[_counter] - mov edi,[memory_end] - sub edi,eax - sub edi,ecx - sub edi,3 - mov [memory_end],edi mov [edx+12],edi - add al,cl - jc name_too_long - inc al - jz name_too_long - mov byte [edi],1Ah - inc edi - mov [edi],al - inc edi - add eax,2 - mov [edx+8],eax - add edx,16 - cmp edx,[labels_list] + movzx eax,[_counter] + add eax,ecx + inc eax + cmp eax,100h + jae name_too_long + lea ebp,[edi+2+eax] + cmp ebp,[memory_end] jae out_of_memory - mov [additional_memory],edx + mov ah,al + mov al,1Ah + stos word [edi] rep movs byte [edi],[esi] mov al,'?' stos byte [edi] - movzx ecx,byte [_counter] push esi mov esi,_counter+1 + movzx ecx,[_counter] rep movs byte [edi],[esi] pop esi - pop ecx edi - cmp edi,[memory_end] - jae out_of_memory + mov eax,edi + sub eax,[edx+12] + mov [edx+8],eax + pop ecx + xor al,al + stos byte [edi] lods byte [esi] - cmp al,',' - je local_symbols cmp al,'}' je macro_block_processed or al,al - jnz extra_characters_on_line - jmp process_next_line + jz process_next_line + cmp al,',' + jne extra_characters_on_line + dec edi + lods byte [esi] + cmp al,1Ah + je make_local_symbol + jmp invalid_argument common_block: call close_macro_block jc process_macro_line @@ -1043,9 +1098,11 @@ use_macro: and byte [ebx+1],not 80h pop [current_line] mov eax,[macro_constants] - mov [additional_memory],eax + mov [memory_end],eax pop eax - mov [macro_status],al + and al,0F0h + and [macro_status],0Fh + or [macro_status],al pop [counter_limit] [counter] pop [macro_block_line_number] [macro_block] [macro_constants] mov esi,[struc_name] @@ -1117,6 +1174,9 @@ increase_counter: clc ret +symbol_characters db 26 + db 9,0Ah,0Dh,1Ah,20h,'+-/*:=|&~()[]<>{},;\#' + preprocessor_directives: db 7,'include' dw include_file-preprocessor diff --git a/SOURCE/VERSION.INC b/SOURCE/VERSION.INC index e4c0baf..f2f17df 100644 --- a/SOURCE/VERSION.INC +++ b/SOURCE/VERSION.INC @@ -1,6 +1,6 @@ -; flat assembler version 1.42 -; Copyright (c) 1999-2002, Tomasz Grysztar. +; flat assembler version 1.43 +; Copyright (c) 1999-2003, Tomasz Grysztar. ; All rights reserved. ; ; This programs is free for commercial and non-commercial use as long as @@ -33,7 +33,7 @@ ; cannot simply be copied and put under another distribution licence ; (including the GNU Public Licence). -VERSION_STRING equ "1.42" +VERSION_STRING equ "1.43" VERSION_MAJOR = 1 -VERSION_MINOR = 42 +VERSION_MINOR = 43 diff --git a/SOURCE/WIN32/FASM.ASM b/SOURCE/WIN32/FASM.ASM index 97bb1cc..5e28da5 100644 --- a/SOURCE/WIN32/FASM.ASM +++ b/SOURCE/WIN32/FASM.ASM @@ -1,6 +1,6 @@ -; flat assembler source -; Copyright (c) 1999-2002, Tomasz Grysztar. +; flat assembler interface for Win32 +; Copyright (c) 1999-2003, Tomasz Grysztar. ; All rights reserved. format PE console on '..\dos\fasm.com' @@ -95,75 +95,6 @@ information: mov al,1 jmp exit_program -get_params: - call [GetCommandLine] - mov esi,eax - mov edi,params - find_command_start: - lodsb - cmp al,20h - je find_command_start - cmp al,22h - je skip_quoted_name - skip_name: - lodsb - cmp al,20h - je find_param - or al,al - jz all_params - jmp skip_name - skip_quoted_name: - lodsb - cmp al,22h - je find_param - or al,al - jz all_params - jmp skip_quoted_name - find_param: - lodsb - cmp al,20h - je find_param - cmp al,22h - je string_param - cmp al,0Dh - je all_params - or al,al - jz all_params - inc edi - mov ebx,edi - copy_param: - stosb - lodsb - cmp al,20h - je param_end - or al,al - jz param_end - jmp copy_param - string_param: - inc edi - mov ebx,edi - copy_string_param: - lodsb - cmp al,22h - je string_param_end - or al,al - jz param_end - stosb - jmp copy_string_param - param_end: - dec esi - string_param_end: - xor al,al - stosb - mov eax,edi - sub eax,ebx - mov [ebx-1],al - jmp find_param - all_params: - xor al,al - stosb - ret - include 'system.inc' include '..\version.inc' @@ -192,12 +123,12 @@ memory_start dd ? memory_end dd ? additional_memory dd ? additional_memory_end dd ? +free_additional_memory dd ? input_file dd ? output_file dd ? source_start dd ? code_start dd ? code_size dd ? -real_code_start dd ? real_code_size dd ? start_time dd ? written_size dd ? @@ -207,6 +138,7 @@ macros_list dd ? macro_constants dd ? macro_block dd ? macro_block_line_number dd ? +macro_embed_level dd ? struc_name dd ? anonymous_reverse dd ? anonymous_forward dd ? @@ -231,10 +163,11 @@ fp_value rd 8 symbol_identifier dd ? address_symbol dd ? format_flags dd ? +symbols_stream dd ? number_of_relocations dd ? number_of_sections dd ? stub_size dd ? -header_data dd ? +stub_file dd ? sections_data dd ? current_section dd ? machine dw ? @@ -245,7 +178,6 @@ image_base dd ? macro_status db ? parenthesis_stack db ? output_format db ? -selected_format db ? code_type db ? current_pass db ? next_pass_needed db ? @@ -273,6 +205,7 @@ nextbyte db ? characters rb 100h params rb 1000h +converted rb 100h buffer rb 4000h stack 4000h,4000h diff --git a/SOURCE/WIN32/SYSTEM.INC b/SOURCE/WIN32/SYSTEM.INC index 50e3b08..4d1e719 100644 --- a/SOURCE/WIN32/SYSTEM.INC +++ b/SOURCE/WIN32/SYSTEM.INC @@ -1,6 +1,6 @@ -; flat assembler source -; Copyright (c) 1999-2002, Tomasz Grysztar. +; flat assembler interface for Win32 +; Copyright (c) 1999-2003, Tomasz Grysztar. ; All rights reserved. CREATE_NEW = 1 @@ -73,6 +73,75 @@ exit_program: push eax call [ExitProcess] +get_params: + call [GetCommandLine] + mov esi,eax + mov edi,params + find_command_start: + lodsb + cmp al,20h + je find_command_start + cmp al,22h + je skip_quoted_name + skip_name: + lodsb + cmp al,20h + je find_param + or al,al + jz all_params + jmp skip_name + skip_quoted_name: + lodsb + cmp al,22h + je find_param + or al,al + jz all_params + jmp skip_quoted_name + find_param: + lodsb + cmp al,20h + je find_param + cmp al,22h + je string_param + cmp al,0Dh + je all_params + or al,al + jz all_params + inc edi + mov ebx,edi + copy_param: + stosb + lodsb + cmp al,20h + je param_end + or al,al + jz param_end + jmp copy_param + string_param: + inc edi + mov ebx,edi + copy_string_param: + lodsb + cmp al,22h + je string_param_end + or al,al + jz param_end + stosb + jmp copy_string_param + param_end: + dec esi + string_param_end: + xor al,al + stosb + mov eax,edi + sub eax,ebx + mov [ebx-1],al + jmp find_param + all_params: + xor al,al + stosb + ret + open: call convert_path push 0 diff --git a/SOURCE/X86.INC b/SOURCE/X86.INC index cf9668b..a8d03a7 100644 --- a/SOURCE/X86.INC +++ b/SOURCE/X86.INC @@ -1,6 +1,6 @@ -; flat assembler source -; Copyright (c) 1999-2002, Tomasz Grysztar. +; flat assembler core +; Copyright (c) 1999-2003, Tomasz Grysztar. ; All rights reserved. simple_instruction: @@ -28,7 +28,7 @@ simple_extended_instruction: jmp instruction_assembled prefix_instruction: stos byte [edi] - jmp assemble_line + jmp continue_line segment_prefix: mov ah,al shr ah,4 @@ -37,7 +37,7 @@ segment_prefix: and al,1111b mov [segment_register],al call store_segment_prefix - jmp assemble_line + jmp continue_line int_instruction: lods byte [esi] call get_size_operator @@ -1320,6 +1320,8 @@ xchg_instruction: stos byte [edi] jmp instruction_assembled push_instruction: + mov [extended_code],al + push_next: lods byte [esi] call get_size_operator cmp al,10h @@ -1331,23 +1333,32 @@ push_instruction: push_mem: call get_address mov al,[operand_size] + mov ah,[extended_code] cmp al,2 je push_mem_16bit cmp al,4 je push_mem_32bit or al,al jnz invalid_operand_size + cmp ah,2 + je push_mem_16bit + cmp ah,4 + je push_mem_32bit cmp [current_pass],0 jne operand_size_not_specified cmp [next_pass_needed],0 je operand_size_not_specified push_mem_16bit: + cmp ah,4 + je invalid_operand_size call operand_16bit_prefix mov [base_code],0FFh mov [postbyte_register],110b call store_instruction jmp push_done push_mem_32bit: + cmp ah,2 + je invalid_operand_size call operand_32bit_prefix mov [base_code],0FFh mov [postbyte_register],110b @@ -1361,36 +1372,50 @@ push_instruction: mov dl,al add dl,50h mov al,ah + mov ah,[extended_code] cmp al,2 je push_reg_16bit cmp al,4 je push_reg_32bit jmp invalid_operand_size push_reg_16bit: + cmp ah,4 + je invalid_operand_size call operand_16bit_prefix mov al,dl stos byte [edi] jmp push_done push_reg_32bit: + cmp ah,2 + je invalid_operand_size call operand_32bit_prefix mov al,dl stos byte [edi] jmp push_done push_sreg: mov bl,[operand_size] + mov bh,[extended_code] cmp bl,4 je push_sreg32 cmp bl,2 je push_sreg16 or bl,bl - jz push_sreg_store - jmp invalid_operand_size + jnz invalid_operand_size + cmp bh,4 + je push_sreg32 + cmp bh,2 + je push_sreg16 + jmp push_sreg_store push_sreg16: + cmp bh,4 + je invalid_operand_size mov bl,al call operand_16bit_prefix mov al,bl jmp push_sreg_store push_sreg32: + cmp bh,2 + je invalid_operand_size mov bl,al call operand_32bit_prefix mov al,bl @@ -1414,10 +1439,22 @@ push_instruction: jmp push_done push_imm: mov al,[operand_size] + mov ah,[extended_code] + or al,al + je push_imm_size_ok + or ah,ah + je push_imm_size_ok + cmp al,ah + jne invalid_operand_size + push_imm_size_ok: cmp al,2 je push_imm_16bit cmp al,4 je push_imm_32bit + cmp ah,2 + je push_imm_optimized_16bit + cmp ah,4 + je push_imm_optimized_32bit or al,al jnz invalid_operand_size cmp [code_type],16 @@ -1431,6 +1468,7 @@ push_instruction: jl push_imm_32bit_forced cmp eax,80h jge push_imm_32bit_forced + call operand_32bit_prefix push_imm_8bit: mov ah,al mov al,6Ah @@ -1445,6 +1483,7 @@ push_instruction: jl push_imm_16bit_forced cmp ax,80h jge push_imm_16bit_forced + call operand_16bit_prefix jmp push_imm_8bit push_imm_16bit: call get_word_value @@ -1476,8 +1515,10 @@ push_instruction: jz instruction_assembled mov [operand_size],0 mov [forced_size],0 - jmp push_instruction + jmp push_next pop_instruction: + mov [extended_code],al + pop_next: lods byte [esi] call get_size_operator cmp al,10h @@ -1487,23 +1528,32 @@ pop_instruction: pop_mem: call get_address mov al,[operand_size] + mov ah,[extended_code] cmp al,2 je pop_mem_16bit cmp al,4 je pop_mem_32bit or al,al jnz invalid_operand_size + cmp ah,2 + je pop_mem_16bit + cmp ah,4 + je pop_mem_32bit cmp [current_pass],0 jne operand_size_not_specified cmp [next_pass_needed],0 je operand_size_not_specified pop_mem_16bit: + cmp ah,4 + je invalid_operand_size call operand_16bit_prefix mov [base_code],08Fh mov [postbyte_register],0 call store_instruction jmp pop_done pop_mem_32bit: + cmp ah,2 + je invalid_operand_size call operand_32bit_prefix mov [base_code],08Fh mov [postbyte_register],0 @@ -1517,36 +1567,50 @@ pop_instruction: mov dl,al add dl,58h mov al,ah + mov ah,[extended_code] cmp al,2 je pop_reg_16bit cmp al,4 je pop_reg_32bit jmp invalid_operand_size pop_reg_16bit: + cmp ah,4 + je invalid_operand_size call operand_16bit_prefix mov al,dl stos byte [edi] jmp pop_done pop_reg_32bit: + cmp ah,2 + je invalid_operand_size call operand_32bit_prefix mov al,dl stos byte [edi] jmp pop_done pop_sreg: mov bl,[operand_size] + mov bh,[extended_code] cmp bl,4 je pop_sreg32 cmp bl,2 je pop_sreg16 or bl,bl - jz pop_sreg_store - jmp invalid_operand_size + jnz invalid_operand_size + cmp bh,4 + je pop_sreg32 + cmp bh,2 + je pop_sreg16 + jmp pop_sreg_store pop_sreg16: + cmp bh,4 + je invalid_operand_size mov bl,al call operand_16bit_prefix mov al,bl jmp pop_sreg_store pop_sreg32: + cmp bh,2 + je invalid_operand_size mov bl,al call operand_32bit_prefix mov al,bl @@ -1578,7 +1642,7 @@ pop_instruction: jz instruction_assembled mov [operand_size],0 mov [forced_size],0 - jmp pop_instruction + jmp pop_next inc_instruction: mov [base_code],al lods byte [esi] @@ -1793,8 +1857,11 @@ ret_instruction: cmp al,'(' jne invalid_operand call get_word_value + cmp [next_pass_needed],0 + jne ret_imm_ok cmp [value_type],0 jne invalid_use_of_symbol + ret_imm_ok: mov dx,ax mov al,[base_code] stos byte [edi] @@ -1904,8 +1971,11 @@ enter_instruction: cmp al,'(' jne invalid_operand call get_word_value + cmp [next_pass_needed],0 + jne enter_imm16_ok cmp [value_type],0 jne invalid_use_of_symbol + enter_imm16_ok: push eax mov [operand_size],0 lods byte [esi] @@ -3431,9 +3501,12 @@ conditional_jump: je invalid_value call get_relative_offset sub eax,2 + cmp [next_pass_needed],0 + jne conditional_jump_value_ok cmp [value_type],1 je invalid_use_of_symbol ja conditional_jump_32bit + conditional_jump_value_ok: mov bl,[operand_size] cmp bl,1 je conditional_jump_8bit @@ -3520,8 +3593,11 @@ loop_instruction: cmp byte [esi],'.' je invalid_value call get_relative_offset + cmp [next_pass_needed],0 + jne loop_value_ok cmp [value_type],0 jne invalid_use_of_symbol + loop_value_ok: mov bl,[operand_size] cmp bl,1 je loop_8bit @@ -3678,9 +3754,12 @@ jmp_instruction: cmp [jump_type],2 je invalid_operand sub eax,2 + cmp [next_pass_needed],0 + jne jmp_value_ok cmp [value_type],1 je invalid_use_of_symbol ja jmp_32bit + jmp_value_ok: mov bl,[operand_size] cmp bl,1 je jmp_8bit @@ -4133,14 +4212,8 @@ basic_fpu_instruction: call store_instruction jmp instruction_assembled basic_fpu_streg: - cmp [operand_size],0 - jne invalid_operand lods byte [esi] - mov ah,al - shr ah,4 - cmp ah,0Ah - jne invalid_operand - and al,111b + call convert_fpu_register mov ah,[postbyte_register] cmp ah,2 je basic_fpu_single_streg @@ -4159,11 +4232,13 @@ basic_fpu_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] - cmp al,0A0h - jne invalid_operand + call convert_fpu_register + or al,al + jnz invalid_operand mov ah,[postbyte_register] or ah,11000000b mov al,0DCh @@ -4174,14 +4249,11 @@ basic_fpu_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] - mov ah,al - shr ah,4 - cmp ah,0Ah - jne invalid_operand - and al,111b + call convert_fpu_register mov ah,[postbyte_register] shl ah,3 or ah,al @@ -4272,14 +4344,8 @@ fld_instruction: call store_instruction jmp instruction_assembled fld_streg: - cmp [operand_size],0 - jne invalid_operand lods byte [esi] - mov ah,al - shr ah,4 - cmp ah,0Ah - jne invalid_operand - and al,111b + call convert_fpu_register mov ah,[postbyte_register] shl ah,3 or ah,al @@ -4353,10 +4419,12 @@ fbld_instruction: jmp instruction_assembled faddp_instruction: mov [postbyte_register],al + mov ebx,esi lods byte [esi] + call get_size_operator cmp al,10h je faddp_streg - dec esi + mov esi,ebx mov ah,[postbyte_register] shl ah,3 or ah,11000001b @@ -4365,11 +4433,7 @@ faddp_instruction: jmp instruction_assembled faddp_streg: lods byte [esi] - mov ah,al - shr ah,4 - cmp ah,0Ah - jne invalid_operand - and al,111b + call convert_fpu_register mov ah,[postbyte_register] shl ah,3 or al,ah @@ -4378,11 +4442,13 @@ faddp_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] - cmp al,0A0h - jne invalid_operand + call convert_fpu_register + or al,al + jnz invalid_operand mov ah,[postbyte_register] or ah,11000000b mov al,0DEh @@ -4397,34 +4463,35 @@ fucompp_instruction: stos word [edi] jmp instruction_assembled fxch_instruction: - mov bx,01D9h + mov dx,01D9h + jmp fpu_single_operand +ffreep_instruction: + mov dx,00DFh jmp fpu_single_operand ffree_instruction: - mov bl,0DDh - mov bh,al + mov dl,0DDh + mov dh,al fpu_single_operand: + mov ebx,esi lods byte [esi] + call get_size_operator cmp al,10h je fpu_streg - or bh,bh + or dh,dh jz invalid_operand - dec esi - shl bh,3 - or bh,11000001b - mov ax,bx + mov esi,ebx + shl dh,3 + or dh,11000001b + mov ax,dx stos word [edi] jmp instruction_assembled fpu_streg: lods byte [esi] - mov ah,al - shr ah,4 - cmp ah,0Ah - jne invalid_operand - and al,111b - shl bh,3 - or bh,al - or bh,11000000b - mov ax,bx + call convert_fpu_register + shl dh,3 + or dh,al + or dh,11000000b + mov ax,dx stos word [edi] jmp instruction_assembled fstenv_instruction: @@ -4493,7 +4560,8 @@ fnstsw_instruction: jmp instruction_assembled fstsw_reg: lods byte [esi] - cmp al,20h + call convert_register + cmp ax,0200h jne invalid_operand mov ax,0E0DFh stos word [edi] @@ -4517,14 +4585,12 @@ fcomip_instruction: fcomi_streg: mov dl,al lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] + call convert_fpu_register mov ah,al - shr al,4 - cmp al,0Ah - jne invalid_operand - and ah,111b cmp byte [esi],',' je fcomi_st0_streg add ah,dl @@ -4536,14 +4602,12 @@ fcomip_instruction: jnz invalid_operand inc esi lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] + call convert_fpu_register mov ah,al - shr al,4 - cmp al,0Ah - jne invalid_operand - and ah,111b add ah,dl mov al,dh stos word [edi] @@ -4551,9 +4615,9 @@ fcomip_instruction: movd_instruction: lods byte [esi] + call get_size_operator cmp al,10h je movd_reg - call get_size_operator cmp al,'[' jne invalid_operand call get_address @@ -4564,6 +4628,7 @@ movd_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -4587,6 +4652,7 @@ movd_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -4611,9 +4677,9 @@ movd_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h je movd_mmreg_reg - call get_size_operator cmp al,'[' jne invalid_operand call get_address @@ -4649,9 +4715,9 @@ movd_instruction: ret movq_instruction: lods byte [esi] + call get_size_operator cmp al,10h je movq_mmreg - call get_size_operator cmp al,'[' jne invalid_operand call get_address @@ -4687,9 +4753,9 @@ movq_instruction: jne invalid_operand mov [operand_size],0 lods byte [esi] + call get_size_operator cmp al,10h je movq_mmreg_mmreg - call get_size_operator call get_address test [operand_size],not 8 jnz invalid_operand_size @@ -4730,9 +4796,9 @@ movq_instruction: movdq_instruction: mov [mmx_prefix],al lods byte [esi] + call get_size_operator cmp al,10h je movdq_mmreg - call get_size_operator cmp al,'[' jne invalid_operand call get_address @@ -4740,6 +4806,7 @@ movdq_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -4761,9 +4828,9 @@ movdq_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h je movdq_mmreg_mmreg - call get_size_operator cmp al,'[' jne invalid_operand call get_address @@ -4790,6 +4857,7 @@ movdq_instruction: jmp instruction_assembled movq2dq_instruction: lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -4802,6 +4870,7 @@ movq2dq_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -4819,6 +4888,7 @@ movq2dq_instruction: jmp instruction_assembled movdq2q_instruction: lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -4831,6 +4901,7 @@ movdq2q_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -4851,6 +4922,7 @@ mmx_instruction: mov [base_code],0Fh mov [extended_code],al lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -4861,9 +4933,9 @@ mmx_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h je mmx_mmreg_mmreg - call get_size_operator cmp al,'[' jne invalid_operand mmx_mmreg_mem: @@ -4890,6 +4962,7 @@ mmx_ps_instruction: mov [base_code],0Fh mov [extended_code],al lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -4901,9 +4974,9 @@ mmx_ps_instruction: jne invalid_operand mov [operand_size],0 lods byte [esi] + call get_size_operator cmp al,10h je mmx_mmreg_mmreg - call get_size_operator cmp al,'(' je mmx_ps_mmreg_imm8 cmp al,'[' @@ -4938,6 +5011,7 @@ mmx_ps_instruction: pmovmskb_instruction: mov [extended_code],al lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -4950,6 +5024,7 @@ pmovmskb_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -4984,6 +5059,7 @@ pinsrw_instruction: mov [extended_code],al mov [base_code],0Fh lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -4995,9 +5071,9 @@ pinsrw_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h je pinsrw_mmreg_reg - call get_size_operator cmp al,'[' jne invalid_operand call get_address @@ -5035,6 +5111,7 @@ pshufd_instruction: mov [base_code],0Fh mov [extended_code],70h lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -5046,9 +5123,9 @@ pshufd_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h je pshufw_mmreg_mmreg - call get_size_operator cmp al,'[' jne invalid_operand call get_address @@ -5110,6 +5187,7 @@ sse_instruction: mov [base_code],0Fh mov [extended_code],al lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand sse_xmmreg: @@ -5124,9 +5202,9 @@ sse_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h je sse_xmmreg_xmmreg - call get_size_operator call get_address pop eax mov [postbyte_register],al @@ -5166,6 +5244,7 @@ sse_instruction: ps_dq_instruction: mov bl,al lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -5222,9 +5301,9 @@ movlpd_instruction: jmp sse_mov_instruction sse_mov_instruction: lods byte [esi] + call get_size_operator cmp al,10h je sse_xmmreg - call get_size_operator cmp al,'[' jne invalid_operand inc [extended_code] @@ -5240,6 +5319,7 @@ sse_mov_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -5255,6 +5335,7 @@ movhlps_instruction: mov [mmx_size],0 mov [mmx_prefix],0 lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -5266,6 +5347,7 @@ movhlps_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h je sse_xmmreg_xmmreg_ok jmp invalid_operand @@ -5276,6 +5358,7 @@ movmskpd_instruction: mov [mmx_prefix],66h sse_movmsk: lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -5288,6 +5371,7 @@ movmskpd_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -5356,6 +5440,7 @@ cmp_sd_instruction: mov [nextbyte],al sse_cmp_instruction: lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -5367,9 +5452,9 @@ sse_cmp_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h je sse_cmp_xmmreg_xmmreg - call get_size_operator cmp al,'[' jne invalid_operand mov [operand_size],0 @@ -5428,6 +5513,7 @@ cvtpi2pd_instruction: mov [base_code],0Fh mov [extended_code],al lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -5440,9 +5526,9 @@ cvtpi2pd_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h je cvtpi_xmmreg_xmmreg - call get_size_operator cmp al,'[' jne invalid_operand call get_address @@ -5480,6 +5566,7 @@ cvtsi2sd_instruction: mov [base_code],0Fh mov [extended_code],al lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -5492,9 +5579,9 @@ cvtsi2sd_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h je cvtsi_xmmreg_reg - call get_size_operator cmp al,'[' jne invalid_operand call get_address @@ -5510,7 +5597,7 @@ cvtsi2sd_instruction: cvtsi_xmmreg_reg: lods byte [esi] call convert_register - cmp [operand_size],4 + cmp ah,4 jne invalid_operand_size pop ebx shl bl,3 @@ -5534,6 +5621,7 @@ cvtpd2pi_instruction: mov [base_code],0Fh mov [extended_code],al lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -5553,6 +5641,7 @@ cvtsd2si_instruction: mov [extended_code],al mov [base_code],0Fh lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -5566,6 +5655,7 @@ amd3dnow_instruction: mov [extended_code],0Fh push eax lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -5577,9 +5667,9 @@ amd3dnow_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h je amd3dnow_mmreg_mmreg - call get_size_operator cmp al,'[' jne invalid_operand call get_address @@ -5667,6 +5757,7 @@ maskmovdqu_instruction: mov [mmx_prefix],66h maskmov_instruction: lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -5678,6 +5769,7 @@ maskmovdqu_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -5715,6 +5807,7 @@ movntdq_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -5736,6 +5829,7 @@ movnti_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h jne invalid_operand lods byte [esi] @@ -5760,6 +5854,13 @@ convert_register: mov [operand_size],ah register_size_ok: ret +convert_fpu_register: + mov ah,al + shr ah,4 + and al,111b + cmp ah,10 + jne invalid_operand + jmp match_register_size convert_mmx_register: mov ah,al shr ah,4 @@ -5838,7 +5939,7 @@ store_segment_prefix_if_necessary: je segment_prefix_ok cmp bh,44h je segment_prefix_ok - jmp segment_prefix + jmp segment_prefix_86 store_segment_prefix: mov al,[segment_register] or al,al @@ -6561,6 +6662,8 @@ instructions_4: dw simple_fpu_instruction-assembler db 'fdiv',6 dw basic_fpu_instruction-assembler + db 'feni',0E0h + dw finit_instruction-assembler db 'fild',0 dw fild_instruction-assembler db 'fist',2 @@ -6583,7 +6686,7 @@ instructions_4: dw simple_fpu_instruction-assembler db 'fxam',100101b dw simple_fpu_instruction-assembler - db 'fxch',1 + db 'fxch',0 dw fxch_instruction-assembler db 'heap',0 dw heap_directive-assembler @@ -6649,8 +6752,12 @@ instructions_4: dw mmx_instruction-assembler db 'popa',61h dw simple_instruction-assembler + db 'popd',4 + dw pop_instruction-assembler db 'popf',9Dh dw simple_instruction-assembler + db 'popw',2 + dw pop_instruction-assembler db 'push',0 dw push_instruction-assembler db 'pxor',0EFh @@ -6799,6 +6906,8 @@ instructions_5: dw fcomi_instruction-assembler db 'fcomp',3 dw basic_fpu_instruction-assembler + db 'fdisi',0E1h + dw finit_instruction-assembler db 'fdivp',7 dw faddp_instruction-assembler db 'fdivr',7 @@ -6827,6 +6936,8 @@ instructions_5: dw simple_fpu_instruction-assembler db 'fmulp',1 dw faddp_instruction-assembler + db 'fneni',0E0h + dw fninit_instruction-assembler db 'fprem',111000b dw simple_fpu_instruction-assembler db 'fptan',110010b @@ -6987,8 +7098,12 @@ instructions_5: dw mmx_instruction-assembler db 'pusha',60h dw simple_instruction-assembler + db 'pushd',4 + dw push_instruction-assembler db 'pushf',9Ch dw simple_instruction-assembler + db 'pushw',2 + dw push_instruction-assembler db 'rcpps',53h dw sse_ps_instruction-assembler db 'rcpss',53h @@ -7129,6 +7244,8 @@ instructions_6: dw fcompp_instruction-assembler db 'fdivrp',6 dw faddp_instruction-assembler + db 'ffreep',0 + dw ffreep_instruction-assembler db 'ficomp',3 dw fi_instruction-assembler db 'fidivr',7 @@ -7147,6 +7264,8 @@ instructions_6: dw simple_fpu_instruction-assembler db 'fnclex',0E2h dw fninit_instruction-assembler + db 'fndisi',0E1h + dw fninit_instruction-assembler db 'fninit',0E3h dw fninit_instruction-assembler db 'fnsave',6 diff --git a/WHATSNEW.TXT b/WHATSNEW.TXT index a1086a8..bdde0a9 100644 --- a/WHATSNEW.TXT +++ b/WHATSNEW.TXT @@ -1,6 +1,17 @@ Visit http://fasm.sourceforge.net for more information +version 1.43 +[10-01-2002] +------------ +[+] introduced ELF output format +[+] extended public and extrn syntax +[+] allowed macro arguments containing commas (with < and > characters) +[+] added some more missing instructions and syntax options +[-] label hashing corrected +[-] formatter revised once again +[-] many other fixes + version 1.42 [05-12-2002] ------------