diff --git a/FASM.TXT b/FASM.TXT deleted file mode 100644 index b1451fa..0000000 --- a/FASM.TXT +++ /dev/null @@ -1,554 +0,0 @@ - - ÜÜÜ - Ûßßß ßÛ - ÛÛ - ÛÛ - Ü ÛÛÜÜ ÜßßßÛÜ ÜßßßßÜÞßÜÞßßÜßÛÝ - ÛÛ ÛÝ ÞÛ ß ÞÛ Û Ý - ÛÛ ÜßßßßßÛÛ ßßßÛÜÜ ÞÛ Û Ý - ÛÛ Û ÛÛ Ü ÞÛ ÞÛ Û Ý - ßßßßßß ßßßßß ßß ßßßßßß ß ß ß - - flat assembler version 1.39 - - Copyright (c) 1999-2002, Tomasz Grysztar. All rights reserved. - - -Table of Contents - - 1 Introduction - 1.1 What is fasm? - 1.2 Hardware requirements - 1.3 Software and OS requirements - 1.4 Output formats - 1.5 Output file ordering - 1.6 Output code optimization - - 2 Using flat assembler - 2.1 Assembler syntax - 2.1.1 Instruction syntax - 2.1.1.1 Data access - 2.1.1.2 Jumps and calls - 2.1.1.3 Labels and constants - 2.1.1.4 Addresses - 2.1.1.5 Special cases - 2.1.1.6 FPU and MMX instructions - 2.1.2 Number syntax - 2.1.3 Logical expressions syntax - 2.1.4 Defining constants - 2.1.5 Defining data - 2.2 Directives - 2.2.1 Preprocessor directives - 2.2.2 Label and constant definitions - 2.2.3 Code and format settings - 2.2.4 Other directives - -ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ - -1 Introduction - -1.1 What is fasm? - - The flat assembler is a fast, efficient 80x86 assembler that runs -in 'flat real mode'. So, it must be run on at least an 80386 PC, but -it can certainly assemble programs for any 80x86 PC. Unlike many other -80x86 assemblers, fasm only requires the source code to include the -information it really needs. See the 'asm' files in the 'examples' -subdirectory to see how simple it can be! The files in the 'source' and -'examples' subdirectories are good references for more complex examples. -You may notice that fasm is case sensitive for all symbols (even instructions -and directives). - -1.2 Hardware requirements - - Aside from the above-mentioned need for at least an 80386 CPU, the -hardware needs are small; at least one megabyte of extended memory is -reccommended for best performance. - -1.3 Software and OS requirements - - Other than an OS compatible with MSDOS 2.0+, fasm needs no other -software. Note that fasm will not run if the CPU is in protected or -V86 modes, since flat real mode cannot be entered in that case. But -it will still run under Win32, because version for that system is attached -to fasm executable. There exists also version for Linux, distributed in -a separate package. - -1.4 Output formats - - There are four possible output formats; by default, the output of -fasm is a non-relocatable binary image such as a 'com' or 'sys' program. -Use of the directive 'format MZ' produces a relocatable and possibly -multi-segment 'exe' program. No extra 'linking' step is needed! Use of -the directive 'format PE' produces portable executable and use of the -diretive 'format COFF' produces object file. - -1.5 Output file ordering - - All output code is in the order in which it was entered into the -source file. So, program code or at least an instruction such as 'jmp -start' must be at the beginning of the source code unless the program -is in format other than binary. In that case, see the 'entry' directive -(below). - -1.6 Output code optimization - - The flat assembler will do multiple (but fast) assembly passes to -generate optimal output code. When size of jump or address in instruction -is not specified, fasm will generate as small instruction code as possible. -That's the only code optimization fasm will do. - -2 Using flat assembler - -2.1 Assembler syntax - -2.1.1 Instruction syntax - -2.1.1.1 Data access - - Moving data to or from a register involves two simple rules; -'mov eax,myvar' will place the offset (address) of 'myvar' in the eax -register, while 'mov eax,[myvar]' will place the 32-bit value of the -variable 'myvar' in eax. Note that fasm will exit with an error if 'myvar' -has not been defined as a 32-bit value. When 'myvar' has not been defined -as 32-bit value, but you need to assemble instruction 'mov eax,[myvar]', -use size override: 'mov eax,dword [myvar]'. This is dangerous if 'myvar' has -been defined as an 8-bit or a 16-bit variable; eax will contain whatever is -in the four bytes beginning at the address of 'myvar'! Allowed size overrides -are: byte (8-bit), word (16-bit), dword (32-bit), pword (48-bit), -qword (64-bit), tword (80-bit), dqword (128-bit). - You can also use 'ptr' operator instead of brackets to get the value of -the variable, so 'mov byte ptr myvar,7' is the same as 'mov byte [myvar],7'. - -2.1.1.2 Jumps and calls - - Unconditional: - - jmp alpha ; simple jump - jmp near byte beta ; short jump - jmp near dword beta ; force dword size - jmp 10h:50h ; far jump - jmp pword 10h:50000h ; 32-bit far jump - call far pword [1000h] ; 32-bit far call - call far dword [delta] ; 16-bit far call - call near dword [delta] ; 32-bit near call - - Conditional: - - je alpha ; will be optimized - jge byte alpha ; force byte (error if out of range) - jb dword alpha ; force dword (no optimization) - -2.1.1.3 Labels and constants - - Examples of defining labels: - - alpha: ; simple label - label beta ; as above - label gamma byte ; low byte of delta dword - delta dd 0 ; data label - epsilon = delta - alpha + 1 ; constant definition - - Local labels: - - sigma: - .alpha: ; local label (1) - jmp .alpha ; jump to (1) - omega: - .alpha: ; local label (2) - jmp .alpha ; jump to (2) - jmp sigma.alpha ; jump to (1) - -2.1.1.4 Addresses - - The fasm is able to do some simple arithmetics on registers, so forms -like '[ebx*5]' are allowed (it will be assembled as '[ebx+ebx*4]'). - Defining size of address value is possible; '[word 4]' and '[dword 4]' -will generate different output code: [0004] and [00000004], '[word bx]' -will be [bx+0000], '[byte bx]' will be [bx+00], '[dword ebx+1]' will -be [ebx+00000001], etc. - -2.1.1.5 Special cases - - 'xlat' instruction accepts one argument: '[bx]'/'byte [bx]' to create -16-bit version, or '[ebx]'/'byte [ebx]' to create 32-bit version of opcode; -in the similar way advanced settings of string instructions can be done, like -'movs byte [es:edi],[fs:esi]', to adjust address registers size and segment -override ('movs' needs two arguments). 'xlatb', 'movsb', etc. accept no -arguments. - -2.1.1.6 FPU and MMX instructions - - Examples of FPU instructions: - - fld tword [si] ; load fp - fadd st0,st3 ; add fp - fimul dword [ebx] ; multiply integer - fstp qword [edx] ; store fp and pop stack - - Examples of MMX instructions: - - paddb mm0,mm1 ; packed add bytes - pand mm7,qword [esi] ; logical and - addps xmm0,xmm1 ; packed single fp add - cmpeqps xmm7,dqword [esi] ; packed single fp compare - shufps xmm4,xmm5,1 ; shuffle single fp - -2.1.2 Number syntax - - Decimal numbers: 15, 15d - Binary: 1011b - Hexadecimal: 0ABh, 0xAB - Octal: 231o, 0231 - Floating point: 3.14, 1.0E3 - Special: $ - current address value, % - current repeat number (see 2.2.3) - Operators: +,-,*,/,mod,not,and,or,xor,shl,shr - Address conversion operator: RVA (only in PE format) - Symbol concatenation operator: # - -2.1.3 Logical expressions syntax - - See 'macros' examples in Section 2.2.1 for usage examples. -The logical operators are: ~ (not), | (or), & (and). Logical values -can be defined using comparing operators: = (equal), < (less), > (greater), -<= (less or equal), >= (greater or equal), <> (not equal) for numbers; -'eq' or 'in' for all other symbols. - -2.1.4 Defining constants - - As opposed to 'equ', '=' works with values only, and they are -calculated at define time; for example 'xyz = $' defines xyz symbol -as an address of point where it was defined, 'xyz equ $' will just -define equivalent to '$', which will be always address of point -where it's used. - -2.1.5 Defining data - - Data can be defined in two ways; if the data is to be initialised -to a specific value, the forms are: - - gdtr db 16,0,0,0,0,0,0 ; sequence of bytes - attrib db 0x1E ; single byte (hexadecimal) - command: times 127 db 0 ; byte string - str001 db 'test.bin',0 ; character string - argv: times 10 dd 0 ; ten 32-bit double words - picture file 'star.gif' ; whole file contents - - When loading data with 'file' instruction, after file name can follow -position in file preceded by colon, then comma and count of bytes to load. - - Other forms available are: - - dw ; 16-bit word - dp ; 48-bit pointer - dq ; 64-bit quad word - dt ; 80-bit floating point - du ; 16-bit word strings - - If it is only desired to reserve space for data, the forms are: - - _proname rd 1 ; reserve one dword - _inch rb 1 ; reserve one byte - newstack rd 255 ; reserve 255 dwords - - Other forms available are: - - rw ; 16-bit word - rp ; 48-bit pointer - rq ; 64-bit quad word - rt ; 80-bit floating point - - Note that if the 'times' directive is to be used to define multiple data -items, any label used must end with a colon. The other way is to use 'label' -directive before data definition, for example: - - label argv dword - times 10 dd 0 - - To create union of some variables, you can use label directive with -'at
' phrase, or virtual directive, for example: - - GDT_limit dw 15 - GDT_address dd ? - - ; now define virtual variable for lgdt and sgdt instructions - - label GDTR pword at GDT_limit - - ; and now the other method - - LDTR dp ? - - virtual at LDTR - LDT_limit dw ? - LDT_address dd ? - end virtual - -2.2 Directives - -2.2.1 Preprocessor directives - - The all preprocessor directives in the source code are processed before -the main assembly process, and so they are not affected by the 'if' or -'repeat' directives, which are processed at assembly time (see 2.2.4). - -include - includes source file in source code before assembly - -macro - defines macroinstructions, arguments are macro name and names - of macro arguments separated with commas, then '{' (start of macro) - character, macro instructions, and '}' (end of macro) character. - Here's an example of macroinstruction for data alignment: - - macro align value { rb (value-1) - ($ + value-1) mod value } - - Note that in PE format you should replace '$' with 'RVA $' to allow - this calculations. - - Macroinstructions may have empty arguments; to check if argument - is empty use something like 'if eq <>'. - If a macro is defined that uses an instruction with the same name - inside the macro definition, the previous meaning of this name is - used; useful redefinition of macros can be done in that way, for - example: - - macro mov arg1,arg2 - { - if arg1 in & arg2 in - push arg2 - pop arg1 - else - mov arg1,arg2 ; here original mov instruction will be used - end if - } - macro mov arg1,arg2,arg3 - { - if eq <> - mov arg1,arg2 ; here previous macro will be used - else - mov arg1,arg2 - mov arg2,arg3 - end if - } - mov ax,bx ; just 'mov ax,bx' - mov ds,es ; 'push es' and 'pop ds' - mov es,ds,dx ; 'push ds', 'pop es' and 'mov ds,dx' - - But note that using these macros in big programs will dramatically - slow down assembly (up to 3 times!) and increase memory requirements. - - If you type arguments in brackets, macroinstruction will allow - multiple groups of arguments, and will repeat all instructions for - each arguments group separately. For example: - - macro stoschar [char] - { - mov al,char - stosb - } - - stoschar 1,2,3,4 ; store four bytes at es:di - - There are some special directives available only inside macro - definitions. The 'local' directive defines local symbols, which - will have unique names in every macro call; arguments are local - symbol names, separated with commas. The 'forward', 'reverse' and - 'common' directives divide macroinstruction into parts, each one - processed after the previous one processing is finished. The part - defined using 'forward' directive will be processed for each - group of multiple arguments, from first to last; the same as - default macroinstruction behaviour. Local symbol defined in one of - the parts will be available in all next parts, when processing the - same group of arguments. - - For example, to create table of addresses to strings, and then - strings data, use this macro: - - macro strtbl [string] - { forward - local label - dd label - forward - label db string,0 } - - The 'reverse' directive will cause groups of arguments to be - processed from last to first; and the 'common' directive will define - part, which will be processed only once. - - Here's example how to define macro for calling procedures with - arguments on stack in using the above directives: - - macro stdcall proc,[arg] - { reverse push arg - common call proc } - - Note that instructions can follow the directive defining part of - macroinstruction. - - Also, in 'common' part name of the macro argument will be replaced - with all the argument values, from first to last, separated with - commas. So we can define next macro for indirectly invoking - procedures this way: - - macro invoke proc,[arg] - { common stdcall [proc],arg } - -struc - this is the variant of macro directive used to create data - structures. When struc macro is used in program, it must be preceded - by a label. Preprocessor will insert this label at the beginning of - every symbol starting with a single dot. For example: - - struc pixel x,y,color - { - .x dw x - .y dw y - .color db color - } - - mypix pixel 10,10,4 - - ; so we have defined mypix.x, mypix.y and mypix.color variables - - virtual at 0 - pixel pixel ?,?,? - end virtual - - ; and now also pixel.x, pixel.y, pixel.color offsets - - To handle cases, when one or more of macro params are empty (for - example just: 'mypix pixel'), you can write something like - '.x dw x+0', or use 'if eq <>'. - -purge - argument is one or more macro names, separated with commas; this - directive will remove last definition of specified macro; for example - when you've redefined some macro, you can get previous definition - back using purge. If the macro has not been defined, you won't get - any error. When you need to totally undefine some non-preprocessor - symbol (defined with equ, or labels), use this clever macro: - - macro undefine symbol - { - local undefined - symbol equ undefined - } - - For example after 'undefine add', you can't use 'add' instruction, - but definition and usage of 'add' label is possible. Also, if you - use '_add equ add', and then 'undefine add', you can define 'add' - label and have access to 'add' instruction using '_add' symbol. - -equ - defines symbolic constant. This directive should be preceded by the - symbol name, and followed by the symbol value. - -2.2.2 Label and constant definitions - -label - define label, needed argument is a name of label, optional - arguments are size of labeled data and 'at
' phrase. - -load - define constant equal to binary value loaded from file; arguments are - constant name, optionally constant size (when no size is specified, - constant will be one byte), then 'from ' phrase, after file - name position in file preceded by a colon can follow. - -2.2.3 Code and format settings - -use16 - set code type to 16-bit (this is default code setting). - -use32 - set code type to 32-bit (this is default code setting for PE format). - -org - argument must be an address value; set from what address this - code will start in memory. - -format - set output file format, can be set binary, MZ, PE, or COFF; binary - is the default format, MZ is an EXE file format, PE is a portable - executable file format and COFF is a common object file format. - To make Microsoft COFF file, use 'format MS COFF' phrase. - specified format is PE, more format settings can follow; use - 'console', 'GUI' or 'native' words to set target subsystem type - (subsystem version can follow); 'i386', 'i486' or 'i586' to specify - target machine type; 'DLL' to create dynamic link library. Use - 'on ' phrase to specify custom stub program. - -segment - define segment at current position (only in MZ format), - code will be aligned to paragraph. In segment definition, after - segment name, 'use16' or 'use32' is allowed. - -section - define section at current position (only in PE and COFF formats). - If output format is PE, code will be aligned to page (4096 bytes). - First argument is a string containing section name (maximum 8 - characters), optional next arguments are section type (code, data), - and section attributes (readable, writeable, executable, shareable, - discardable). With PE format you can also specify that section - is one of predefined data types: export, import, resource, fixups. - -public - declare the existing symbol as public (only in COFF format), needed - argument is a name of symbol, optional argument is 'as ' - (string should be quoted) to make this symbol visible outside - with the different name. - -extrn - define the external symbol (only in COFF format), needed argument is - a name of symbol, optional argument is the size of data labeled by - this symbol. - -entry - define program entry point (only in MZ and PE formats). In MZ format - argument must be a segment:offset address (like in far jump). - -stack - define program stack size (only in MZ and PE formats), when no stack - is defined, default size of 1000h bytes is used. In MZ format the - stack location can be defined in segment:offset form. In PE format - second argument is allowed to define stack commit (first argument - defines stack reserve). - -heap - define 'heap' size in paragraphs (only in MZ and PE formats). In MZ - format argument is a 16-bit value, defining maximum size of additional - heap in paragraphs (note that this is heap in addition to stack and - undefined data; use 'heap 0' to always allocate only memory program - really needs); default value of 'heap' is FFFFh. In PE format - argument is a 32-bit value, defining heap reserve; second argument is - allowed to define heap commit. - -data - begin PE format specific data definition. Argument is a number of PE - data directory, or a predefined data type (export, import, resource, - fixups). Data definition should be ended with 'end data' directive. - -2.2.4 Other directives - -times - repeat instruction n times; arguments are number of repeats and - instruction to repeat (optionally character ':' can be used to - separate number and instructions), also % value (current repeat - number) can be used in instruction, so 'times 5 db %' will create - 01,02,03,04,05 bytes; recurrency is also allowed, so - 'times 3 times % db %' will create 01,01,02,01,02,03 bytes. - -repeat - larger version of times directive, repeat has one argument - - number of repeats, instructions to repeat are expected in next - lines, ended with 'end repeat' directive. - -virtual - creates virtual code or data at specified address; this data - won't be included in output file, but labels defined there can - be useful in other parts of program; argument to virtual is - 'at
' phrase, virtual instructions are expected in - next lines, ended with 'end virtual' directive. If directive - has no arguments, it uses the current address, the same as - 'virtual at $'. - -if - used to assemble some part of codes, when specified conditions are - met; argument is a logical expression, in next lines instructions to - assemble when this expression value is true, then 'end if' directive, - or 'else', or 'else if' and next logical expression. - -end - used to end structures defined with some other directives. - -display - display text at the assembly time; arguments are strings or byte - values to be displayed. - -ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ - -Thanks to: - - Leonid Petroff - for really good work with bugs reporting and many - helpful suggestions - - Bartek Uliasz - without him the flat assembler project would never - be started - - and all others who helped me (there were many of them)! diff --git a/LICENSE.TXT b/LICENSE.TXT index 794e4de..d6edd50 100644 --- a/LICENSE.TXT +++ b/LICENSE.TXT @@ -1,5 +1,5 @@ -flat assembler version 1.39 +flat assembler version 1.40 Copyright (c) 1999-2002, Tomasz Grysztar All rights reserved. @@ -35,4 +35,3 @@ The licence and distribution terms for any publically available version or derivative of this code cannot be changed. i.e. this code cannot simply be copied and put under another distribution licence (including the GNU Public Licence). - diff --git a/SOURCE/ASSEMBLE.INC b/SOURCE/ASSEMBLE.INC index efc3abc..d4ac21d 100644 --- a/SOURCE/ASSEMBLE.INC +++ b/SOURCE/ASSEMBLE.INC @@ -10,6 +10,7 @@ assembler: shr ecx,2 xor eax,eax rep stos dword [edi] + mov [stub_size],eax mov [current_pass],0 mov [number_of_sections],0 mov [times_working],0 @@ -26,10 +27,12 @@ assembler: mov [virtual_data],0 mov esi,[source_start] mov edi,[code_start] + mov [org_origin],edi mov [org_start],edi - mov [org_sib],0 - mov [error_line],0 - mov [counter],0 + xor eax,eax + mov [org_sib],eax + mov [error_line],eax + mov [counter],eax mov [number_of_relocations],0 mov [undefined_data_end],0 pass_loop: @@ -61,7 +64,7 @@ assemble_line: mov eax,[display_buffer] sub eax,100h cmp edi,eax - jae out_of_memory + ja out_of_memory lods byte [esi] or al,al jz source_end @@ -103,7 +106,7 @@ assemble_line: mov cl,al shl ecx,16 mov eax,edi - sub eax,[org_start] + sub eax,[org_origin] cdq xor ch,ch cmp [reloc_labels],0 @@ -148,13 +151,23 @@ assemble_line: jmp assemble_line define_constant: lods dword [esi] + mov edx,[eax+8] + push edx + cmp [current_pass],0 + je get_constant_value + test dl,4 + jnz get_constant_value + and dl,not 1 + mov [eax+8],dl + get_constant_value: push eax lods byte [esi] - push ax + push eax call get_value - pop bx + pop ebx mov ch,bl pop ebx + pop dword [ebx+8] or ebx,ebx jz set_org cmp ebx,10h @@ -331,8 +344,9 @@ org_directive: org_ok: mov ecx,edi sub ecx,eax - mov [org_start],ecx + mov [org_origin],ecx mov [org_sib],0 + mov [org_start],edi jmp instruction_assembled label_directive: lods byte [esi] @@ -357,7 +371,7 @@ label_directive: mov cl,ah label_size_ok: mov eax,edi - sub eax,[org_start] + sub eax,[org_origin] cdq mov ebp,[org_sib] shl ecx,16 @@ -367,7 +381,9 @@ label_directive: lods byte [esi] cmp al,'(' jne invalid_argument + push dword [ebx+8] push ebx ecx + and byte [ebx+8],not 1 cmp byte [esi],'.' je invalid_value call get_address_value @@ -379,6 +395,7 @@ label_directive: xchg bl,bh mov bp,bx pop ecx ebx + pop dword [ebx+8] cdq or ch,[value_type] jz free_label_reloc_ok @@ -444,12 +461,14 @@ load_directive: cmp al,8 ja invalid_value mov [operand_size],al - lods byte [esi] - cmp al,82h - jne invalid_argument + mov dword [value],0 + mov dword [value+4],0 lods word [esi] - cmp ax,'(' + cmp ax,82h+'(' shl 8 jne invalid_argument + cmp byte [esi],0 + jne load_from_code + inc esi lea edx,[esi+4] mov eax,[esi] lea esi,[esi+4+eax+1] @@ -474,18 +493,37 @@ load_directive: load_position_ok: xor al,al call lseek - mov dword [value],0 - mov dword [value+4],0 movzx ecx,[operand_size] mov edx,value call read jc error_reading_file call close + value_loaded: mov eax,dword [value] mov edx,dword [value+4] pop ebx xor cx,cx jmp make_constant + load_from_code: + cmp byte [esi],'.' + je invalid_value + call get_relative_offset + neg eax + cmp [value_type],0 + jne invalid_use_of_symbol + push esi edi + mov esi,edi + sub esi,eax + jc value_out_of_range + cmp esi,[org_start] + jb value_out_of_range + mov edi,value + movzx ecx,[operand_size] + cmp ecx,eax + ja value_out_of_range + rep movs byte [edi],[esi] + pop edi esi + jmp value_loaded display_directive: push esi edi prepare_display: @@ -505,7 +543,7 @@ display_directive: stos byte [edi] display_next: cmp edi,[display_buffer] - jae out_of_memory + ja out_of_memory lods byte [esi] or al,al jz do_display @@ -608,7 +646,7 @@ virtual_directive: virtual_at_current: dec esi mov eax,edi - sub eax,[org_start] + sub eax,[org_origin] xor bx,bx xor cx,cx mov [value_type],0 @@ -625,14 +663,17 @@ virtual_directive: mov word [ebx],virtual_directive-assembler neg eax add eax,edi - xchg [org_start],eax + xchg [org_origin],eax mov [ebx+4],eax mov [ebx+8],edx mov al,[virtual_data] mov [ebx+2],al mov al,[reloc_labels] mov [ebx+3],al - mov [ebx+0Ch],edi + mov eax,edi + xchg eax,[org_start] + mov [ebx+0Ch],eax + mov [ebx+10h],edi or [virtual_data],-1 mov [reloc_labels],0 cmp [value_type],1 @@ -643,7 +684,7 @@ virtual_directive: jmp instruction_assembled allocate_structure_data: mov ebx,[structures_buffer] - sub ebx,10h + sub ebx,14h cmp ebx,[additional_memory] jb out_of_memory mov [structures_buffer],ebx @@ -668,7 +709,7 @@ virtual_directive: cmp word [ebx],repeat_directive-assembler je no_such_structure repeat_structure_ok: - add ebx,10h + add ebx,14h jmp scan_structures no_such_structure: stc @@ -681,16 +722,18 @@ virtual_directive: mov al,[ebx+3] mov [reloc_labels],al mov eax,[ebx+4] - mov [org_start],eax + mov [org_origin],eax mov eax,[ebx+8] mov [org_sib],eax - mov edi,[ebx+0Ch] + mov eax,[ebx+0Ch] + mov [org_start],eax + mov edi,[ebx+10h] remove_structure_data: push esi edi mov esi,[structures_buffer] mov ecx,ebx sub ecx,esi - lea edi,[esi+10h] + lea edi,[esi+14h] mov [structures_buffer],edi shr ecx,2 rep movs dword [edi],[esi] @@ -916,7 +959,7 @@ data_bytes: stos byte [edi] byte_ok: cmp edi,[display_buffer] - jae out_of_memory + ja out_of_memory lods byte [esi] or al,al jz data_end @@ -932,6 +975,9 @@ data_bytes: inc esi lods dword [esi] mov ecx,eax + lea eax,[edi+ecx] + cmp eax,[display_buffer] + ja out_of_memory rep movs byte [edi],[esi] inc esi jmp byte_ok @@ -973,7 +1019,7 @@ data_words: stos word [edi] word_ok: cmp edi,[display_buffer] - jae out_of_memory + ja out_of_memory lods byte [esi] or al,al jz data_end @@ -987,6 +1033,9 @@ data_words: lods dword [esi] mov ecx,eax jecxz word_string_ok + lea eax,[edi+ecx*2] + cmp eax,[display_buffer] + ja out_of_memory xor ah,ah copy_word_string: lods byte [esi] @@ -1026,20 +1075,20 @@ data_dwords: cmp al,'(' jne invalid_operand mov al,[value_type] - push ax + push eax cmp byte [esi],'.' je invalid_value call get_word_value call mark_relocation stos word [edi] - pop ax + pop eax mov [value_type],al mov ax,dx call mark_relocation stos word [edi] dword_ok: cmp edi,[display_buffer] - jae out_of_memory + ja out_of_memory lods byte [esi] or al,al jz data_end @@ -1083,20 +1132,20 @@ data_pwords: cmp al,'(' jne invalid_operand mov al,[value_type] - push ax + push eax cmp byte [esi],'.' je invalid_value call get_dword_value call mark_relocation stos dword [edi] - pop ax + pop eax mov [value_type],al mov ax,dx call mark_relocation stos word [edi] pword_ok: cmp edi,[display_buffer] - jae out_of_memory + ja out_of_memory lods byte [esi] or al,al jz data_end @@ -1126,7 +1175,7 @@ data_qwords: stos dword [edi] qword_ok: cmp edi,[display_buffer] - jae out_of_memory + ja out_of_memory lods byte [esi] or al,al jz data_end @@ -1178,7 +1227,7 @@ data_twords: add esi,12 tbyte_ok: cmp edi,[display_buffer] - jae out_of_memory + ja out_of_memory lods byte [esi] or al,al jz data_end @@ -1237,7 +1286,7 @@ data_file: add edi,ecx jc out_of_memory cmp edi,[display_buffer] - jae out_of_memory + ja out_of_memory call read jc error_reading_file call close @@ -1253,7 +1302,7 @@ data_file: add edi,ecx jc out_of_memory cmp edi,[display_buffer] - jae out_of_memory + ja out_of_memory jmp check_for_next_name reserve_bytes: lods byte [esi] @@ -1271,7 +1320,7 @@ reserve_bytes: add edx,edi jc out_of_memory cmp edx,[display_buffer] - jae out_of_memory + ja out_of_memory push edi cmp [next_pass_needed],0 je zero_bytes @@ -1317,7 +1366,7 @@ reserve_words: add edx,edi jc out_of_memory cmp edx,[display_buffer] - jae out_of_memory + ja out_of_memory push edi cmp [next_pass_needed],0 je zero_words @@ -1351,7 +1400,7 @@ reserve_dwords: add edx,edi jc out_of_memory cmp edx,[display_buffer] - jae out_of_memory + ja out_of_memory push edi cmp [next_pass_needed],0 je zero_dwords @@ -1382,7 +1431,7 @@ reserve_pwords: add edx,edi jc out_of_memory cmp edx,[display_buffer] - jae out_of_memory + ja out_of_memory push edi cmp [next_pass_needed],0 je zero_words @@ -1410,7 +1459,7 @@ reserve_qwords: add edx,edi jc out_of_memory cmp edx,[display_buffer] - jae out_of_memory + ja out_of_memory push edi cmp [next_pass_needed],0 je zero_dwords @@ -1437,7 +1486,7 @@ reserve_twords: add edx,edi jc out_of_memory cmp edx,[display_buffer] - jae out_of_memory + ja out_of_memory push edi cmp [next_pass_needed],0 je zero_words @@ -1483,7 +1532,7 @@ int_instruction: stos word [edi] jmp instruction_assembled aa_instruction: - push ax + push eax mov bl,10 cmp byte [esi],'(' jne .store @@ -1497,7 +1546,7 @@ aa_instruction: .store: cmp [operand_size],0 jne invalid_operand - pop ax + pop eax mov ah,bl stos word [edi] jmp instruction_assembled @@ -2482,7 +2531,6 @@ test_instruction: inc [base_code] call store_instruction jmp instruction_assembled - test_mem_imm: mov al,[operand_size] cmp al,1 @@ -3252,14 +3300,14 @@ lea_instruction: cmp al,',' jne invalid_operand mov al,[operand_size] - push ax + push eax mov [operand_size],0 lods byte [esi] call get_size_operator cmp al,'[' jne invalid_operand call get_address - pop ax + pop eax cmp al,2 je lea_16bit cmp al,4 @@ -3339,7 +3387,7 @@ enter_instruction: call get_word_value cmp [value_type],0 jne invalid_use_of_symbol - push ax + push eax mov [operand_size],0 lods byte [esi] cmp al,',' @@ -3355,7 +3403,7 @@ enter_instruction: jne invalid_operand call get_byte_value mov dl,al - pop bx + pop ebx mov al,0C8h stos byte [edi] mov ax,bx @@ -3375,7 +3423,7 @@ sh_instruction: call get_address push edx bx cx mov al,[operand_size] - push ax + push eax mov [operand_size],0 lods byte [esi] cmp al,',' @@ -3390,7 +3438,7 @@ sh_instruction: lods byte [esi] cmp al,11h jne invalid_operand - pop ax cx bx edx + pop eax cx bx edx cmp al,1 je sh_mem_cl_8bit cmp al,2 @@ -3426,7 +3474,7 @@ sh_instruction: sh_mem_imm_size_ok: call get_byte_value mov byte [value],al - pop ax cx bx edx + pop eax cx bx edx cmp al,1 je sh_mem_imm_8bit cmp al,2 @@ -3486,7 +3534,7 @@ sh_instruction: or al,11000000b or [postbyte_register],al mov al,ah - push ax + push eax mov [operand_size],0 lods byte [esi] cmp al,',' @@ -3501,7 +3549,7 @@ sh_instruction: lods byte [esi] cmp al,11h jne invalid_operand - pop ax + pop eax mov bl,[postbyte_register] cmp al,1 je sh_reg_cl_8bit @@ -3539,7 +3587,7 @@ sh_instruction: sh_reg_imm_size_ok: call get_byte_value mov byte [value],al - pop ax + pop eax mov bl,[postbyte_register] cmp al,1 je sh_reg_imm_8bit @@ -3624,7 +3672,7 @@ shd_instruction: jne invalid_operand xor al,al xchg al,[operand_size] - push ax + push eax lods byte [esi] call get_size_operator cmp al,'(' @@ -3634,7 +3682,7 @@ shd_instruction: lods byte [esi] cmp al,11h jne invalid_operand - pop ax cx bx edx + pop eax cx bx edx cmp al,2 je shd_mem_reg_cl_16bit cmp al,4 @@ -3659,7 +3707,7 @@ shd_instruction: shd_mem_reg_imm_size_ok: call get_byte_value mov byte [value],al - pop ax cx bx edx + pop eax cx bx edx cmp al,2 je shd_mem_reg_imm_16bit cmp al,4 @@ -3924,7 +3972,7 @@ bt_instruction: bt_mem_imm: xor al,al xchg al,[operand_size] - push ax + push eax lods byte [esi] call get_size_operator cmp al,'(' @@ -3938,7 +3986,7 @@ bt_instruction: mov [extended_code],0BAh call get_byte_value mov byte [value],al - pop ax + pop eax cmp al,2 je bt_mem_imm_16bit cmp al,4 @@ -4013,7 +4061,7 @@ bt_instruction: bt_reg_imm: xor al,al xchg al,[operand_size] - push ax + push eax lods byte [esi] call get_size_operator cmp al,'(' @@ -4026,7 +4074,7 @@ bt_instruction: bt_reg_imm_size_ok: call get_byte_value mov byte [value],al - pop ax + pop eax cmp al,2 je bt_reg_imm_16bit cmp al,4 @@ -4069,6 +4117,7 @@ bs_instruction: cmp al,',' jne invalid_operand lods byte [esi] + call get_size_operator cmp al,10h je bs_reg_reg cmp al,'[' @@ -4500,7 +4549,7 @@ in_instruction: cmp al,',' jne invalid_operand mov al,ah - push ax + push eax mov [operand_size],0 lods byte [esi] call get_size_operator @@ -4513,7 +4562,7 @@ in_instruction: lods byte [esi] cmp al,22h jne invalid_operand - pop ax + pop eax cmp al,1 je in_al_dx cmp al,2 @@ -4544,7 +4593,7 @@ in_instruction: in_imm_size_ok: call get_byte_value mov dl,al - pop ax + pop eax cmp al,1 je in_al_imm cmp al,2 @@ -5176,13 +5225,13 @@ jmp_instruction: cmp [jump_type],1 je invalid_operand call get_word_value - push ax + push eax inc esi lods byte [esi] cmp al,'(' jne invalid_operand mov al,[value_type] - push ax [symbol_identifier] + push eax [symbol_identifier] cmp byte [esi],'.' je invalid_value mov bl,[operand_size] @@ -5204,9 +5253,9 @@ jmp_instruction: call mark_relocation stos word [edi] jmp_far_segment: - pop [symbol_identifier] ax + pop [symbol_identifier] eax mov [value_type],al - pop ax + pop eax call mark_relocation stos word [edi] jmp instruction_assembled @@ -5316,7 +5365,7 @@ movs_instruction: jnz invalid_address cmp [segment_register],1 ja invalid_address - push bx + push ebx lods byte [esi] cmp al,',' jne invalid_operand @@ -5325,7 +5374,7 @@ movs_instruction: cmp al,'[' jne invalid_operand call get_address - pop dx + pop edx or eax,eax jnz invalid_address or bl,ch @@ -5949,7 +5998,7 @@ movd_instruction: cmp ah,4 jne invalid_operand_size mov [operand_size],0 - push ax + push eax lods byte [esi] cmp al,',' jne invalid_operand @@ -5959,7 +6008,7 @@ movd_instruction: lods byte [esi] call convert_mmx_register call make_mmx_prefix - pop bx + pop ebx shl al,3 or bl,al or bl,11000000b @@ -5972,7 +6021,7 @@ movd_instruction: movd_mmreg: call convert_mmx_register call make_mmx_prefix - push ax + push eax mov [operand_size],0 lods byte [esi] cmp al,',' @@ -5984,7 +6033,7 @@ movd_instruction: cmp al,'[' jne invalid_operand call get_address - pop ax + pop eax mov [postbyte_register],al test [operand_size],not 4 jnz invalid_operand_size @@ -5997,7 +6046,7 @@ movd_instruction: call convert_register cmp ah,4 jne invalid_operand_size - pop bx + pop ebx shl bl,3 or bl,al or bl,11000000b @@ -6048,7 +6097,7 @@ movq_instruction: movq_mmreg: lods byte [esi] call convert_mmx_register - push ax + push eax lods byte [esi] cmp al,',' jne invalid_operand @@ -6060,7 +6109,7 @@ movq_instruction: call get_address test [operand_size],not 8 jnz invalid_operand_size - pop ax + pop eax mov [postbyte_register],al mov [base_code],0Fh cmp [operand_size],16 @@ -6074,7 +6123,7 @@ movq_instruction: call store_instruction jmp instruction_assembled movq_mmreg_mmreg: - pop bx + pop ebx lods byte [esi] call convert_mmx_register shl bl,3 @@ -6123,7 +6172,7 @@ movdq_instruction: call convert_mmx_register cmp ah,16 jne invalid_operand_size - push ax + push eax lods byte [esi] cmp al,',' jne invalid_operand @@ -6134,14 +6183,14 @@ movdq_instruction: cmp al,'[' jne invalid_operand call get_address - pop ax + pop eax mov [postbyte_register],al mov [base_code],0Fh mov [extended_code],6Fh call store_mmx_instruction jmp instruction_assembled movdq_mmreg_mmreg: - pop bx + pop ebx lods byte [esi] call convert_mmx_register cmp ah,16 @@ -6223,7 +6272,7 @@ mmx_instruction: lods byte [esi] call convert_mmx_register call make_mmx_prefix - push ax + push eax lods byte [esi] cmp al,',' jne invalid_operand @@ -6235,14 +6284,14 @@ mmx_instruction: jne invalid_operand mmx_mmreg_mem: call get_address - pop ax + pop eax mov [postbyte_register],al call store_mmx_instruction jmp instruction_assembled mmx_mmreg_mmreg: lods byte [esi] call convert_mmx_register - pop bx + pop ebx shl bl,3 or bl,al or bl,11000000b @@ -6262,7 +6311,7 @@ mmx_ps_instruction: lods byte [esi] call convert_mmx_register call make_mmx_prefix - push ax + push eax lods byte [esi] cmp al,',' jne invalid_operand @@ -6289,7 +6338,7 @@ mmx_ps_instruction: mov [extended_code],ah sub al,0Ch shl al,1 - pop bx + pop ebx shl al,3 or bl,al or bl,11000000b @@ -6408,7 +6457,7 @@ pshufd_instruction: call convert_mmx_register cmp ah,[mmx_size] jne invalid_operand_size - push ax + push eax lods byte [esi] cmp al,',' jne invalid_operand @@ -6419,14 +6468,14 @@ pshufd_instruction: cmp al,'[' jne invalid_operand call get_address - pop ax + pop eax mov [postbyte_register],al call store_mmx_instruction jmp mmx_imm8 pshufw_mmreg_mmreg: lods byte [esi] call convert_mmx_register - pop bx + pop ebx shl bl,3 or bl,al or bl,11000000b @@ -6481,7 +6530,7 @@ sse_instruction: cmp ah,16 jne invalid_operand_size sse_reg: - push ax + push eax mov [operand_size],0 lods byte [esi] cmp al,',' @@ -6491,7 +6540,7 @@ sse_instruction: je sse_xmmreg_xmmreg call get_size_operator call get_address - pop ax + pop eax mov [postbyte_register],al cmp [operand_size],0 je sse_mem_size_ok @@ -6513,7 +6562,7 @@ sse_instruction: call convert_mmx_register cmp ah,16 jne invalid_operand_size - pop bx + pop ebx shl bl,3 or bl,al or bl,11000000b @@ -6525,6 +6574,7 @@ sse_instruction: stos byte [edi] cmp [extended_code],0C6h jne instruction_assembled + jmp mmx_imm8 ps_dq_instruction: mov bl,al lods byte [esi] @@ -6623,7 +6673,7 @@ movhlps_instruction: call convert_mmx_register cmp ah,16 jne invalid_operand_size - push ax + push eax lods byte [esi] cmp al,',' jne invalid_operand @@ -6724,7 +6774,7 @@ sse_cmp_instruction: call convert_mmx_register cmp ah,16 jne invalid_operand_size - push ax + push eax lods byte [esi] cmp al,',' jne invalid_operand @@ -6736,7 +6786,7 @@ sse_cmp_instruction: jne invalid_operand mov [operand_size],0 call get_address - pop ax + pop eax mov [postbyte_register],al cmp [operand_size],0 je sse_cmp_xmmreg_mem_store @@ -6770,7 +6820,7 @@ sse_cmp_instruction: call convert_mmx_register cmp ah,16 jne invalid_operand_size - pop bx + pop ebx shl bl,3 or bl,al or bl,11000000b @@ -6796,7 +6846,7 @@ cvtpi2pd_instruction: call convert_mmx_register cmp ah,16 jne invalid_operand_size - push ax + push eax mov [operand_size],0 lods byte [esi] cmp al,',' @@ -6808,7 +6858,7 @@ cvtpi2pd_instruction: cmp al,'[' jne invalid_operand call get_address - pop ax + pop eax mov [postbyte_register],al cmp [operand_size],0 je cvtpi_size_ok @@ -6822,7 +6872,7 @@ cvtpi2pd_instruction: call convert_mmx_register cmp ah,8 jne invalid_operand_size - pop bx + pop ebx shl bl,3 or bl,al or bl,11000000b @@ -6848,7 +6898,7 @@ cvtsi2sd_instruction: call convert_mmx_register cmp ah,16 jne invalid_operand_size - push ax + push eax mov [operand_size],0 lods byte [esi] cmp al,',' @@ -6860,7 +6910,7 @@ cvtsi2sd_instruction: cmp al,'[' jne invalid_operand call get_address - pop ax + pop eax mov [postbyte_register],al cmp [operand_size],0 je cvtsi_size_ok @@ -6874,7 +6924,7 @@ cvtsi2sd_instruction: call convert_register cmp [operand_size],4 jne invalid_operand_size - pop bx + pop ebx shl bl,3 or bl,al or bl,11000000b @@ -6973,7 +7023,7 @@ maskmovdqu_instruction: call convert_mmx_register cmp ah,cl jne invalid_operand_size - push ax + push eax lods byte [esi] cmp al,',' jne invalid_operand @@ -6982,7 +7032,7 @@ maskmovdqu_instruction: jne invalid_operand lods byte [esi] call convert_mmx_register - pop bx + pop ebx shl bl,3 or bl,al or bl,11000000b @@ -7231,8 +7281,6 @@ store_instruction: address_bp: mov al,110b postbyte_16bit: - cmp ch,1 - je address_8bit_value cmp ch,2 je address_16bit_value or ch,ch @@ -7308,8 +7356,6 @@ store_instruction: or ah,bl and bh,111b or ah,bh - cmp ch,1 - je sib_address_8bit_value test ch,4 jnz sib_address_32bit_value cmp ch,2 @@ -7372,8 +7418,6 @@ store_instruction: and al,111b cmp al,4 je zero_index_register - cmp ch,1 - je simple_address_8bit_value test ch,4 jnz simple_address_32bit_value cmp ch,2 @@ -7434,8 +7478,11 @@ store_instruction: jz address_relocation_ok mov al,2 xchg [value_type],al + mov ebx,[address_symbol] + xchg ebx,[symbol_identifier] call mark_relocation mov [value_type],al + mov [symbol_identifier],ebx address_relocation_ok: mov eax,edx stos dword [edi] diff --git a/SOURCE/DOS/FASM.ASM b/SOURCE/DOS/FASM.ASM index 3821dbb..6fcc1d5 100644 --- a/SOURCE/DOS/FASM.ASM +++ b/SOURCE/DOS/FASM.ASM @@ -32,6 +32,10 @@ start: je information inc eax mov [output_file],eax + movzx ecx,byte [eax-1] + add eax,ecx + cmp byte [eax],0 + jne information mov di,characters mov cx,100h @@ -190,10 +194,13 @@ macro_block dd ? macro_block_line_number dd ? struc_name dd ? current_locals_prefix dd ? +anonymous_reverse dd ? +anonymous_forward dd ? labels_list dd ? label_hash dd ? -org_start dd ? +org_origin dd ? org_sib dd ? +org_start dd ? undefined_data_start dd ? undefined_data_end dd ? counter dd ? @@ -207,6 +214,7 @@ current_offset dd ? value dq ? fp_value rd 8 symbol_identifier dd ? +address_symbol dd ? format_flags dd ? number_of_relocations dd ? number_of_sections dd ? @@ -217,6 +225,7 @@ current_section dd ? machine dw ? subsystem dw ? subsystem_version dd ? +image_base dd ? macro_status db ? parenthesis_stack db ? diff --git a/SOURCE/DOS/SYSTEM.INC b/SOURCE/DOS/SYSTEM.INC index 57cfd98..bd127b0 100644 --- a/SOURCE/DOS/SYSTEM.INC +++ b/SOURCE/DOS/SYSTEM.INC @@ -247,35 +247,100 @@ xms_call dd ? ; XMS driver pointer xms_handle dw ? ; handle of XMS memory block open: - push edx esi di - mov esi,edx - mov di,buffer - .name: - lods byte [esi] - stos byte [di] - or al,al - jnz .name - mov dx,buffer + push esi di + call convert_path mov ax,3D00h int 21h mov bx,ax - pop di esi edx + pop di esi ret -create: - push edx esi di + convert_path: mov esi,edx mov di,buffer - .name: + copy_path: lods byte [esi] - stos byte [es:di] + cmp al,'%' + je environment_variable + cmp al,'/' + jne path_char_ok + mov al,'\' + path_char_ok: + stos byte [di] or al,al - jnz .name + jnz copy_path + sub di,buffer + cmp di,4000h + ja out_of_memory mov dx,buffer + ret + environment_variable: + mov ebx,esi + find_variable_end: + lods byte [esi] + or al,al + jz not_environment_variable + cmp al,'%' + jne find_variable_end + push esi + mov si,cs + neg si + add si,[2Ch] + movsx esi,si + sal esi,4 + compare_variable_names: + mov edx,ebx + compare_character: + lods byte [esi] + mov ah,[edx] + inc edx + cmp al,'=' + je end_of_variable_name + cmp ah,'%' + je next_variable + sub ah,al + jz compare_character + cmp ah,20h + jne next_variable + cmp al,41h + jb next_variable + cmp al,5Ah + jna compare_character + next_variable: + lods byte [esi] + or al,al + jnz next_variable + cmp byte [esi],0 + jne compare_variable_names + pop esi + jmp copy_path + end_of_variable_name: + cmp ah,'%' + jne next_variable + copy_variable_value: + lods byte [esi] + cmp al,'/' + jne value_char_ok + mov al,'\' + value_char_ok: + stos byte [di] + or al,al + jnz copy_variable_value + dec di + pop esi + jmp copy_path + not_environment_variable: + mov al,'%' + stos byte [di] + mov esi,ebx + jmp copy_path +create: + push esi di + call convert_path mov ah,3Ch xor cx,cx int 21h mov bx,ax - pop di esi edx + pop di esi ret write: push edx esi edi ebp @@ -510,7 +575,91 @@ assembler_error: int 21h jmp exit_program -times 12 nop +make_timestamp: + mov ah,2Ah + int 21h + push dx cx + movzx ecx,cx + mov eax,ecx + sub eax,1970 + mov ebx,365 + mul ebx + mov ebp,eax + mov eax,ecx + sub eax,1969 + shr eax,2 + add ebp,eax + mov eax,ecx + sub eax,1901 + mov ebx,100 + div ebx + sub ebp,eax + mov eax,ecx + xor edx,edx + sub eax,1601 + mov ebx,400 + div ebx + add ebp,eax + movzx ecx,byte [esp+3] + mov eax,ecx + dec eax + mov ebx,30 + mul ebx + add ebp,eax + cmp ecx,8 + jbe months_correction + mov eax,ecx + sub eax,7 + shr eax,1 + add ebp,eax + mov ecx,8 + months_correction: + mov eax,ecx + shr eax,1 + add ebp,eax + sub ebp,2 + cmp ecx,2 + jbe day_correction_ok + pop cx + test ecx,11b + jnz day_correction_ok + xor edx,edx + mov eax,ecx + mov ebx,100 + div ebx + or edx,edx + jnz day_correction + mov eax,ecx + mov ebx,400 + div ebx + or edx,edx + jnz day_correction_ok + day_correction: + inc ebp + day_correction_ok: + pop dx + movzx eax,dl + dec eax + add eax,ebp + mov ebx,24 + mul ebx + push eax + mov ah,2Ch + int 21h + pop eax + push dx + movzx ebx,ch + add eax,ebx + mov ebx,60 + mul ebx + movzx ebx,cl + add eax,ebx + mov ebx,60 + mul ebx + pop dx + movzx ebx,dh + add eax,ebx + ret character db ?,0 bytes_count dd ? diff --git a/SOURCE/EXPRESSI.INC b/SOURCE/EXPRESSI.INC index 00a85dd..82881cb 100644 --- a/SOURCE/EXPRESSI.INC +++ b/SOURCE/EXPRESSI.INC @@ -36,17 +36,17 @@ convert_expression: and bh,0F0h cmp bl,bh ja push_operator - pop bx + pop ebx mov byte [edi],bl inc edi jmp operators_loop push_operator: - push ax + push eax jmp expression_loop expression_end: cmp esp,ebp je expression_converted - pop ax + pop eax stos byte [edi] jmp expression_end expression_converted: @@ -382,6 +382,10 @@ get_fp_value: je fp_character_exp cmp al,'e' je fp_character_exp + cmp al,'F' + je fp_last_character + cmp al,'f' + je fp_last_character cmp al,'0' jb not_fp_value cmp al,'9' @@ -395,13 +399,18 @@ get_fp_value: fp_character_exp: cmp ah,1 ja not_fp_value - mov ah,2 + or ah,2 cmp ecx,1 jne fp_character_ok cmp byte [esi],'+' je fp_exp_sign cmp byte [esi],'-' jne fp_character_ok + fp_last_character: + cmp cl,1 + jne not_fp_value + or ah,4 + jmp fp_character_ok fp_exp_sign: inc esi cmp byte [esi],1Ah @@ -442,6 +451,10 @@ get_fp_value: je fp_exponent cmp al,'e' je fp_exponent + cmp al,'F' + je fp_done + cmp al,'f' + je fp_done sub al,30h mov edi,fp_value+16 xor edx,edx @@ -476,6 +489,10 @@ get_fp_value: je fp_exponent cmp al,'e' je fp_exponent + cmp al,'F' + je fp_done + cmp al,'f' + je fp_done inc [fp_format] cmp [fp_format],80h jne fp_counter_ok @@ -524,11 +541,14 @@ get_fp_value: movzx eax,byte [esi] inc esi sub al,30h + cmp al,10 + jae exponent_ok imul edx,10 cmp edx,8000h jae value_out_of_range add edx,eax loop get_exponent + exponent_ok: mov edi,fp_value or edx,edx jz fp_done @@ -773,9 +793,12 @@ calculate_expression: je calculate_add cmp al,81h je calculate_sub + cmp [next_pass_needed],0 + jne absolute_values_calculation mov ah,[ebx+12] or ah,[edi+12] jnz invalid_use_of_symbol + absolute_values_calculation: cmp al,90h je calculate_mul cmp al,91h @@ -910,7 +933,7 @@ calculate_expression: mov [edi+16],eax get_current_offset: mov eax,[current_offset] - sub eax,[org_start] + sub eax,[org_origin] cdq stos dword [edi] mov eax,edx @@ -937,12 +960,12 @@ calculate_expression: add edi,0Ch jmp calculation_loop calculate_add: - cmp [next_pass_needed],0 - jne add_values mov ecx,[ebx+16] cmp byte [edi+12],0 je add_values mov ecx,[edi+16] + cmp [next_pass_needed],0 + jne add_values cmp byte [ebx+12],0 jne invalid_use_of_symbol add_values: @@ -1001,14 +1024,12 @@ calculate_expression: ret calculate_sub: xor ah,ah - cmp [next_pass_needed],0 - jne sub_values mov ah,[ebx+12] mov al,[edi+12] or al,al jz sub_values cmp al,ah - jne invalid_use_of_symbol + jne invalid_sub xor ah,ah cmp [output_format],4 jne sub_values @@ -1016,7 +1037,7 @@ calculate_expression: cmp ecx,[ebx+16] je sub_values cmp ecx,[current_section] - jne invalid_use_of_symbol + jne invalid_sub mov ah,3 sub_values: mov [ebx+12],ah @@ -1036,6 +1057,10 @@ calculate_expression: call sub_register pop esi jmp calculation_loop + invalid_sub: + cmp [next_pass_needed],0 + jne sub_values + jmp invalid_use_of_symbol sub_register: or cl,cl jz add_register_done @@ -1059,19 +1084,19 @@ calculate_expression: xchg eax,[edi+12] mov [ebx+12],eax mul_start: - push esi dx + push esi edx mov esi,ebx xor bl,bl - test dword [esi+4],1 shl 31 - jz mul_first_sign_ok + bt dword [esi+4],31 + jnc mul_first_sign_ok not dword [esi] not dword [esi+4] add dword [esi],1 adc dword [esi+4],0 not bl mul_first_sign_ok: - test dword [edi+4],1 shl 31 - jz mul_second_sign_ok + bt dword [edi+4],31 + jnc mul_second_sign_ok not dword [edi] not dword [edi+4] add dword [edi],1 @@ -1107,7 +1132,7 @@ calculate_expression: add dword [esi],1 adc dword [esi+4],0 mul_ok: - pop dx + pop edx or dx,dx jz mul_calculated cmp word [edi+8],0 @@ -1149,10 +1174,10 @@ calculate_expression: pop esi jmp calculation_loop calculate_div: - push esi dx + push esi edx mov esi,ebx call div_64 - pop dx + pop edx or dx,dx jz div_calculated cmp byte [esi+8],0 @@ -1260,8 +1285,8 @@ calculate_expression: jmp calculation_loop calculate_shl: mov eax,dword [edi+4] - test eax,1 shl 31 - jnz shl_negative + bt eax,31 + jc shl_negative or eax,eax jnz zero_value mov ecx,[edi] @@ -1290,8 +1315,8 @@ calculate_expression: adc dword [edi+4],0 calculate_shr: mov eax,dword [edi+4] - test eax,1 shl 31 - jnz shr_negative + bt eax,31 + jc shr_negative or eax,eax jnz zero_value mov ecx,[edi] @@ -1324,10 +1349,13 @@ calculate_expression: mov dword [ebx+4],0 jmp calculation_loop calculate_not: + cmp [next_pass_needed],0 + jne not_ok cmp word [edi+8],0 jne invalid_expression cmp byte [edi+12],0 jne invalid_use_of_symbol + not_ok: cmp [value_size],1 je not_byte cmp [value_size],2 @@ -1373,10 +1401,13 @@ calculate_expression: add edi,14h jmp calculation_loop calculate_neg: + cmp [next_pass_needed],0 + jne neg_ok cmp word [edi+8],0 jne invalid_expression cmp byte [edi+12],0 jne invalid_use_of_symbol + neg_ok: mov eax,[edi] mov edx,[edi+4] mov dword [edi],0 @@ -1386,17 +1417,14 @@ calculate_expression: add edi,14h jmp calculation_loop calculate_rva: + cmp [next_pass_needed],0 + jne rva_ok cmp word [edi+8],0 jne invalid_expression cmp [output_format],3 jne invalid_use_of_symbol - mov al,[edi+12] - cmp al,2 - je rva_ok - or al,al - jnz invalid_use_of_symbol - cmp [next_pass_needed],0 - je invalid_use_of_symbol + cmp byte [edi+12],2 + jne invalid_use_of_symbol rva_ok: mov byte [edi+12],0 mov eax,[header_data] @@ -1415,16 +1443,16 @@ calculate_expression: je value_out_of_range jmp div_done divider_ok: - test dword [esi+4],1 shl 31 - jz div_first_sign_ok + bt dword [esi+4],31 + jnc div_first_sign_ok not dword [esi] not dword [esi+4] add dword [esi],1 adc dword [esi+4],0 not bl div_first_sign_ok: - test dword [edi+4],1 shl 31 - jz div_second_sign_ok + bt dword [edi+4],31 + jnc div_second_sign_ok not dword [edi] not dword [edi+4] add dword [edi],1 @@ -1498,8 +1526,8 @@ calculate_expression: shr eax,9 jnc fp_dword_ok inc eax - test eax,1 shl 23 - jz fp_dword_ok + bt eax,23 + jnc fp_dword_ok and eax,1 shl 23 - 1 inc bx shr eax,1 @@ -1534,8 +1562,8 @@ calculate_expression: jnc fp_qword_ok add eax,1 adc edx,0 - test edx,1 shl 20 - jz fp_qword_ok + bt edx,20 + jnc fp_qword_ok and edx,1 shl 20 - 1 inc bx shr edx,1 @@ -1628,7 +1656,6 @@ get_dword_value: mov [value_size],4 mov [forced_size],2 call calculate_expression - got_dword_value: cmp word [edi+8],0 jne invalid_value mov al,[edi+12] @@ -1639,8 +1666,8 @@ get_dword_value: je dword_positive cmp dword [edi+4],-1 jne range_exceeded - test eax,1 shl 31 - jz range_exceeded + bt eax,31 + jnc range_exceeded dword_positive: ret get_pword_value: @@ -1730,6 +1757,8 @@ get_address: jne calculate_address lods byte [esi] sub al,70h + cmp al,2 + jb invalid_address_size cmp al,4 ja invalid_address_size mov [address_size],al @@ -1741,6 +1770,8 @@ get_address_value: push address_ok calculate_address: call calculate_expression + mov eax,[edi+16] + mov [address_symbol],eax mov al,[edi+12] mov [value_type],al cmp al,1 @@ -1849,28 +1880,43 @@ get_relative_offset: mov word [esi+5],')' shl 8 + 81h call calculation_loop pop esi - jmp got_dword_value + cmp word [edi+8],0 + jne invalid_value + mov al,[edi+12] + mov [value_type],al + mov eax,[edi] + cmp dword [edi+4],0 + je offset_positive + cmp dword [edi+4],-1 + jne range_exceeded + bt eax,31 + jnc range_exceeded + ret + offset_positive: + bt eax,31 + jc range_exceeded + ret calculate_logical_expression: call get_logical_value logical_loop: - push ax + push eax lods byte [esi] cmp al,'|' je logical_or cmp al,'&' je logical_and dec esi - pop ax + pop eax ret logical_or: call get_logical_value - pop bx + pop ebx or al,bl jmp logical_loop logical_and: call get_logical_value - pop bx + pop ebx and al,bl jmp logical_loop @@ -1881,7 +1927,7 @@ get_logical_value: inc esi or al,-1 negation_ok: - push ax + push eax cmp byte [esi],'{' je logical_expression push esi @@ -2013,11 +2059,11 @@ get_logical_value: pop esi call get_value mov bl,[value_type] - push eax edx bx + push eax edx ebx lods byte [esi] mov [compare_type],al call get_value - pop bx + pop ebx cmp [next_pass_needed],0 jne values_ok cmp bl,[value_type] @@ -2093,12 +2139,12 @@ get_logical_value: logical_expression: inc esi call calculate_logical_expression - push ax + push eax lods byte [esi] cmp al,'}' jne invalid_expression - pop ax + pop eax logical_value_ok: - pop bx + pop ebx xor al,bl ret diff --git a/SOURCE/FORMATS.INC b/SOURCE/FORMATS.INC index 95645bf..0a54d25 100644 --- a/SOURCE/FORMATS.INC +++ b/SOURCE/FORMATS.INC @@ -176,6 +176,8 @@ segment_directive: mov edx,edi xor al,al rep stos byte [edi] + mov [org_origin],edi + mov [org_sib],0 mov [org_start],edi mov eax,edx call undefined_data @@ -539,32 +541,24 @@ format_pe: mov [machine],14Ch ; intel 80386 mov [subsystem],3 ; console subsystem mov [subsystem_version],3 + 10 shl 16 + mov [image_base],400000h xor edx,edx pe_settings: cmp byte [esi],84h je get_stub_name + cmp byte [esi],80h + je get_pe_base cmp byte [esi],1Bh jne pe_settings_ok lods byte [esi] lods byte [esi] test al,80h+40h jz subsystem_setting - test al,80h - jz machine_setting cmp al,80h - je pe_dll - jmp pe_settings - pe_dll: + jne pe_settings bts [format_flags],8 jc symbol_already_defined jmp pe_settings - machine_setting: - bts [format_flags],6 - jc symbol_already_defined - and ax,3Fh - add ax,149h - mov [machine],ax - jmp pe_settings subsystem_setting: bts [format_flags],7 jc symbol_already_defined @@ -582,6 +576,23 @@ format_pe: add esi,12 mov [subsystem_version],eax jmp pe_settings + get_pe_base: + bts [format_flags],9 + jc symbol_already_defined + lods word [esi] + cmp ah,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + push edx edi + add edi,[stub_size] + call get_dword_value + pop edi edx + cmp [value_type],0 + jne invalid_use_of_symbol + mov [image_base],eax + cmp byte [esi],84h + jne pe_settings_ok get_stub_name: lods byte [esi] lods word [esi] @@ -624,10 +635,11 @@ format_pe: mov word [edx+4],ax mov dword [edx+14h],0E0h ; size of optional header mov dword [edx+16h],10B818Eh; flags and magic value - mov dword [edx+34h],400000h ; base of image mov dword [edx+38h],1000h ; section alignment mov dword [edx+3Ch],200h ; file alignment mov word [edx+40h],1 ; OS version + mov eax,[image_base] + mov dword [edx+34h],eax mov ax,[subsystem] mov [edx+5Ch],ax mov eax,[subsystem_version] @@ -660,7 +672,9 @@ format_pe: neg eax add eax,edi sub eax,[edx+34h] - mov [org_start],eax + mov [org_origin],eax + mov [org_sib],0 + mov [org_start],edi bt [format_flags],8 jnc instruction_assembled or dword [edx+16h],2000h @@ -730,7 +744,9 @@ pe_section: mov eax,edi sub eax,[ebx+0Ch] sub eax,[edx+34h] - mov [org_start],eax + mov [org_origin],eax + mov [org_sib],0 + mov [org_start],edi or [reloc_labels],-1 get_section_flags: lods byte [esi] @@ -739,14 +755,6 @@ pe_section: cmp al,19h je section_flag dec esi - cmp al,13h - jne instruction_assembled - lods byte [esi] - lods byte [esi] - mov [code_type],al - cmp al,16 - jne instruction_assembled - or byte [ebx+24h],4 jmp instruction_assembled set_directory: movzx eax,byte [esi] @@ -860,11 +868,8 @@ data_directive: jmp remove_structure_data pe_entry: lods byte [esi] - call get_size_operator cmp al,'(' jne invalid_argument - test ah,not 4 - jnz invalid_address cmp byte [esi],'.' je invalid_value call get_dword_value @@ -882,11 +887,8 @@ pe_entry: jmp instruction_assembled pe_stack: lods byte [esi] - call get_size_operator cmp al,'(' jne invalid_argument - test ah,not 4 - jnz invalid_address cmp byte [esi],'.' je invalid_value call get_dword_value @@ -898,11 +900,8 @@ pe_stack: jne default_stack_commit lods byte [esi] lods byte [esi] - call get_size_operator cmp al,'(' jne invalid_argument - test ah,not 4 - jnz invalid_address cmp byte [esi],'.' je invalid_value call get_dword_value @@ -922,11 +921,8 @@ pe_stack: jmp instruction_assembled pe_heap: lods byte [esi] - call get_size_operator cmp al,'(' jne invalid_argument - test ah,not 4 - jnz invalid_address cmp byte [esi],'.' je invalid_value call get_dword_value @@ -938,11 +934,8 @@ pe_heap: jne default_heap_commit lods byte [esi] lods byte [esi] - call get_size_operator cmp al,'(' jne invalid_argument - test ah,not 4 - jnz invalid_address cmp byte [esi],'.' je invalid_value call get_dword_value @@ -1018,6 +1011,9 @@ close_pe: call close_pe_section mov edx,[header_data] mov [edx+50h],eax + call make_timestamp + mov edx,[header_data] + mov [edx+8],eax mov eax,[number_of_relocations] cmp eax,0 jle pe_flags_ok @@ -1058,7 +1054,12 @@ format_coff: mov [ebx],eax mov [ebx+4],eax mov [ebx+8],edi - mov dword [ebx+10h],0E0000060h + mov eax,60h + bt [format_flags],0 + jnc flat_section_flags_ok + or eax,0E0000000h + flat_section_flags_ok: + mov dword [ebx+10h],eax mov [current_section],ebx mov [number_of_sections],1 mov [code_type],32 @@ -1076,6 +1077,8 @@ coff_section: xor eax,eax mov [ebx],al mov [ebx+8],edi + mov [org_origin],edi + mov [org_sib],0 mov [org_start],edi or [reloc_labels],-1 mov [ebx+10h],eax @@ -1144,15 +1147,6 @@ public_directive: mov [ebx+8],eax mov eax,[current_line] mov [ebx+0Ch],eax - cmp byte [esi],86h - jne instruction_assembled - inc esi - lods word [esi] - cmp al,'(' - jne invalid_argument - mov [ebx+4],esi - lods dword [esi] - lea esi,[esi+eax+1] jmp instruction_assembled extrn_directive: cmp [output_format],4 @@ -1240,7 +1234,7 @@ mark_coff_relocation: mov [additional_memory],ebx mov byte [ebx-0Ch],al mov eax,edi - sub eax,[org_start] + sub eax,[org_origin] mov [ebx-0Ch+4],eax mov eax,[symbol_identifier] mov [ebx-0Ch+8],eax @@ -1280,6 +1274,14 @@ coff_formatter: mov [additional_memory],edi mov word [ebx],14Ch mov word [ebx+12h],104h + bt [format_flags],0 + jnc coff_flags_ok + or byte [ebx+12h],80h + coff_flags_ok: + push ebx + call make_timestamp + pop ebx + mov [ebx+4],eax mov eax,[number_of_sections] mov [ebx+2],ax mov esi,[sections_data] diff --git a/SOURCE/LINUX/FASM.ASM b/SOURCE/LINUX/FASM.ASM index 8dc7b1f..1edae71 100644 --- a/SOURCE/LINUX/FASM.ASM +++ b/SOURCE/LINUX/FASM.ASM @@ -3,7 +3,7 @@ ; Copyright (c) 1999-2002, Tomasz Grysztar ; All rights reserved. - program_base = 0x700000 + program_base = 0x8048000 org program_base use32 @@ -33,6 +33,8 @@ start: pop eax pop [input_file] pop [output_file] + pop eax + pop [environment] call init_memory @@ -157,6 +159,7 @@ additional_memory dd ? additional_memory_end dd ? input_file dd ? output_file dd ? +environment dd ? source_start dd ? code_start dd ? code_size dd ? @@ -171,10 +174,13 @@ macro_block dd ? macro_block_line_number dd ? struc_name dd ? current_locals_prefix dd ? +anonymous_reverse dd ? +anonymous_forward dd ? labels_list dd ? label_hash dd ? -org_start dd ? +org_origin dd ? org_sib dd ? +org_start dd ? undefined_data_start dd ? undefined_data_end dd ? counter dd ? @@ -188,6 +194,7 @@ current_offset dd ? value dq ? fp_value rd 8 symbol_identifier dd ? +address_symbol dd ? format_flags dd ? number_of_relocations dd ? number_of_sections dd ? @@ -198,6 +205,7 @@ current_section dd ? machine dw ? subsystem dw ? subsystem_version dd ? +image_base dd ? macro_status db ? parenthesis_stack db ? @@ -228,6 +236,6 @@ nextbyte db ? characters rb 100h converted rb 100h -buffer rb 100h +buffer rb 4000h program_end: diff --git a/SOURCE/LINUX/SYSTEM.INC b/SOURCE/LINUX/SYSTEM.INC index e1518b7..2d4c944 100644 --- a/SOURCE/LINUX/SYSTEM.INC +++ b/SOURCE/LINUX/SYSTEM.INC @@ -60,29 +60,105 @@ exit_program: int 0x80 open: - push edx esi edi ebp - mov ebx,edx + push esi edi ebp + call convert_path mov eax,5 + mov ebx,buffer mov ecx,O_RDONLY xor edx,edx int 0x80 - pop ebp edi esi edx + pop ebp edi esi test eax,eax js file_error mov ebx,eax clc ret - file_error: - stc + convert_path: + mov esi,edx + mov edi,buffer + copy_path: + lods byte [esi] + cmp al,'%' + je environment_variable + cmp al,'\' + jne path_char_ok + mov al,'/' + path_char_ok: + stos byte [edi] + or al,al + jnz copy_path + cmp edi,buffer+4000h + ja out_of_memory ret + convert_backslash: + mov al,'/' + stos byte [edi] + jmp copy_path + environment_variable: + mov ebx,esi + find_variable_end: + lods byte [esi] + or al,al + jz not_environment_variable + cmp al,'%' + jne find_variable_end + push esi + mov esi,[environment] + compare_variable_names: + mov edx,ebx + compare_character: + lods byte [esi] + mov ah,[edx] + inc edx + cmp al,'=' + je end_of_variable_name + cmp ah,'%' + je next_variable + sub ah,al + jz compare_character + cmp ah,20h + jne next_variable + cmp al,41h + jb next_variable + cmp al,5Ah + jna compare_character + next_variable: + lods byte [esi] + or al,al + jnz next_variable + cmp byte [esi],0 + jne compare_variable_names + pop esi + jmp copy_path + end_of_variable_name: + cmp ah,'%' + jne next_variable + copy_variable_value: + lods byte [esi] + cmp al,'\' + jne value_char_ok + mov al,'/' + value_char_ok: + stos byte [edi] + or al,al + jnz copy_variable_value + dec di + pop esi + jmp copy_path + not_environment_variable: + mov al,'%' + stos byte [edi] + mov esi,ebx + jmp copy_path create: - push edx esi edi ebp - mov ebx,edx + push esi edi ebp + call convert_path mov eax,5 + mov ebx,buffer mov ecx,O_CREAT+O_TRUNC+O_WRONLY mov edx,S_IRUSR+S_IWUSR+S_IRGRP int 0x80 - pop ebp edi esi edx + pop ebp edi esi test eax,eax js file_error mov ebx,eax @@ -104,6 +180,9 @@ read: jne file_error clc ret + file_error: + stc + ret write: push edx esi edi ebp mov eax,4 @@ -120,6 +199,8 @@ lseek: mov dl,al mov eax,19 int 0x80 + test eax,eax + js file_error clc ret @@ -280,6 +361,12 @@ assembler_error: call display_string jmp exit_program +make_timestamp: + mov eax,13 + xor ebx,ebx + int 0x80 + ret + character db ?,0 error_prefix db 'error: ',0 diff --git a/SOURCE/PARSER.INC b/SOURCE/PARSER.INC index 3fb9de4..1b9dab8 100644 --- a/SOURCE/PARSER.INC +++ b/SOURCE/PARSER.INC @@ -6,7 +6,10 @@ parser: mov eax,[memory_end] mov [labels_list],eax - mov [current_locals_prefix],0 + xor eax,eax + mov [current_locals_prefix],eax + mov [anonymous_reverse],eax + mov [anonymous_forward],eax mov esi,[source_start] mov edi,[code_start] push [additional_memory] @@ -24,6 +27,8 @@ parser: jb parser_loop xor al,al stos byte [edi] + cmp [anonymous_forward],0 + jne unexpected_end_of_file pop [additional_memory] mov eax,[code_start] mov [source_start],eax @@ -92,13 +97,13 @@ parse_line: data_label: pop ecx ebx pop edi - push ax esi + push eax esi mov esi,ebx call identify_label mov byte [edi],2 inc edi stos dword [edi] - pop esi ax + pop esi eax stos byte [edi] push edi jmp data_instruction @@ -119,10 +124,16 @@ parse_line: cmp eax,10h jb label_identified mov ebx,[eax+4] + cmp ebx,eax + je anonymous_label_name dec ebx mov [current_locals_prefix],ebx label_identified: ret + anonymous_label_name: + cmp byte [esi-1],'@' + jne reserved_word_used_as_symbol + ret local_label_name: call get_label_id ret @@ -435,16 +446,11 @@ parse_line: or al,al jz line_parsed cmp al,':' - je empty_label + je invalid_name cmp al,3Bh je skip_preprocessed_symbol dec esi jmp parse_arguments - empty_label: - mov eax,_counter - call increase_counter - mov [current_locals_prefix],eax - jmp instruction_start skip_preprocessed_symbol: lods byte [esi] movzx eax,al diff --git a/SOURCE/PREPROCE.INC b/SOURCE/PREPROCE.INC index ae8b66f..afc9b18 100644 --- a/SOURCE/PREPROCE.INC +++ b/SOURCE/PREPROCE.INC @@ -244,6 +244,12 @@ preprocess_line: push ecx esi mov esi,[current_line] add esi,12 + test [macro_status],0C0h + jz concatenations_ok + call process_concatenations + mov esi,[current_line] + add esi,12 + concatenations_ok: mov al,[macro_status] dec al jz find_macro_block @@ -299,9 +305,6 @@ preprocess_line: mov esi,[current_line] add esi,12 call process_symbolic_constants - mov esi,[current_line] - add esi,12 - call process_concatenations line_preprocessed: pop esi ecx pop [struc_name] @@ -349,11 +352,11 @@ process_symbolic_constants: check_symbol: movzx ecx,byte [esi] inc esi - call replace_symbolic_constant - jnc process_after_replaced + call find_symbolic_constant + jnc replace_symbolic_constant add esi,ecx jmp process_symbolic_constants - replace_symbolic_constant: + find_symbolic_constant: push edi mov ebx,esi mov eax,ecx @@ -377,6 +380,9 @@ process_symbolic_constants: ret symbolic_constant_found: pop edi + clc + ret + replace_symbolic_constant: mov ecx,[edx+8] mov edx,[edx+12] xchg esi,edx @@ -391,8 +397,6 @@ process_symbolic_constants: mov cl,al rep movs byte [edi],[esi] mov esi,edx - clc - ret process_after_replaced: lods byte [esi] cmp al,1Ah @@ -425,8 +429,8 @@ process_symbolic_constants: symbol_after_replaced: movzx ecx,byte [esi] inc esi - call replace_symbolic_constant - jnc process_after_replaced + call find_symbolic_constant + jnc replace_symbolic_constant mov al,1Ah mov ah,cl stos word [edi] @@ -540,6 +544,39 @@ define_symbolic_constant: mov [edx],al mov [edx+4],ebx jmp line_preprocessed +restore_symbolic_constant: + lods byte [esi] + cmp al,1Ah + jne invalid_name + movzx ecx,byte [esi] + inc esi + call find_symbolic_constant + jc no_symbolic_constant + mov ecx,edx + sub ecx,[labels_list] + add [labels_list],16 + shr ecx,2 + jz constant_restored + mov ebx,esi + mov esi,edx + xchg edi,edx + add edi,12 + sub esi,4 + std + rep movs dword [edi],[esi] + cld + mov esi,ebx + mov edi,edx + jmp constant_restored + no_symbolic_constant: + add esi,ecx + constant_restored: + lods byte [esi] + cmp al,',' + je restore_symbolic_constant + or al,al + jnz extra_characters_on_line + jmp line_preprocessed define_struc: or ah,1 define_macro: @@ -650,6 +687,7 @@ purge_macro: use_macro: push [macro_constants] [macro_block] [macro_block_line_number] push [counter] [counter_limit] + push dword [macro_status] or [macro_status],80h or byte [ebx+1],80h mov edx,esi @@ -1000,7 +1038,8 @@ use_macro: pop [current_line] mov eax,[macro_constants] mov [additional_memory],eax - mov [macro_status],0 + pop eax + mov [macro_status],al pop [counter_limit] [counter] pop [macro_block_line_number] [macro_block] [macro_constants] jmp line_preprocessed diff --git a/SOURCE/TABLES.INC b/SOURCE/TABLES.INC index 013e576..975d101 100644 --- a/SOURCE/TABLES.INC +++ b/SOURCE/TABLES.INC @@ -148,6 +148,8 @@ get_instruction: get_label_id: cmp ecx,100h jae name_too_long + cmp byte [esi],'@' + je anonymous_label cmp byte [esi],'.' jne standard_label cmp byte [esi+1],'.' @@ -182,6 +184,56 @@ get_label_id: call get_label_id pop esi ret + anonymous_label: + cmp ecx,2 + jne standard_label + mov al,[esi+1] + mov ebx,characters + xlat byte [ebx] + cmp al,'@' + je new_anonymous + cmp al,'b' + je anonymous_back + cmp al,'r' + je anonymous_back + cmp al,'f' + jne standard_label + add esi,2 + mov eax,[anonymous_forward] + or eax,eax + jnz anonymous_ok + mov eax,[labels_list] + sub eax,16 + mov [labels_list],eax + cmp eax,edi + jbe out_of_memory + mov dword [eax],0 + mov [eax+4],eax + mov [anonymous_forward],eax + anonymous_ok: + ret + anonymous_back: + add esi,2 + mov eax,[anonymous_reverse] + or eax,eax + jz invalid_value + ret + new_anonymous: + add esi,2 + mov eax,[anonymous_forward] + or eax,eax + jnz new_anonymous_ok + mov eax,[labels_list] + sub eax,16 + mov [labels_list],eax + cmp eax,edi + jbe out_of_memory + mov dword [eax],0 + mov [eax+4],eax + new_anonymous_ok: + mov [anonymous_reverse],eax + mov [anonymous_forward],0 + ret standard_label: cmp ecx,1 jne find_label @@ -296,7 +348,6 @@ single_operand_operators: db 0 directive_operators: - db 2,'as',86h db 2,'at',80h db 2,'eq',81h db 4,'from',82h @@ -419,9 +470,6 @@ formatter_symbols: db 6,'export',1Ah,0 db 6,'fixups',1Ah,5 db 3,'gui',1Bh,2 - db 4,'i386',1Bh,43h - db 4,'i486',1Bh,44h - db 4,'i586',1Bh,45h db 6,'import',1Ah,1 db 2,'ms',18h,41h db 2,'mz',18h,2 @@ -440,6 +488,8 @@ preprocessor_directives: dw define_macro-preprocessor db 5,'purge' dw purge_macro-preprocessor + db 7,'restore' + dw restore_symbolic_constant-preprocessor db 5,'struc' dw define_struc-preprocessor db 0 @@ -1679,10 +1729,6 @@ instructions_10: dw cmp_ps_instruction-assembler db 'cmpunordss',3 dw cmp_ss_instruction-assembler - db 'loadall286',5 - dw simple_extended_instruction-assembler - db 'loadall386',7 - dw simple_extended_instruction-assembler db 'maskmovdqu',0 dw maskmovdqu_instruction-assembler db 'prefetcht0',1 diff --git a/SOURCE/VERSION.INC b/SOURCE/VERSION.INC index 54ab134..5594e03 100644 --- a/SOURCE/VERSION.INC +++ b/SOURCE/VERSION.INC @@ -1,5 +1,5 @@ -; flat assembler version 1.39 +; flat assembler version 1.40 ; Copyright (c) 1999-2002, Tomasz Grysztar ; All rights reserved. ; @@ -33,7 +33,7 @@ ; cannot simply be copied and put under another distribution licence ; (including the GNU Public Licence). -VERSION_STRING equ "1.39" +VERSION_STRING equ "1.40" VERSION_MAJOR = 1 -VERSION_MINOR = 39 +VERSION_MINOR = 40 diff --git a/SOURCE/WIN32/FASM.ASM b/SOURCE/WIN32/FASM.ASM index 11eb2c4..d05e49d 100644 --- a/SOURCE/WIN32/FASM.ASM +++ b/SOURCE/WIN32/FASM.ASM @@ -23,6 +23,10 @@ start: je information inc eax mov [output_file],eax + movzx ecx,byte [eax-1] + add eax,ecx + cmp byte [eax],0 + jne information call init_memory @@ -204,11 +208,14 @@ macro_constants dd ? macro_block dd ? macro_block_line_number dd ? struc_name dd ? +anonymous_reverse dd ? +anonymous_forward dd ? current_locals_prefix dd ? labels_list dd ? label_hash dd ? -org_start dd ? +org_origin dd ? org_sib dd ? +org_start dd ? undefined_data_start dd ? undefined_data_end dd ? counter dd ? @@ -222,6 +229,7 @@ current_offset dd ? value dq ? fp_value rd 8 symbol_identifier dd ? +address_symbol dd ? format_flags dd ? number_of_relocations dd ? number_of_sections dd ? @@ -232,6 +240,7 @@ current_section dd ? machine dw ? subsystem dw ? subsystem_version dd ? +image_base dd ? macro_status db ? parenthesis_stack db ? @@ -262,8 +271,8 @@ nextbyte db ? characters rb 100h converted rb 100h -params rb 100h -buffer rb 100h +params rb 1000h +buffer rb 4000h stack 4000h @@ -280,9 +289,11 @@ section '.idata' import data readable writeable CloseHandle dd rva _CloseHandle SetFilePointer dd rva _SetFilePointer GetCommandLine dd rva _GetCommandLineA + GetEnvironmentVariable dd rva _GetEnvironmentVariable GetStdHandle dd rva _GetStdHandle VirtualAlloc dd rva _VirtualAlloc GetTickCount dd rva _GetTickCount + GetSystemTime dd rva _GetSystemTime GlobalMemoryStatus dd rva _GlobalMemoryStatus dd 0 @@ -302,12 +313,16 @@ section '.idata' import data readable writeable db 'SetFilePointer',0 _GetCommandLineA dw 0 db 'GetCommandLineA',0 + _GetEnvironmentVariable dw 0 + db 'GetEnvironmentVariableA',0 _GetStdHandle dw 0 db 'GetStdHandle',0 _VirtualAlloc dw 0 db 'VirtualAlloc',0 _GetTickCount dw 0 db 'GetTickCount',0 + _GetSystemTime dw 0 + db 'GetSystemTime',0 _GlobalMemoryStatus dw 0 db 'GlobalMemoryStatus',0 diff --git a/SOURCE/WIN32/SYSTEM.INC b/SOURCE/WIN32/SYSTEM.INC index 7a2cfc7..9c46b55 100644 --- a/SOURCE/WIN32/SYSTEM.INC +++ b/SOURCE/WIN32/SYSTEM.INC @@ -74,13 +74,14 @@ exit_program: call [ExitProcess] open: + call convert_path push 0 push 0 push OPEN_EXISTING push 0 push 0 push GENERIC_READ - push edx + push buffer call [CreateFile] cmp eax,-1 je file_error @@ -90,14 +91,53 @@ open: file_error: stc ret + convert_path: + push esi edi + mov esi,edx + mov edi,buffer + copy_path: + lods byte [esi] + cmp al,'%' + je environment_variable + stos byte [edi] + or al,al + jnz copy_path + cmp edi,buffer+4000h + ja out_of_memory + pop edi esi + ret + environment_variable: + mov ebx,esi + find_variable_end: + lods byte [esi] + or al,al + jz not_environment_variable + cmp al,'%' + jne find_variable_end + mov byte [esi-1],0 + mov eax,buffer+4000h + sub eax,edi + push eax + push edi + push ebx + call [GetEnvironmentVariable] + add edi,eax + mov byte [esi-1],'%' + jmp copy_path + not_environment_variable: + mov al,'%' + stos byte [edi] + mov esi,ebx + jmp copy_path create: + call convert_path push 0 push 0 push CREATE_ALWAYS push 0 push 0 push GENERIC_WRITE - push edx + push buffer call [CreateFile] cmp eax,-1 je file_error @@ -140,6 +180,8 @@ lseek: push edx push ebx call [SetFilePointer] + cmp eax,-1 + je file_error ret display_string: @@ -175,10 +217,10 @@ display_block: ret display_character: push ebx + mov [character],dl push STD_OUTPUT_HANDLE call [GetStdHandle] mov ebx,eax - mov [character],dl push 0 push bytes_count push 1 @@ -205,9 +247,9 @@ display_number: display_digit: mov dl,al add dl,30h - push ebx ecx + push ecx call display_character - pop ecx ebx + pop ecx digit_ok: mov eax,ecx xor edx,edx @@ -310,6 +352,84 @@ assembler_error: call display_string jmp exit_program +make_timestamp: + push buffer + call [GetSystemTime] + movzx ecx,word [buffer] + mov eax,ecx + sub eax,1970 + mov ebx,365 + mul ebx + mov ebp,eax + mov eax,ecx + sub eax,1969 + shr eax,2 + add ebp,eax + mov eax,ecx + sub eax,1901 + mov ebx,100 + div ebx + sub ebp,eax + mov eax,ecx + xor edx,edx + sub eax,1601 + mov ebx,400 + div ebx + add ebp,eax + movzx ecx,word [buffer+2] + mov eax,ecx + dec eax + mov ebx,30 + mul ebx + add ebp,eax + cmp ecx,8 + jbe months_correction + mov eax,ecx + sub eax,7 + shr eax,1 + add ebp,eax + mov ecx,8 + months_correction: + mov eax,ecx + shr eax,1 + add ebp,eax + sub ebp,2 + cmp ecx,2 + jbe day_correction_ok + movzx ecx,word [buffer] + test ecx,11b + jnz day_correction_ok + xor edx,edx + mov eax,ecx + mov ebx,100 + div ebx + or edx,edx + jnz day_correction + mov eax,ecx + mov ebx,400 + div ebx + or edx,edx + jnz day_correction_ok + day_correction: + inc ebp + day_correction_ok: + movzx eax,word [buffer+6] + dec eax + add eax,ebp + mov ebx,24 + mul ebx + movzx ecx,word [buffer+8] + add eax,ecx + mov ebx,60 + mul ebx + movzx ecx,word [buffer+10] + add eax,ecx + mov ebx,60 + mul ebx + movzx ecx,word [buffer+12] + add eax,ecx + ret + character db ?,0 bytes_count dd ? diff --git a/WHATSNEW.TXT b/WHATSNEW.TXT index 519404a..0a746a2 100644 --- a/WHATSNEW.TXT +++ b/WHATSNEW.TXT @@ -1,6 +1,19 @@ +Visit http://fasm.metro-nt.pl/ for more examples and documentation Questions or comments please send to fasm@metro-nt.pl -Visit http://fasm.metro-nt.pl for more examples and tools + +version 1.40 +[04-08-2002] +------------ +[+] added restore directive +[+] concatenations processed before symbolic constants now +[+] timestamps generated for COFF and PE +[+] custom base of PE image allowed +[+] added support for anonymous labels +[+] load directive extended for code loading +[+] environment variables in paths allowed +[-] concatenations allowed in macroinstructions only +[-] more fixes version 1.39 [08-07-2002] @@ -190,7 +203,7 @@ version 1.01 version 1.00 [19-06-2000] ------------ -[+] first serious release +[+] first official release version 0.90 [04-05-1999]