From 26b2f09d6ebef4611b292688def641310ad21b2e Mon Sep 17 00:00:00 2001 From: Tomasz Grysztar Date: Sat, 31 Jan 2004 12:00:00 +0000 Subject: [PATCH] release 1.51 --- FASM.TXT | 566 +++++++++++++++++++++------------------- LICENSE.TXT | 4 +- SOURCE/ASSEMBLE.INC | 23 +- SOURCE/DOS/FASM.ASM | 210 +++++++-------- SOURCE/DOS/SYSTEM.INC | 31 ++- SOURCE/EXPRESSI.INC | 13 +- SOURCE/LINUX/FASM.ASM | 188 ++++++------- SOURCE/LINUX/SYSTEM.INC | 2 + SOURCE/PARSER.INC | 204 +++++++++------ SOURCE/PREPROCE.INC | 411 ++++++++++++++++------------- SOURCE/VERSION.INC | 8 +- SOURCE/WIN32/FASM.ASM | 156 +++++------ SOURCE/WIN32/SYSTEM.INC | 1 + SOURCE/X86.INC | 101 ++++++- WHATSNEW.TXT | 7 + 15 files changed, 1094 insertions(+), 831 deletions(-) diff --git a/FASM.TXT b/FASM.TXT index cd40d9b..820d4f3 100644 --- a/FASM.TXT +++ b/FASM.TXT @@ -1,12 +1,12 @@ - Üßßß - ÜÜŪÜÜ ÜÜÜÜ ÜÜÜÜÜ ÜÜÜ ÜÜ - Ū Ū Ū Ū Ū Ū - Ū ÜßßßßŪ ßßßßÜ Ū Ū Ū - Ū ßÜÜÜÜŪÜ ÜÜÜÜÜß Ū Ū Ū + Üßßß + ÜÜŪÜÜ ÜÜÜÜ ÜÜÜÜÜ ÜÜÜ ÜÜ + Ū Ū Ū Ū Ū Ū + Ū ÜßßßßŪ ßßßßÜ Ū Ū Ū + Ū ßÜÜÜÜŪÜ ÜÜÜÜÜß Ū Ū Ū - flat assembler 1.50 - Programmer's Manual + flat assembler 1.51 + Programmer's Manual Table of contents @@ -14,57 +14,58 @@ Table of contents Chapter 1 Introduction - 1.1 Compiler overview - 1.1.1 System requirements - 1.1.2 Executing compiler from command line - 1.1.3 Compiler messages - 1.1.4 Output formats + 1.1 Compiler overview + 1.1.1 System requirements + 1.1.2 Executing compiler from command line + 1.1.3 Compiler messages + 1.1.4 Output formats - 1.2 Assembly syntax - 1.2.1 Instruction syntax - 1.2.2 Data definitions - 1.2.3 Constants and labels - 1.2.4 Numerical expressions - 1.2.5 Jumps and calls - 1.2.6 Size settings + 1.2 Assembly syntax + 1.2.1 Instruction syntax + 1.2.2 Data definitions + 1.2.3 Constants and labels + 1.2.4 Numerical expressions + 1.2.5 Jumps and calls + 1.2.6 Size settings Chapter 2 Instruction set - 2.1 Intel Architecture instructions - 2.1.1 Data movement instructions - 2.1.2 Type conversion instructions - 2.1.3 Binary arithmetic instructions - 2.1.4 Decimal arithmetic instructions - 2.1.5 Logical instructions - 2.1.6 Control transfer instructions - 2.1.7 I/O instructions - 2.1.8 Strings operations - 2.1.9 Flag control instructions - 2.1.10 Conditional operations - 2.1.11 Miscellaneous instructions - 2.1.12 System instructions - 2.1.13 FPU instructions - 2.1.14 MMX instructions - 2.1.15 SSE instructions - 2.1.16 SSE2 instructions - 2.1.17 AMD 3DNow! instructions + 2.1 Intel Architecture instructions + 2.1.1 Data movement instructions + 2.1.2 Type conversion instructions + 2.1.3 Binary arithmetic instructions + 2.1.4 Decimal arithmetic instructions + 2.1.5 Logical instructions + 2.1.6 Control transfer instructions + 2.1.7 I/O instructions + 2.1.8 Strings operations + 2.1.9 Flag control instructions + 2.1.10 Conditional operations + 2.1.11 Miscellaneous instructions + 2.1.12 System instructions + 2.1.13 FPU instructions + 2.1.14 MMX instructions + 2.1.15 SSE instructions + 2.1.16 SSE2 instructions + 2.1.17 Prescott new instructions + 2.1.18 AMD 3DNow! instructions - 2.2 Control directives - 2.2.1 Repeating blocks of instructions - 2.2.2 Conditional assembly - 2.2.3 Other directives + 2.2 Control directives + 2.2.1 Repeating blocks of instructions + 2.2.2 Conditional assembly + 2.2.3 Other directives - 2.3 Preprocessor directives - 2.3.1 Including source files - 2.3.2 Symbolic constants - 2.3.3 Macroinstructions - 2.3.4 Structures + 2.3 Preprocessor directives + 2.3.1 Including source files + 2.3.2 Symbolic constants + 2.3.3 Macroinstructions + 2.3.4 Structures - 2.4 Formatter directives - 2.4.1 MZ executable - 2.4.2 Portable Executable - 2.4.3 Common Object File Format - 2.4.4 Executable and Linkable Format + 2.4 Formatter directives + 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 @@ -117,23 +118,23 @@ compilation summary. It includes the information of how many passes was done, how much time it took, and how many bytes were written into destination file. Here is an example of the compilation summary: -flat assembler version 1.50 +flat assembler version 1.51 38 passes, 5.3 seconds, 77824 bytes. In case of error during the compilation process, program will display an error message. For example, when compiler can't find the input file, it will display the following message: -flat assembler version 1.50 +flat assembler version 1.51 error: source file not found. If the error is connected with a specific part of source code, the source line that caused the error will be also displayed. Also placement of this line in the source is given to help you finding this error, for example: -flat assembler version 1.50 +flat assembler version 1.51 example.asm [3]: - mob ax,1 + mob ax,1 error: illegal instruction. It means that in the third line of the "example.asm" file compiler has @@ -141,11 +142,11 @@ encountered an unrecognized instruction. When the line that caused error contains a macroinstruction, also the line in macrinstruction definition that generated the erroneous instruction is displayed: -flat assembler version 1.50 +flat assembler version 1.51 example.asm [6]: - stoschar 7 + stoschar 7 example.asm [3] stoschar [1]: - mob al,char + mob al,char error: illegal instruction. It means that the macroinstruction in the sixth line of the "example.asm" file @@ -201,7 +202,7 @@ segment register should be used for addressing, segment register name followed by a colon should be put just before the address value (inside the square brackets or after the "ptr" operator). - Table 1.1 Size Operators + Table 1.1 Size operators ŚÄÄÄÄÄÄÄÄÄÄĀÄÄÄÄÄÄĀÄÄÄÄÄÄÄæ ³ Operator ³ Bits ³ Bytes ³ ĘĶĶĶĶĶĶĶĶĶĶŲĶĶĶĶĶĶŲĶĶĶĶĶĶ͵ @@ -217,21 +218,21 @@ brackets or after the "ptr" operator). Table 1.2 Registers ŚÄÄÄÄÄÄÄÄÄĀÄÄÄÄÄÄĀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄæ - ³ Type ³ Bits ³ ³ + ³ Type ³ Bits ³ ³ ĘĶĶĶĶĶĶĶĶĶŲĶĶĶĶĶĶŲĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶ͵ - ³ ³ 8 ³ al cl dl bl ah ch dh bh ³ - ³ General ³ 16 ³ ax cx dx bx sp bp si di ³ - ³ ³ 32 ³ eax ecx edx ebx esp ebp esi edi ³ + ³ ³ 8 ³ al cl dl bl ah ch dh bh ³ + ³ General ³ 16 ³ ax cx dx bx sp bp si di ³ + ³ ³ 32 ³ eax ecx edx ebx esp ebp esi edi ³ ĆÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ Segment ³ 16 ³ es cs ss ds fs gs ³ + ³ Segment ³ 16 ³ es cs ss ds fs gs ³ ĆÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ Control ³ 32 ³ cr0 cr2 cr3 cr4 ³ + ³ Control ³ 32 ³ cr0 cr2 cr3 cr4 ³ ĆÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ Debug ³ 32 ³ dr0 dr1 dr2 dr3 dr6 dr7 ³ + ³ Debug ³ 32 ³ dr0 dr1 dr2 dr3 dr6 dr7 ³ ĆÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ FPU ³ 80 ³ st0 st1 st2 st3 st4 st5 st6 st7 ³ + ³ FPU ³ 80 ³ st0 st1 st2 st3 st4 st5 st6 st7 ³ ĆÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ MMX ³ 64 ³ mm0 mm1 mm2 mm3 mm4 mm5 mm6 mm7 ³ + ³ MMX ³ 64 ³ mm0 mm1 mm2 mm3 mm4 mm5 mm6 mm7 ³ ĆÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ ³ SSE ³ 128 ³ xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7 ³ ĄÄÄÄÄÄÄÄÄÄĮÄÄÄÄÄÄĮÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŁ @@ -274,20 +275,20 @@ considered unknown. ³ Size ³ Define ³ Reserve ³ ³ (bytes) ³ data ³ data ³ ĘĶĶĶĶĶĶĶĶĶŲĶĶĶĶĶĶĶĶŲĶĶĶĶĶĶĶĶ͵ - ³ 1 ³ db ³ rb ³ - ³ ³ file ³ ³ + ³ 1 ³ db ³ rb ³ + ³ ³ file ³ ³ ĆÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ“ - ³ 2 ³ dw ³ rw ³ - ³ ³ du ³ ³ + ³ 2 ³ dw ³ rw ³ + ³ ³ du ³ ³ ĆÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ“ - ³ 4 ³ dd ³ rd ³ + ³ 4 ³ dd ³ rd ³ ĆÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ“ - ³ 6 ³ dp ³ rp ³ - ³ ³ df ³ rf ³ + ³ 6 ³ dp ³ rp ³ + ³ ³ df ³ rf ³ ĆÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ“ - ³ 8 ³ dq ³ rq ³ + ³ 8 ³ dq ³ rq ³ ĆÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ“ - ³ 10 ³ dt ³ rt ³ + ³ 10 ³ dt ³ rt ³ ĄÄÄÄÄÄÄÄÄÄĮÄÄÄÄÄÄÄÄĮÄÄÄÄÄÄÄÄÄŁ @@ -398,19 +399,19 @@ while simple "1" defines an integer value. ŚÄÄÄÄÄÄÄÄÄÄĀÄÄÄÄÄÄÄÄÄÄÄÄÄÄæ ³ Priority ³ Operators ³ ĘĶĶĶĶĶĶĶĶĶĶŲĶĶĶĶĶĶĶĶĶĶĶĶĶ͵ - ³ 0 ³ + - ³ + ³ 0 ³ + - ³ ĆÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ 1 ³ * / ³ + ³ 1 ³ * / ³ ĆÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ 2 ³ mod ³ + ³ 2 ³ mod ³ ĆÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ 3 ³ and or xor ³ + ³ 3 ³ and or xor ³ ĆÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ 4 ³ shl shr ³ + ³ 4 ³ shl shr ³ ĆÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ 5 ³ not ³ + ³ 5 ³ not ³ ĆÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ 6 ³ rva ³ + ³ 6 ³ rva ³ ĄÄÄÄÄÄÄÄÄÄÄĮÄÄÄÄÄÄÄÄÄÄÄÄÄÄŁ @@ -492,14 +493,14 @@ can be assembled only if the size of source operand and size of destination operand are the same. Below are the examples for each of the allowed combinations: - mov bx,ax ; general register to general register + mov bx,ax ; general register to general register mov [char],al ; general register to memory mov bl,[char] ; memory to general register - mov dl,32 ; immediate value to general register + mov dl,32 ; immediate value to general register mov [char],32 ; immediate value to memory - mov ax,ds ; segment register to general register + mov ax,ds ; segment register to general register mov [bx],ds ; segment register to memory - mov ds,ax ; general register to segment register + mov ds,ax ; general register to segment register mov ds,[bx] ; memory to segment register mov eax,cr0 ; control register to general register mov cr3,ebx ; general register to control register @@ -509,7 +510,7 @@ two word operands or two double word operands. Order of operands is not important. The operands may be two general registers, or general register with memory. For example: - xchg ax,bx ; swap two general registers + xchg ax,bx ; swap two general registers xchg al,[char] ; swap register with memory "push" decrements the stack frame pointer (ESP register), then transfers @@ -523,10 +524,10 @@ 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 - push [bx] ; store memory - push 1000h ; store immediate value + push ax ; store general register + push es ; store segment register + push [bx] ; store memory + push 1000h ; store immediate value "pusha" saves the contents of the eight general register on the stack. This instruction has no operands. There are two version of this instruction, @@ -545,9 +546,9 @@ 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 - pop [si] ; restore memory + pop bx ; restore general register + pop ds ; restore segment register + pop [si] ; restore memory "popa" restores the registers saved on the stack by "pusha" instruction, except for the saved value of SP (or ESP), which is ignored. This instruction @@ -573,10 +574,10 @@ using the sign extension. "movzx" does the same, but it uses the zero extension. The source operand can be general register or memory, while the destination operand must be a general register. For example: - movsx ax,al ; byte register to word register - movsx edx,dl ; byte register to double word register - movsx eax,ax ; word register to double word register - movsx ax,byte [bx] ; byte memory to word register + movsx ax,al ; byte register to word register + movsx edx,dl ; byte register to double word register + movsx eax,ax ; word register to double word register + movsx ax,byte [bx] ; byte memory to word register movsx edx,byte [bx] ; byte memory to double word register movsx eax,word [bx] ; word memory to double word register @@ -589,10 +590,10 @@ be bytes, words or double words. The destination operand can be general register or memory, the source operand can be general register or immediate value, it can also be memory if the destination operand is register. - add ax,bx ; add register to register + add ax,bx ; add register to register add ax,[si] ; add memory to register add [di],al ; add register to memory - add al,48 ; add immediate value to register + add al,48 ; add immediate value to register add [char],48 ; add immediate value to memory "adc" sums the operands, adds one if CF is set, and replaces the destination @@ -602,7 +603,7 @@ add numbers longer than 32 bits. "inc" adds one to the operand. It does not affect CF. The operand can be general register or memory, size of operand can be byte, word or double word. - inc ax ; increment register by one + inc ax ; increment register by one inc byte [bx] ; increment memory by one "sub" subtracts the source operand from the destination operand and replaces @@ -659,11 +660,11 @@ forms can be also used for unsigned operands because, whether the operands are signed or unsigned, the lower half of the product is the same. Below are the examples for all three forms: - imul bl ; accumulator by register + imul bl ; accumulator by register imul word [si] ; accumulator by memory - imul bx,cx ; register by register + imul bx,cx ; register by register imul bx,[si] ; register by memory - imul bx,10 ; register by immediate value + imul bx,10 ; register by immediate value imul ax,bx,10 ; register by immediate value to register imul ax,[si],10 ; memory by immediate value to register @@ -744,9 +745,9 @@ bit to CF. "bt" instruction does nothing more, "bts" sets the selected bit to 1, "btr" resets the selected bit to 0, "btc" changes the bit to its complement. The first operand can be word or double word. - bt ax,15 ; test bit in register + bt ax,15 ; test bit in register bts word [bx],15 ; test and set bit in memory - btr ax,cx ; test and reset bit in register + btr ax,cx ; test and reset bit in register btc word [bx],cx ; test and complement bit in memory "bsf" and "bsr" instructions scan a word or double word for first set bit @@ -759,7 +760,7 @@ 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). - bsf ax,bx ; scan register forward + bsf ax,bx ; scan register forward bsr ax,[si] ; scan memory reverse "shl" shifts the destination operand left by the number of bits specified @@ -769,9 +770,9 @@ or the CL register. The processor shifts zeros in from the right (low order) side of the operand as bits exit from the left side. The last bit that exited is stored in CF. "sal" is a synonym for "shl". - shl al,1 ; shift register left by one bit + shl al,1 ; shift register left by one bit shl byte [bx],1 ; shift memory left by one bit - shl ax,cl ; shift register left by count from cl + shl ax,cl ; shift register left by count from cl shl word [bx],cl ; shift memory left by count from cl "shr" and "sar" shift the destination operand right by the number of bits @@ -818,7 +819,7 @@ the same as for the "and" instruction. bits 16 through 23. This instruction is provided for converting little-endian values to big-endian format and vice versa. - bswap edx ; swap bytes in register + bswap edx ; swap bytes in register 2.1.6 Control transfer instructions @@ -839,9 +840,9 @@ is the offset within segment. An indirect "jmp" instruction obtains the destination address indirectly through a register or a pointer variable, the operand should be general register or memory. See also 1.2.5 for more details. - jmp 100h ; direct near jump + jmp 100h ; direct near jump jmp 0FFFFh:0 ; direct far jump - jmp ax ; indirect near jump + jmp ax ; indirect near jump jmp pword [ebx] ; indirect far jump "call" transfers control to the procedure, saving on the stack the address @@ -878,53 +879,53 @@ address. Table 2.1 Conditions ŚÄÄÄÄÄÄÄÄÄÄĀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄæ - ³ Mnemonic ³ Condition tested ³ Description ³ + ³ Mnemonic ³ Condition tested ³ Description ³ ĘĶĶĶĶĶĶĶĶĶĶŲĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶŲĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶ͵ - ³ o ³ OF = 1 ³ overflow ³ + ³ o ³ OF = 1 ³ overflow ³ ĆÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ no ³ OF = 0 ³ not overflow ³ + ³ no ³ OF = 0 ³ not overflow ³ ĆÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ c ³ ³ carry ³ - ³ b ³ CF = 1 ³ below ³ - ³ nae ³ ³ not above nor equal ³ + ³ c ³ ³ carry ³ + ³ b ³ CF = 1 ³ below ³ + ³ nae ³ ³ not above nor equal ³ ĆÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ nc ³ ³ not carry ³ - ³ ae ³ CF = 0 ³ above or equal ³ - ³ nb ³ ³ not below ³ + ³ nc ³ ³ not carry ³ + ³ ae ³ CF = 0 ³ above or equal ³ + ³ nb ³ ³ not below ³ ĆÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ e ³ ZF = 1 ³ equal ³ - ³ z ³ ³ zero ³ + ³ e ³ ZF = 1 ³ equal ³ + ³ z ³ ³ zero ³ ĆÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ ne ³ ZF = 0 ³ not equal ³ - ³ nz ³ ³ not zero ³ + ³ ne ³ ZF = 0 ³ not equal ³ + ³ nz ³ ³ not zero ³ ĆÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ be ³ CF or ZF = 1 ³ jump if below or equal ³ - ³ na ³ ³ not above ³ + ³ be ³ CF or ZF = 1 ³ below or equal ³ + ³ na ³ ³ not above ³ ĆÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ a ³ CF or ZF = 0 ³ above ³ - ³ nbe ³ ³ not below nor equal ³ + ³ a ³ CF or ZF = 0 ³ above ³ + ³ nbe ³ ³ not below nor equal ³ ĆÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ s ³ SF = 1 ³ sign ³ + ³ s ³ SF = 1 ³ sign ³ ĆÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ ns ³ SF = 0 ³ not sign ³ + ³ ns ³ SF = 0 ³ not sign ³ ĆÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ p ³ PF = 1 ³ parity ³ - ³ pe ³ ³ parity even ³ + ³ p ³ PF = 1 ³ parity ³ + ³ pe ³ ³ parity even ³ ĆÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ np ³ PF = 0 ³ not parity ³ - ³ po ³ ³ parity odd ³ + ³ np ³ PF = 0 ³ not parity ³ + ³ po ³ ³ parity odd ³ ĆÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ l ³ SF xor OF = 1 ³ less ³ - ³ nge ³ ³ not greater nor equal ³ + ³ l ³ SF xor OF = 1 ³ less ³ + ³ nge ³ ³ not greater nor equal ³ ĆÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ ge ³ SF xor OF = 0 ³ greater or equal ³ - ³ nl ³ ³ not less ³ + ³ ge ³ SF xor OF = 0 ³ greater or equal ³ + ³ nl ³ ³ not less ³ ĆÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ le ³ (SF xor OF) or ZF = 1 ³ less or equal ³ - ³ ng ³ ³ not greater ³ + ³ le ³ (SF xor OF) or ZF = 1 ³ less or equal ³ + ³ ng ³ ³ not greater ³ ĆÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ“ - ³ g ³ (SF xor OF) or ZF = 0 ³ greater ³ - ³ nle ³ ³ not less nor equal ³ + ³ g ³ (SF xor OF) or ZF = 0 ³ greater ³ + ³ nle ³ ³ not less nor equal ³ ĄÄÄÄÄÄÄÄÄÄÄĮÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĮÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŁ The "loop" instructions are conditional jumps that use a value placed in @@ -973,8 +974,8 @@ value coded in instruction, or indirectly via the DX register. The destination operand should be AL, AX, or EAX register. The source operand should be an immediate value in range from 0 to 255, or DX register. - in al,20h ; input byte from port 20h - in ax,dx ; input word from port addressed by dx + in al,20h ; input byte from port 20h + in ax,dx ; input word from port addressed by dx "out" transfers a byte, word, or double word to an output port from AL, AX, or EAX. The program can specify the number of the port using the same methods @@ -982,8 +983,8 @@ as the "in" instruction. The destination operand should be an immediate value in range from 0 to 255, or DX register. The source operand should be AL, AX, or EAX register. - out 20h,ax ; output word to port 20h - out dx,al ; output byte to port addressed by dx + out 20h,ax ; output word to port 20h + out dx,al ; output byte to port addressed by dx 2.1.8 Strings operations @@ -1013,7 +1014,7 @@ prefix. movs byte [di],[si] ; transfer byte movs word [es:di],[ss:si] ; transfer word - movsd ; transfer double word + movsd ; transfer double word "cmps" subtracts the destination string element from the source string element and updates the flags AF, SF, PF, CF and OF, but it does not change @@ -1023,7 +1024,7 @@ source string element addressed by SI or ESI with any segment prefix, the second operand should be the destination string element addressed by DI or EDI. - cmpsb ; compare bytes + cmpsb ; compare bytes cmps word [ds:si],[es:di] ; compare words cmps dword [fs:esi],[edi] ; compare double words @@ -1032,8 +1033,8 @@ EDI. PF, CF and OF. If the values are equal, ZF is set, otherwise it is cleared. The operand should be the destination string element addressed by DI or EDI. - scas byte [es:di] ; scan byte - scasw ; scan word + scas byte [es:di] ; scan byte + scasw ; scan word scas dword [es:edi] ; scan double word "stos" places the value of AL, AX, or EAX into the destination string @@ -1042,25 +1043,25 @@ element. Rules for the operand are the same as for the "scas" instruction. should be the source string element addressed by SI or ESI with any segment prefix. - lods byte [ds:si] ; load byte - lods word [cs:si] ; load word - lodsd ; load double word + lods byte [ds:si] ; load byte + lods word [cs:si] ; load word + lodsd ; load double word "ins" transfers a byte, word, or double word from an input port addressed by DX register to the destination string element. The destination operand should be memory addressed by DI or EDI, the source operand should be the DX register. - insb ; input byte + insb ; input byte ins word [es:di],dx ; input word - ins dword [edi],dx ; input double word + ins dword [edi],dx ; input double word "outs" transfers the source string element to an output port addressed by DX register. The destination operand should be the DX register and the source operand should be memory addressed by SI or ESI with any segment prefix. - outs dx,byte [si] ; output byte - outsw ; output word + outs dx,byte [si] ; output byte + outsw ; output word outs dx,dword [gs:esi] ; output double word The repeat prefixes "rep", "repe"/"repz", and "repne"/"repnz" specify @@ -1077,8 +1078,8 @@ instruction depends on the zero flag (ZF) also, "repe" and "repz" terminate the execution when the ZF is zero, "repne" and "repnz" terminate the execution when the ZF is set. - rep movsd ; transfer multiple double words - repe cmpsb ; compare bytes until not equal + rep movsd ; transfer multiple double words + repe cmpsb ; compare bytes until not equal 2.1.9 Flag control instructions @@ -1105,14 +1106,14 @@ the current code setting. "popfw" variant forces restoring from the word and "popfd" forces restoring from the double word. -2.1.10 Conditional operations +2.1.10 Conditional operations The instructions obtained by attaching the condition mnemonic (see table 2.1) to the "set" mnemonic set a byte to one if the condition is true and set the byte to zero otherwise. The operand should be an 8-bit be general register or the byte in memory. - setne al ; set al if zero flag cleared + setne al ; set al if zero flag cleared seto byte [bx] ; set byte if overflow "salc" instruction sets the all bits of AL register when the carry flag is @@ -1144,7 +1145,7 @@ operand should be a quad word in memory. cmpxchg8b [bx] ; compare and exchange 8 bytes -2.1.11 Miscellaneous instructions +2.1.11 Miscellaneous instructions "nop" instruction occupies one byte but affects nothing but the instruction pointer. This instruction has no operands and doesn't perform any operation. @@ -1205,15 +1206,15 @@ the stack before adjusting the stack pointer. enter 2048,0 ; enter and allocate 2048 bytes on stack -2.1.12 System instructions +2.1.12 System instructions "lmsw" loads the operand into the machine status word (bits 0 through 15 of CR0 register), while "smsw" stores the machine status word into the destination operand. The operand can be a 16-bit or 32-bit general register or the word in memory. - lmsw ax ; load machine status from register - smsw [bx] ; store machine status to memory + lmsw ax ; load machine status from register + smsw [bx] ; store machine status to memory "lgdt" and "lidt" instructions load the values in operand into the global descriptor table register or the interrupt descriptor table register @@ -1221,7 +1222,7 @@ respectively. "sgdt" and "sidt" store the contents of the global descriptor table register or the interrupt descriptor table register in the destination operand. The operand should be a 6 bytes in memory. - lgdt [ebx] ; load global descriptor table + lgdt [ebx] ; load global descriptor table "lldt" loads the operand into the segment selector field of the local descriptor table register and "sldt" stores the segment selector from the @@ -1256,7 +1257,7 @@ operand. Otherwise, the ZF flag is cleared and no change is made to the destination operand. The destination operand can be a word general register or memory, the source operand must be a general register. - arpl bx,ax ; adjust RPL of selector in register + arpl bx,ax ; adjust RPL of selector in register arpl [bx],ax ; adjust RPL of selector in memory "clts" clears the TS (task switched) flag in the CR0 register. This @@ -1302,7 +1303,7 @@ executes a fast return to level 3 user code. The addresses used by these instructions are stored in MSRs. These instructions have no operands. -2.1.13 FPU instructions +2.1.13 FPU instructions The FPU (Floating-Point Unit) instructions operate on the floating-point values in three formats: single precision (32-bit), double precision (64-bit) @@ -1318,7 +1319,7 @@ register) and is automatically converted into the double extended precision format. fld dword [bx] ; load single prevision value from memory - fld st2 ; push value of st2 onto register stack + fld st2 ; push value of st2 onto register stack "fld1", "fldz", "fldl2t", "fldl2e", "fldpi", "fldlg2" and "fldln2" load the commonly used contants onto the FPU register stack. The loaded constants are @@ -1336,7 +1337,7 @@ performs the same operation as "fst" and then pops the register stack, getting rid of ST0. "fstp" accepts the same operands as the "fst" instruction and can also store value in the 80-bit memory. - fst st3 ; copy value of st0 into st3 register + fst st3 ; copy value of st0 into st3 register fstp tword [bx] ; store value in memory and pop stack "fist" converts the value in ST0 to a signed integer and stores the result @@ -1365,7 +1366,7 @@ destination location and then pops the register stack. The destination operand must be an FPU register and the source operand must be the ST0. When no operands are specified, ST1 is used as a destination operand. - faddp ; add st0 to st1 and pop the stack + faddp ; add st0 to st1 and pop the stack faddp st2,st0 ; add st0 to st2 and pop the stack "fiadd" instruction converts an integer source operand into double extended @@ -1419,8 +1420,8 @@ additionally pops the register stack after performing the comparision. The operand can be a single or double precision value in memory or the FPU register. When no operand is specified, ST1 is used as a source operand. - fcom ; compare st0 with st1 - fcomp st2 ; compare st0 with st2 and pop stack + fcom ; compare st0 with st1 + fcomp st2 ; compare st0 with st2 and pop stack "fcompp" compares the contents of ST0 and ST1, sets flags in the FPU status word according to the results and pops the register stack twice. This @@ -1448,21 +1449,21 @@ FPU register, and one with two operands, in that case destination operand should be ST0 register and the second operand specifies the source FPU register. - fcomi st2 ; compare st0 with st2 and set flags + fcomi st2 ; compare st0 with st2 and set flags fcmovb st0,st2 ; transfer st2 to st0 if below Table 2.2 FPU conditions ŚÄÄÄÄÄÄÄÄÄÄĀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄæ - ³ Mnemonic ³ Condition tested ³ Description ³ + ³ Mnemonic ³ Condition tested ³ Description ³ ĘĶĶĶĶĶĶĶĶĶĶŲĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶŲĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶ͵ - ³ b ³ CF = 1 ³ below ³ - ³ e ³ ZF = 1 ³ equal ³ - ³ be ³ CF or ZF = 1 ³ below or equal ³ - ³ u ³ PF = 1 ³ unordered ³ - ³ nb ³ CF = 0 ³ not below ³ - ³ ne ³ ZF = 0 ³ not equal ³ - ³ nbe ³ CF and ZF = 0 ³ not below nor equal ³ - ³ nu ³ PF = 0 ³ not unordered ³ + ³ b ³ CF = 1 ³ below ³ + ³ e ³ ZF = 1 ³ equal ³ + ³ be ³ CF or ZF = 1 ³ below or equal ³ + ³ u ³ PF = 1 ³ unordered ³ + ³ nb ³ CF = 0 ³ not below ³ + ³ ne ³ ZF = 0 ³ not equal ³ + ³ nbe ³ CF and ZF = 0 ³ not below nor equal ³ + ³ nu ³ PF = 0 ³ not unordered ³ ĄÄÄÄÄÄÄÄÄÄÄĮÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĮÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŁ "ftst" compares the value in ST0 with 0.0 and sets the flags in the FPU @@ -1503,7 +1504,7 @@ substracting one to the pointer of the top of stack. These instruction have no operands. -2.1.14 MMX instructions +2.1.14 MMX instructions The MMX instructions operate on the packed integer types and use the MMX registers, which are the low 64-bit parts of the 80-bit FPU registers. Because @@ -1575,7 +1576,7 @@ value. used before using the FPU instructions if any MMX instructions were used. -2.1.15 SSE instructions +2.1.15 SSE instructions The SSE extension adds more MMX instructions and also introduces the operations on packed single precision floating point values. The 128-bit @@ -1659,16 +1660,16 @@ mnemonic from table 2.3 to the "cmp" mnemonic and then attaching the "ps" or Table 2.3 SSE conditions ŚÄÄÄÄÄÄĀÄÄÄÄÄÄÄÄÄÄĀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄæ - ³ Code ³ Mnemonic ³ Description ³ + ³ Code ³ Mnemonic ³ Description ³ ĘĶĶĶĶĶĶŲĶĶĶĶĶĶĶĶĶĶŲĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶ͵ - ³ 0 ³ eq ³ equal ³ - ³ 1 ³ lt ³ less than ³ - ³ 2 ³ le ³ less than or equal ³ - ³ 3 ³ unord ³ unordered ³ - ³ 4 ³ neq ³ not equal ³ - ³ 5 ³ nlt ³ not less than ³ - ³ 6 ³ nle ³ not less than nor equal ³ - ³ 7 ³ ord ³ ordered ³ + ³ 0 ³ eq ³ equal ³ + ³ 1 ³ lt ³ less than ³ + ³ 2 ³ le ³ less than or equal ³ + ³ 3 ³ unord ³ unordered ³ + ³ 4 ³ neq ³ not equal ³ + ³ 5 ³ nlt ³ not less than ³ + ³ 6 ³ nle ³ not less than nor equal ³ + ³ 7 ³ ord ³ ordered ³ ĄÄÄÄÄÄÄĮÄÄÄÄÄÄÄÄÄÄĮÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŁ "comiss" and "ucomiss" compare the single precision values and set the ZF, @@ -1790,7 +1791,7 @@ instructions must be aligned on 16 byte boundary, it should declare operand of no specified size. -2.1.16 SSE2 instructions +2.1.16 SSE2 instructions The SSE2 extension introduces the operations on packed double precision floating point values, extends the syntax of MMX instructions, and adds also @@ -1950,7 +1951,48 @@ combines the functions of "sfence" (described in previous section) and "lfence" instructions. These instructions have no operands. -2.1.17 AMD 3DNow! instructions +2.1.17 Prescott new instructions + +Prescott technology introduces some new instructions to improve the performance +of SSE and SSE2 - it is also called the SSE3 extension. + "fisttp" behaves like the "fistp" instruction and accepts the same operands, +the only difference is that it always used truncation, irrespective of the +rounding mode. + "movshdup" loads into destination operand the 128-bit value obtained from +the source value of the same size by filling the each quad word with the two +duplicates of the value in its high double word. "movsldup" performs the same +action, except it duplicates the values of low double words. The destination +operand should be SSE register, the source operand can be SSE register or +128-bit memory location. + "movddup" loads the 64-bit source value and duplicates it into high and low +quad word of the destination operand. The destination operand should be SSE +register, the source operand can be SSE register or 64-bit memory location. + "lddqu" is functionally equivalent to "movdqu" instruction with memory as +source operand, but it may improve performance when the source operand crosses +a cacheline boundary. The destination operand has to be SSE register, the source +operand must be 128-bit memory location. + "addsubps" performs single precision addition of second and fourth pairs and +single precision substracion of the first and third pairs of floating point +values in the operands. "addsubpd" performs double precision addition of the +second pair and double precision substraction of the first pair of floating +point values in the operand. "haddps" performs the addition of two single +precision values within the each quad word of source and destination operands, +and stores the results of such horizontal addition of values from destination +operand into low quad word of destination operand, and the results from the +source operand into high quad word of destination operand. "haddpd" performs +the addition of two double precision values within each operand, and stores +the result from destination operand into low quad word of destination operand, +and the result from source operand into high quad word of destination operand. +All these instruction need the destination operand to be SSE register, source +operand can be SSE register or 128-bit memory location. + "monitor" sets up an address range for monitoring of write-back stores. It +need its three operands to be EAX, ECX and EDX register in that order. "mwait" +waits for a write-back store to the address range set up by the "monitor" +instruction. It uses two operands with additional parameters, first being the +EAX and second the ECX register. + + +2.1.18 AMD 3DNow! instructions The 3DNow! extension adds a new MMX instructions to those described in 2.1.14, and introduces operation on the 64-bit packed floating point values, each @@ -2030,8 +2072,8 @@ to repeat are expected in next lines, ended with the "end repeat" directive, for example: repeat 8 - mov byte [bx],% - inc bx + mov byte [bx],% + inc bx end repeat The generated code will store byte values from one to eight in the memory @@ -2077,8 +2119,8 @@ expression contains only symbols that are defined in the source. defined somewhere in source: if count>0 - mov cx,count - rep movsb + mov cx,count + rep movsb end if These two assembly instructions will be assembled only if the "count" constant @@ -2087,28 +2129,20 @@ is greater than 0. "reg" has been defined: if reg in - mov dx,reg - add ax,dx - shl ax,1 + mov dx,reg + add ax,dx + shl ax,1 else if reg eq ax - shl ax,2 + shl ax,2 else - add ax,reg - shl ax,1 + add ax,reg + shl ax,1 end if The first block of instructions will be assembled only if the value of "reg" is segment register, otherwise the second or third block will assembled whether the value of "reg" is AX register or not. - The last example shows how to conditionally define a variable that was not -defined yet: - if ~defined var & used var - var db 0 - end if - -The directive that defines "var" will be processed only if such symbol was -not defined yet, but is used somewhere in source. 2.2.3 Other directives @@ -2122,8 +2156,8 @@ are expected in next lines, ended with "end virtual" directive. GDTR dp ? virtual at GDTR - GDT_limit dw ? - GDT_address dd ? + GDT_limit dw ? + GDT_address dd ? end virtual It defines two labels for parts of the 48-bit variable at "GDTR" address. @@ -2131,8 +2165,8 @@ It defines two labels for parts of the 48-bit variable at "GDTR" address. register, for example: virtual at bx - LDT_limit dw ? - LDT_address dd ? + LDT_limit dw ? + LDT_address dd ? end virtual With such definition instruction "mov ax,[LDT_limit]" will be assembled @@ -2144,9 +2178,9 @@ used after the code it loads but before the virtual block ends, because it can only load the values from the same code space. For example: virtual at 0 - xor eax,eax - and edx,eax - load zeroq dword from 0 + xor eax,eax + and edx,eax + load zeroq dword from 0 end virtual The above piece of code will define the "zeroq" constant containing four bytes @@ -2160,16 +2194,16 @@ can be used to display values of some constants, for example: d3 = '0'+ $ shr 4 and 0Fh d4 = '0'+ $ and 0Fh if d1>'9' - d1 = d1 + 'A'-'9'-1 + d1 = d1 + 'A'-'9'-1 end if if d2>'9' - d2 = d2 + 'A'-'9'-1 + d2 = d2 + 'A'-'9'-1 end if if d3>'9' - d3 = d3 + 'A'-'9'-1 + d3 = d3 + 'A'-'9'-1 end if if d4>'9' - d4 = d4 + 'A'-'9'-1 + d4 = d4 + 'A'-'9'-1 end if display 'Current offset is 0x',d1,d2,d3,d4,13,10 @@ -2287,8 +2321,8 @@ For example: macro stos0 { - xor al,al - stosb + xor al,al + stosb } The macroinstruction "stos0" will be replaced with these two assembly @@ -2314,10 +2348,10 @@ redefinition of macroinstructions can be done in that way, for example: macro mov op1,op2 { if op1 in & op2 in - push op2 - pop op1 + push op2 + pop op1 else - mov op1,op2 + mov op1,op2 end if } @@ -2330,10 +2364,10 @@ macroinstruction of that name, which will use the previous macroinstruction: macro mov op1,op2,op3 { if op3 eq - mov op1,op2 + mov op1,op2 else - mov op1,op2 - mov op2,op3 + mov op1,op2 + mov op2,op3 end if } @@ -2366,8 +2400,8 @@ argument name in square brackets: macro stoschar [char] { - mov al,char - stosb + mov al,char + stosb } This macroinstruction accepts unlimited number of arguments, and each one @@ -2390,12 +2424,12 @@ For example: macro movstr { - local move + local move move: - lodsb - stosb - test al,al - jnz move + lodsb + stosb + test al,al + jnz move } Each time this macroinstruction is used, "move" will become other unique name @@ -2420,12 +2454,12 @@ addresses to strings followed by these strings: macro strtbl name,[string] { common - label name dword + label name dword forward - local label - dd label + local label + dd label forward - label db string,0 + label db string,0 } First argument given to this macroinstruction will become the label for table @@ -2473,8 +2507,8 @@ according to the "cond" argument: macro jif op1,cond,op2,label { - cmp op1,op2 - j#cond label + cmp op1,op2 + j#cond label } For example "jif ax,ae,10h,exit" will be assembled as "cmp ax,10h" and @@ -2490,10 +2524,10 @@ those two features: macro label name { - label name - if ~ used name - display `name # " is defined but not used.",13,10 - end if + label name + if ~ used name + display `name # " is defined but not used.",13,10 + end if } When label defined with such macro is not used in the source, macro will warn @@ -2506,16 +2540,16 @@ quoted string from an other argument: macro message arg { if arg eqtype "" - local str - jmp @f - str db arg,0Dh,0Ah,24h - @@: - mov dx,str + local str + jmp @f + str db arg,0Dh,0Ah,24h + @@: + mov dx,str else - mov dx,arg + mov dx,arg end if - mov ah,9 - int 21h + mov ah,9 + int 21h } The above macro is designed for displaying messages in DOS programs. When the @@ -2541,8 +2575,8 @@ standard macroinstructions apply to structure macroinstructions. struc point x,y { - .x dw x - .y dw y + .x dw x + .y dw y } For example "my point 7,11" will define structure labelled "my", consisting of @@ -2554,9 +2588,9 @@ macroinstruction: struc db [data] { common - label .data byte - db data - .size = $-.data + label .data byte + db data + .size = $-.data } With such definition for example "msg db 'Hello!',13,10" will define also diff --git a/LICENSE.TXT b/LICENSE.TXT index e3e0eb7..f76e42c 100644 --- a/LICENSE.TXT +++ b/LICENSE.TXT @@ -1,6 +1,6 @@ -flat assembler version 1.50 -Copyright (c) 1999-2003, Tomasz Grysztar. +flat assembler version 1.51 +Copyright (c) 1999-2004, 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 e08b4e7..1f99b80 100644 --- a/SOURCE/ASSEMBLE.INC +++ b/SOURCE/ASSEMBLE.INC @@ -129,13 +129,11 @@ assemble_line: cmp edi,eax ja out_of_memory lods byte [esi] - or al,al - jz source_end cmp al,1 je assemble_instruction - cmp al,2 - je define_label + jb source_end cmp al,3 + jb define_label je define_constant cmp al,0Fh je new_line @@ -318,10 +316,10 @@ assemble_line: assemble_instruction: mov [operand_size],0 mov [forced_size],0 - lods word [esi] - movzx ebx,ax + movzx ebx,word [esi] + mov al,[esi+2] add ebx,assembler - lods byte [esi] + add esi,3 jmp near ebx instruction_assembled: mov al,[esi] @@ -626,16 +624,21 @@ load_directive: push esi edi mov esi,edi sub esi,eax - jc value_out_of_range + jc bad_load_address cmp esi,[org_start] - jb value_out_of_range + jb bad_load_address mov edi,value movzx ecx,[operand_size] cmp ecx,eax - ja value_out_of_range + ja bad_load_address rep movs byte [edi],[esi] pop edi esi jmp value_loaded + bad_load_address: + cmp [next_pass_needed],0 + je value_out_of_range + pop edi esi + jmp value_loaded display_directive: push esi edi prepare_display: diff --git a/SOURCE/DOS/FASM.ASM b/SOURCE/DOS/FASM.ASM index 951b043..5d0acd3 100644 --- a/SOURCE/DOS/FASM.ASM +++ b/SOURCE/DOS/FASM.ASM @@ -3,9 +3,9 @@ ; Copyright (c) 1999-2003, Tomasz Grysztar. ; All rights reserved. - format MZ - heap 0 - entry main:start + format MZ + heap 0 + entry main:start include 'modes.inc' @@ -13,120 +13,120 @@ segment main use16 start: - mov ax,ds - mov dx,[2Ch] - push cs cs - pop ds es - mov [psp_segment],ax - mov [environment_segment],dx + mov ax,ds + mov dx,[2Ch] + push cs cs + pop ds es + mov [psp_segment],ax + mov [environment_segment],dx - mov dx,_logo - mov ah,9 - int 21h + mov dx,_logo + mov ah,9 + int 21h - cld + cld - call go32 - use32 - call init_memory + call go32 + use32 + call init_memory - call get_params - cmp [params],0 - je information - lea eax,[params+1] - mov [input_file],eax - movzx ecx,byte [eax-1] - add eax,ecx - cmp byte [eax],0 - je information - inc eax - mov [output_file],eax - movzx ecx,byte [eax-1] - add eax,ecx - cmp byte [eax],0 - jne information + call get_params + cmp [params],0 + je information + lea eax,[params+1] + mov [input_file],eax + movzx ecx,byte [eax-1] + add eax,ecx + cmp byte [eax],0 + je information + inc eax + mov [output_file],eax + movzx ecx,byte [eax-1] + add eax,ecx + cmp byte [eax],0 + jne information - mov edi,characters - mov ecx,100h - xor al,al + mov edi,characters + mov ecx,100h + xor al,al make_characters_table: - stosb - inc al - loop make_characters_table - mov esi,characters+'a' - mov edi,characters+'A' - mov ecx,26 - rep movsb - mov edi,characters - mov esi,symbol_characters+1 - movzx ecx,byte [esi-1] - xor ebx,ebx + stosb + inc al + loop make_characters_table + mov esi,characters+'a' + mov edi,characters+'A' + mov ecx,26 + rep movsb + mov edi,characters + mov esi,symbol_characters+1 + movzx ecx,byte [esi-1] + xor ebx,ebx convert_table: - lodsb - mov bl,al - mov byte [edi+ebx],0 - loop convert_table - mov [display_buffer],0 + lodsb + mov bl,al + mov byte [edi+ebx],0 + loop convert_table + mov [display_buffer],0 - xor ah,ah - int 1Ah - mov ax,cx - shl eax,16 - mov ax,dx - mov [start_time],eax + xor ah,ah + int 1Ah + mov ax,cx + shl eax,16 + mov ax,dx + mov [start_time],eax - call preprocessor - call parser - call assembler - call formatter + call preprocessor + call parser + call assembler + call formatter - call display_user_messages - movzx eax,[current_pass] - inc eax - call display_number - mov ah,9 - mov dx,_passes_suffix - call dos_int - xor ah,ah - int 1Ah - mov ax,cx - shl eax,16 - mov ax,dx - sub eax,[start_time] - mov ebx,100 - mul ebx - mov ebx,182 - div ebx - or eax,eax - jz display_bytes_count - xor edx,edx - mov ebx,10 - div ebx - push edx - call display_number - mov ah,2 - mov dl,'.' - int 21h - pop eax - call display_number - mov ah,9 - mov dx,_seconds_suffix - call dos_int + call display_user_messages + movzx eax,[current_pass] + inc eax + call display_number + mov ah,9 + mov dx,_passes_suffix + call dos_int + xor ah,ah + int 1Ah + mov ax,cx + shl eax,16 + mov ax,dx + sub eax,[start_time] + mov ebx,100 + mul ebx + mov ebx,182 + div ebx + or eax,eax + jz display_bytes_count + xor edx,edx + mov ebx,10 + div ebx + push edx + call display_number + mov ah,2 + mov dl,'.' + int 21h + pop eax + call display_number + mov ah,9 + mov dx,_seconds_suffix + call dos_int display_bytes_count: - mov eax,[written_size] - call display_number - mov ah,9 - mov dx,_bytes_suffix - call dos_int - xor al,al - jmp exit_program + mov eax,[written_size] + call display_number + mov ah,9 + mov dx,_bytes_suffix + call dos_int + xor al,al + jmp exit_program information: - mov dx,_usage - mov ah,9 - call dos_int - mov al,1 - jmp exit_program + mov dx,_usage + mov ah,9 + call dos_int + mov al,1 + jmp exit_program include 'system.inc' @@ -184,6 +184,8 @@ anonymous_reverse dd ? anonymous_forward dd ? labels_list dd ? label_hash dd ? +label_leaf dd ? +hash_tree dd ? org_origin dd ? org_registers dd ? org_start dd ? diff --git a/SOURCE/DOS/SYSTEM.INC b/SOURCE/DOS/SYSTEM.INC index ef9fb64..b52388c 100644 --- a/SOURCE/DOS/SYSTEM.INC +++ b/SOURCE/DOS/SYSTEM.INC @@ -149,14 +149,22 @@ extended_memory_ok: mov [additional_memory],edi mov [additional_memory_end],edi add [additional_memory_end],ecx - cmp [memory_start],0 ; if extended memory available, done - jne memory_ok + cmp [memory_start],0 + je only_conventional_memory + mov eax,[memory_end] + sub eax,[memory_start] + shr eax,3 + imul eax,3 + cmp eax,ecx + ja no_conventional_memory + ret + only_conventional_memory: shr ecx,3 ; use part of conventional memory + imul ecx,3 add edi,ecx ; as a substitute for extended memory mov [memory_start],edi xchg [additional_memory_end],edi mov [memory_end],edi - memory_ok: ret init_dpmi_memory: @@ -188,22 +196,29 @@ init_dpmi_memory: int 31h movzx ecx,bx shl ecx,4 - jecxz conventional_memory_unavailable + jecxz no_conventional_memory mov ax,100h ; allocate all conventional memory int 31h movzx edi,ax shl edi,4 sub edi,[program_base] - jc conventional_memory_unavailable + jc no_conventional_memory mov [additional_memory],edi mov [additional_memory_end],edi add [additional_memory_end],ecx + mov eax,[memory_end] + sub eax,[memory_start] + shr eax,3 + imul eax,3 + cmp eax,ecx + ja no_conventional_memory ret - conventional_memory_unavailable: + no_conventional_memory: mov eax,[memory_end] mov ebx,[memory_start] sub eax,ebx shr eax,3 + imul eax,3 mov [additional_memory],ebx add ebx,eax mov [additional_memory_end],ebx @@ -412,7 +427,7 @@ open: jnz next_variable cmp byte [esi],0 jne compare_variable_names - pop esi + pop esi ds jmp copy_path end_of_variable_name: cmp ah,'%' @@ -787,8 +802,8 @@ make_timestamp: sub ebp,2 months_correction_ok: cmp ecx,2 - jbe day_correction_ok pop cx + jbe day_correction_ok test ecx,11b jnz day_correction_ok xor edx,edx diff --git a/SOURCE/EXPRESSI.INC b/SOURCE/EXPRESSI.INC index 31a1a63..6591787 100644 --- a/SOURCE/EXPRESSI.INC +++ b/SOURCE/EXPRESSI.INC @@ -327,11 +327,17 @@ get_number: cmp bl,64 jae oct_out_of_range add bl,3 - cmp cl,32 - jae oct_digit_high + cmp cl,30 + je oct_digit_wrap + ja oct_digit_high shl eax,cl or dword [edi],eax jmp get_oct_digit + oct_digit_wrap: + shl eax,cl + adc dword [edi+4],0 + or dword [edi],eax + jmp get_oct_digit oct_digit_high: sub cl,32 shl eax,cl @@ -455,7 +461,8 @@ get_fp_value: movzx ecx,al inc ecx fp_character_ok: - loop check_fp_value + dec ecx + jnz check_fp_value or ah,ah jz not_fp_value pop esi diff --git a/SOURCE/LINUX/FASM.ASM b/SOURCE/LINUX/FASM.ASM index e52c3b3..dac8f5d 100644 --- a/SOURCE/LINUX/FASM.ASM +++ b/SOURCE/LINUX/FASM.ASM @@ -3,114 +3,114 @@ ; Copyright (c) 1999-2003, Tomasz Grysztar. ; All rights reserved. - format ELF executable - entry start + format ELF executable + entry start start: - mov esi,_logo - call display_string + mov esi,_logo + call display_string - pop eax - cmp eax,3 - jne information - pop eax - pop [input_file] - pop [output_file] - pop eax - pop [environment] + pop eax + cmp eax,3 + jne information + pop eax + pop [input_file] + pop [output_file] + pop eax + pop [environment] - call init_memory + call init_memory - mov edi,characters - mov ecx,100h - xor al,al + mov edi,characters + mov ecx,100h + xor al,al make_characters_table: - stosb - inc al - loop make_characters_table - mov esi,characters+'a' - mov edi,characters+'A' - mov ecx,26 - rep movsb - mov edi,characters - mov esi,symbol_characters+1 - movzx ecx,byte [esi-1] - xor eax,eax + stosb + inc al + loop make_characters_table + mov esi,characters+'a' + mov edi,characters+'A' + mov ecx,26 + rep movsb + mov edi,characters + mov esi,symbol_characters+1 + movzx ecx,byte [esi-1] + xor eax,eax convert_table: - lodsb - mov byte [edi+eax],0 - loop convert_table - mov [display_buffer],0 + lodsb + mov byte [edi+eax],0 + loop convert_table + mov [display_buffer],0 - mov eax,78 - mov ebx,buffer - xor ecx,ecx - int 0x80 - mov eax,dword [buffer] - mov ecx,1000 - mul ecx - mov ebx,eax - mov eax,dword [buffer+4] - div ecx - add eax,ebx - mov [start_time],eax + mov eax,78 + mov ebx,buffer + xor ecx,ecx + int 0x80 + mov eax,dword [buffer] + mov ecx,1000 + mul ecx + mov ebx,eax + mov eax,dword [buffer+4] + div ecx + add eax,ebx + mov [start_time],eax - call preprocessor - call parser - call assembler - call formatter + call preprocessor + call parser + call assembler + call formatter - call display_user_messages - movzx eax,[current_pass] - inc eax - call display_number - mov esi,_passes_suffix - call display_string - mov eax,78 - mov ebx,buffer - xor ecx,ecx - int 0x80 - mov eax,dword [buffer] - mov ecx,1000 - mul ecx - mov ebx,eax - mov eax,dword [buffer+4] - div ecx - add eax,ebx - sub eax,[start_time] - jnc time_ok - add eax,3600000 + call display_user_messages + movzx eax,[current_pass] + inc eax + call display_number + mov esi,_passes_suffix + call display_string + mov eax,78 + mov ebx,buffer + xor ecx,ecx + int 0x80 + mov eax,dword [buffer] + mov ecx,1000 + mul ecx + mov ebx,eax + mov eax,dword [buffer+4] + div ecx + add eax,ebx + sub eax,[start_time] + jnc time_ok + add eax,3600000 time_ok: - xor edx,edx - mov ebx,100 - div ebx - or eax,eax - jz display_bytes_count - xor edx,edx - mov ebx,10 - div ebx - push edx - call display_number - mov dl,'.' - call display_character - pop eax - call display_number - mov esi,_seconds_suffix - call display_string + xor edx,edx + mov ebx,100 + div ebx + or eax,eax + jz display_bytes_count + xor edx,edx + mov ebx,10 + div ebx + push edx + call display_number + mov dl,'.' + call display_character + pop eax + call display_number + mov esi,_seconds_suffix + call display_string display_bytes_count: - mov eax,[written_size] - call display_number - mov esi,_bytes_suffix - call display_string - xor al,al - jmp exit_program + mov eax,[written_size] + call display_number + mov esi,_bytes_suffix + call display_string + xor al,al + jmp exit_program information: - mov esi,_usage - call display_string - mov al,1 - jmp exit_program + mov esi,_usage + call display_string + mov al,1 + jmp exit_program include 'system.inc' @@ -167,6 +167,8 @@ anonymous_reverse dd ? anonymous_forward dd ? labels_list dd ? label_hash dd ? +label_leaf dd ? +hash_tree dd ? org_origin dd ? org_registers dd ? org_start dd ? diff --git a/SOURCE/LINUX/SYSTEM.INC b/SOURCE/LINUX/SYSTEM.INC index 91ced82..d087e52 100644 --- a/SOURCE/LINUX/SYSTEM.INC +++ b/SOURCE/LINUX/SYSTEM.INC @@ -38,12 +38,14 @@ init_memory: allocate_memory: mov ebx,[additional_memory] add ebx,dword [buffer+14h] + add ebx,dword [buffer+24h] mov eax,45 int 0x80 mov [memory_end],eax sub eax,[additional_memory] jz not_enough_memory shr eax,3 + imul eax,3 add eax,[additional_memory] mov [additional_memory_end],eax mov [memory_start],eax diff --git a/SOURCE/PARSER.INC b/SOURCE/PARSER.INC index fde1d77..b9e9ffb 100644 --- a/SOURCE/PARSER.INC +++ b/SOURCE/PARSER.INC @@ -12,6 +12,8 @@ parser: mov [current_locals_prefix],eax mov [anonymous_reverse],eax mov [anonymous_forward],eax + mov [hash_tree],eax + push [additional_memory_end] mov esi,[memory_start] mov edi,[source_start] parser_loop: @@ -31,6 +33,7 @@ parser: cmp [anonymous_forward],0 jne unexpected_end_of_file mov [code_start],edi + pop [additional_memory_end] ret parse_line: @@ -39,27 +42,19 @@ parse_line: cmp byte [esi],1Ah jne empty_instruction push edi - inc esi - movzx ecx,byte [esi] - inc esi + add esi,2 + movzx ecx,byte [esi-1] cmp byte [esi+ecx],':' je simple_label - push esi ecx - add esi,ecx - cmp byte [esi],1Ah - je check_for_data_label - cmp byte [esi],'=' + cmp byte [esi+ecx],'=' je constant_label - pop ecx esi - jmp get_main_instruction - check_for_data_label: - inc esi - movzx ecx,byte [esi] - inc esi - push edi + cmp byte [esi+ecx],1Ah + jne get_main_instruction + push esi ecx + lea esi,[esi+ecx+2] + movzx ecx,byte [esi-1] mov edi,data_directives call get_symbol - pop edi jnc data_label pop ecx esi get_main_instruction: @@ -82,9 +77,8 @@ parse_line: sub esi,2 jmp parse_arguments constant_label: - pop ecx esi pop edi - call identify_label + call get_label_id mov byte [edi],3 inc edi stos dword [edi] @@ -97,6 +91,7 @@ parse_line: pop edi push eax esi mov esi,ebx + movzx ecx,byte [esi-1] call identify_label mov byte [edi],2 inc edi @@ -136,6 +131,32 @@ parse_line: local_label_name: call get_label_id ret + parse_label_directive: + cmp byte [esi],1Ah + jne argument_parsed + inc esi + movzx ecx,byte [esi] + lods byte [esi] + mov al,2 + stos byte [edi] + call identify_label + stos dword [edi] + xor al,al + stos byte [edi] + jmp argument_parsed + parse_load_directive: + cmp byte [esi],1Ah + jne argument_parsed + inc esi + movzx ecx,byte [esi] + lods byte [esi] + mov al,2 + stos byte [edi] + call get_label_id + stos dword [edi] + xor al,al + stos byte [edi] + jmp argument_parsed parse_prefix_instruction: cmp byte [esi],1Ah jne parse_arguments @@ -144,21 +165,6 @@ parse_line: movzx ecx,byte [esi] inc esi jmp get_main_instruction - parse_label_directive: - 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 identify_label - stos dword [edi] - xor al,al - stos byte [edi] - jmp argument_parsed parse_instruction: pop edi mov dl,al @@ -174,10 +180,10 @@ parse_line: je parse_prefix_instruction cmp bx,label_directive-assembler je parse_label_directive - cmp bx,load_directive-assembler - je parse_label_directive cmp bx,segment_directive-assembler je parse_label_directive + cmp bx,load_directive-assembler + je parse_load_directive cmp bx,extrn_directive-assembler je parse_extrn_directive cmp bx,public_directive-assembler @@ -722,26 +728,25 @@ get_label_id: cmp [current_locals_prefix],0 je standard_label push edi + mov edi,[additional_memory_end] + sub edi,2 + sub edi,ecx push ecx esi - mov edi,[free_additional_memory] - xor ax,ax - stos word [edi] mov esi,[current_locals_prefix] - mov ebx,edi lods byte [esi] movzx ecx,al - lea ebp,[edi+ecx] - cmp ebp,[additional_memory_end] - jae out_of_memory + sub edi,ecx + cmp edi,[free_additional_memory] + jb out_of_memory + mov [additional_memory_end],edi + mov word [edi],0 + add edi,2 + mov ebx,edi rep movs byte [edi],[esi] pop esi ecx add al,cl jc name_too_long - lea ebp,[edi+ecx] - cmp ebp,[additional_memory_end] - jae out_of_memory rep movs byte [edi],[esi] - mov [free_additional_memory],edi pop edi push esi movzx ecx,al @@ -832,29 +837,82 @@ get_label_id: sub esi,2 find_label: xor ebx,ebx - xor ebp,ebp + mov eax,2166136261 + mov ebp,16777619 hash_label: - rol ebp,12 - mov eax,ebp - shr ebp,8 - and eax,1111b - or ebp,eax - movzx eax,byte [esi+ebx] - add ebp,eax + xor al,[esi+ebx] + mul ebp inc bl cmp bl,cl jb hash_label - and ebp,0FFFFFFh - shl ebx,24 + mov ebp,eax + shl eax,8 + and ebp,0FFh shl 24 + xor ebp,eax or ebp,ebx mov [label_hash],ebp - push edi - push esi + push edi esi + push ecx + mov ecx,32 + mov ebx,hash_tree + follow_tree: + mov edx,[ebx] + or edx,edx + jz extend_tree + xor eax,eax + shl ebp,1 + adc eax,0 + lea ebx,[edx+eax*4] + dec ecx + jnz follow_tree + mov [label_leaf],ebx + pop edx + mov eax,[ebx] + or eax,eax + jz add_label mov ebx,esi - mov edx,ecx - mov eax,[labels_list] + mov ebp,[label_hash] + align 16 + scan_hashes: + cmp ebp,[eax] + je check_label + next_label: + add eax,8 cmp eax,[memory_end] jne scan_hashes + jmp add_label + check_label: + mov esi,ebx + mov ecx,edx + mov edi,[eax+4] + repe cmps byte [esi],[edi] + jne next_label + label_found: + add esp,4 + pop edi + mov ebx,[eax+4] + make_label_id: + sub eax,[memory_end] + imul eax,3 + add eax,[memory_end] + ret + extend_tree: + mov edx,[free_additional_memory] + lea eax,[edx+8] + cmp eax,[additional_memory_end] + ja out_of_memory + mov [free_additional_memory],eax + xor eax,eax + mov [edx],eax + mov [edx+4],eax + shl ebp,1 + adc eax,0 + mov [ebx],edx + lea ebx,[edx+eax*4] + dec ecx + jnz extend_tree + mov [label_leaf],ebx + pop edx add_label: mov ecx,edx pop esi @@ -910,35 +968,13 @@ get_label_id: pop edi cmp eax,edi jbe out_of_memory + mov edx,[label_leaf] + mov [edx],eax jmp make_label_id reserved_word: mov eax,0Fh pop edi ret - align 16 - scan_hashes: - cmp ebp,[eax] - je check_label - next_label: - add eax,8 - cmp eax,[memory_end] - jne scan_hashes - jmp add_label - check_label: - mov esi,ebx - mov ecx,edx - mov edi,[eax+4] - repe cmps byte [esi],[edi] - jne next_label - label_found: - add esp,4 - pop edi - mov ebx,[eax+4] - make_label_id: - sub eax,[memory_end] - imul eax,3 - add eax,[memory_end] - ret operators: db 1,'+',80h diff --git a/SOURCE/PREPROCE.INC b/SOURCE/PREPROCE.INC index 653fe6f..6317de8 100644 --- a/SOURCE/PREPROCE.INC +++ b/SOURCE/PREPROCE.INC @@ -307,11 +307,9 @@ preprocess_line: mov byte [edx-2],3Bh movzx ebx,ax add ebx,preprocessor - xor eax,eax jmp near ebx not_preprocessor_directive: - mov al,cl - xor ah,ah + xor ch,ch call get_macro jc not_macro mov byte [edx-2],3Bh @@ -342,7 +340,8 @@ preprocess_line: je define_equ_constant mov al,3 not_symbolic_constant: - mov ah,1 + mov ch,1 + mov cl,al call get_macro jc not_preprocessor_symbol mov al,3Ah @@ -418,30 +417,153 @@ preprocess_line: pop [struc_name] ret -get_macro: - mov edx,esi - mov ebp,edi - mov ebx,[free_additional_memory] - check_macro: - mov cl,al - cmp ebx,[macros_list] - je no_macro_found - sub ebx,8 - cmp ax,[ebx] - jne check_macro - mov edi,[ebx+4] - repe cmps byte [esi],[edi] - je macro_ok - mov esi,edx - jmp check_macro - no_macro_found: - mov edi,ebp - stc +define_fix_constant: + add esi,3 + push ebp esi + call process_fix_constants + mov esi,[esp+4] + movzx ecx,byte [esi-1] + mov [value_type],1 + call find_symbolic_constant + jc allocate_new_fix_constant + mov ebx,edx + jmp make_fix_constant + allocate_new_fix_constant: + mov edx,[labels_list] + sub edx,16 + cmp edx,[free_additional_memory] + jb out_of_memory + mov [labels_list],edx + make_fix_constant: + pop ebx + mov ecx,edi + dec ecx + sub ecx,ebx + mov [edx+8],ecx + mov [edx+12],ebx + pop ebx + mov byte [ebx-2],3Bh + mov ch,1 + mov cl,[ebx-1] + push edx + call hash_constant + pop edx + mov [edx],eax + mov [edx+4],ebx + inc [fix_constants_count] + jmp line_preprocessed +define_equ_constant: + add esi,3 + push esi + call process_equ_constants + pop ebx + mov edx,[labels_list] + sub edx,16 + cmp edx,[free_additional_memory] + jb out_of_memory + mov [labels_list],edx + mov ecx,edi + dec ecx + sub ecx,ebx + mov [edx+8],ecx + mov [edx+12],ebx + mov ebx,[struc_name] + mov byte [ebx-2],3Bh + xor ch,ch + mov cl,[ebx-1] + push edx + call hash_constant + pop edx + mov [edx],eax + mov [edx+4],ebx + inc [equ_constants_count] + jmp line_preprocessed +hash_constant: + push esi ebp + mov esi,ebx + xor ebx,ebx + mov eax,2166136261 + mov ebp,16777619 + hash_constant_name: + xor al,[esi+ebx] + mul ebp + inc bl + cmp bl,cl + jb hash_constant_name + mov ebp,eax + and ebp,2FFh shl 22 + shl eax,10 + xor eax,ebp + or ax,cx + mov ebx,esi + pop ebp esi ret - macro_ok: - mov edi,ebp +restore_equ_constant: + lods byte [esi] + cmp al,1Ah + jne invalid_name + movzx ecx,byte [esi] + inc esi + mov [value_type],0 + 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,16-4 + sub esi,4 + std + rep movs dword [edi],[esi] + cld + dec [equ_constants_count] + mov esi,ebx + mov edi,edx + jmp constant_restored + no_symbolic_constant: + add esi,ecx + constant_restored: + lods byte [esi] + cmp al,',' + je restore_equ_constant + or al,al + jnz extra_characters_on_line + jmp line_preprocessed +find_symbolic_constant: + push edi + mov ebx,esi + mov ch,[value_type] + call hash_constant + movzx ecx,al + mov edx,[labels_list] + align 16 + scan_symbolic_constants: + cmp edx,[additional_memory_end] + je symbolic_constants_ok + cmp eax,[edx] + je check_symbolic_constant + next_symbolic_constant: + add edx,16 + jmp scan_symbolic_constants + check_symbolic_constant: + mov edi,[edx+4] + repe cmps byte [esi],[edi] + mov cl,al + je symbolic_constant_found + mov esi,ebx + jmp next_symbolic_constant + symbolic_constant_found: + pop edi clc ret + symbolic_constants_ok: + pop edi + stc + ret process_fix_constants: cmp [fix_constants_count],0 je no_symbolic_constants @@ -450,7 +572,8 @@ process_fix_constants: process_equ_constants: cmp [equ_constants_count],0 je no_symbolic_constants - mov [value_type],2 + mov [value_type],0 + align 16 process_symbolic_constants: mov ebp,esi lods byte [esi] @@ -474,42 +597,13 @@ process_equ_constants: jnc replace_symbolic_constant add esi,ecx jmp process_symbolic_constants - find_symbolic_constant: - push edi - mov ebx,esi - mov eax,ecx - mov edx,[labels_list] - scan_symbolic_constants: - mov esi,ebx - mov ecx,eax - cmp edx,[additional_memory_end] - je symbolic_constants_ok - mov al,[value_type] - cmp al,[edx+1] - mov eax,ecx - jne next_symbolic_constant - cmp cl,[edx] - jne next_symbolic_constant - mov edi,[edx+4] - repe cmps byte [esi],[edi] - je symbolic_constant_found - next_symbolic_constant: - add edx,16 - jmp scan_symbolic_constants - symbolic_constants_ok: - pop edi - stc - ret - symbolic_constant_found: - pop edi - clc - ret replace_symbolic_constant: mov ecx,[edx+8] mov edx,[edx+12] xchg esi,edx call move_data mov esi,edx + align 16 process_after_replaced: lods byte [esi] cmp al,1Ah @@ -525,22 +619,21 @@ process_equ_constants: call move_data ret move_data: - xor eax,eax shr ecx,1 - rcl al,1 + jnc movsb_ok + movs byte [edi],[esi] + movsb_ok: shr ecx,1 - rcl ah,1 + jnc movsw_ok + movs word [edi],[esi] + movsw_ok: rep movs dword [edi],[esi] - mov cl,ah - rep movs word [edi],[esi] - mov cl,al - rep movs byte [edi],[esi] ret string_after_replaced: lods dword [esi] stos dword [edi] mov ecx,eax - rep movs byte [edi],[esi] + call move_data jmp process_after_replaced symbol_after_replaced: movzx ecx,byte [esi] @@ -550,7 +643,7 @@ process_equ_constants: mov al,1Ah mov ah,cl stos word [edi] - rep movs byte [edi],[esi] + call move_data jmp process_after_replaced process_concatenations: xor dl,dl @@ -700,117 +793,64 @@ process_concatenations: mov ecx,eax rep movs byte [edi],[esi] jmp after_concatenation -include_file: - lods byte [esi] - cmp al,22h - jne invalid_argument - lods dword [esi] + +get_macro: + call hash_macro mov edx,esi - add esi,eax - cmp byte [esi],0 - jne extra_characters_on_line - call preprocess_file - jc file_not_found - jmp line_preprocessed -define_fix_constant: - add esi,3 - push ebp esi - call process_fix_constants - mov esi,[esp+4] - movzx ecx,byte [esi-1] - mov [value_type],1 - call find_symbolic_constant - jc allocate_new_fix_constant - mov ebx,edx - jmp make_fix_constant - allocate_new_fix_constant: - mov edx,[labels_list] - sub edx,16 - cmp edx,[free_additional_memory] - jb out_of_memory - mov [labels_list],edx - make_fix_constant: - pop ebx - mov ecx,edi - dec ecx - sub ecx,ebx - mov [edx+8],ecx - mov [edx+12],ebx - pop ebx - mov byte [ebx-2],3Bh - mov al,[ebx-1] - mov [edx],al - mov [edx+4],ebx - mov byte [edx+1],1 - inc [fix_constants_count] - jmp line_preprocessed -define_equ_constant: - add esi,3 - push esi - call process_equ_constants - pop ebx - mov edx,[labels_list] - sub edx,16 - cmp edx,[free_additional_memory] - jb out_of_memory - mov [labels_list],edx - mov ecx,edi - dec ecx - sub ecx,ebx - mov [edx+8],ecx - mov [edx+12],ebx - mov ebx,[struc_name] - mov byte [ebx-2],3Bh - mov al,[ebx-1] - mov [edx],al - mov [edx+4],ebx - mov byte [edx+1],2 - inc [equ_constants_count] - jmp line_preprocessed -restore_equ_constant: - lods byte [esi] - cmp al,1Ah - jne invalid_name - movzx ecx,byte [esi] - inc esi - mov [value_type],2 - 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,16-4 - sub esi,4 - std - rep movs dword [edi],[esi] - cld - dec [equ_constants_count] - mov esi,ebx - mov edi,edx - jmp constant_restored - no_symbolic_constant: - add esi,ecx - constant_restored: - lods byte [esi] - cmp al,',' - je restore_equ_constant - or al,al - jnz extra_characters_on_line - jmp line_preprocessed -define_struc: - or ah,1 -define_macro: - lods byte [esi] - cmp al,1Ah - jne invalid_name - lods byte [esi] + mov ebp,edi mov ebx,[free_additional_memory] - mov [ebx],ax + movzx ecx,cl + align 16 + check_macro: + cmp ebx,[macros_list] + je no_macro_found + sub ebx,8 + cmp eax,[ebx] + jne check_macro + mov edi,[ebx+4] + repe cmps byte [esi],[edi] + mov cl,al + je macro_ok + mov esi,edx + jmp check_macro + macro_ok: + mov edi,ebp + clc + ret + no_macro_found: + mov edi,ebp + stc + ret +hash_macro: + xor ebx,ebx + mov eax,2166136261 + mov ebp,16777619 + hash_macro_name: + xor al,[esi+ebx] + mul ebp + inc bl + cmp bl,cl + jb hash_macro_name + mov ebp,eax + and ebp,2FFh shl 22 + shl eax,10 + xor eax,ebp + or ax,cx + ret +define_struc: + mov ch,1 + jmp make_macro +define_macro: + xor ch,ch + make_macro: + lods byte [esi] + cmp al,1Ah + jne invalid_name + lods byte [esi] + mov cl,al + call hash_macro + mov ebx,[free_additional_memory] + mov [ebx],eax mov [ebx+4],esi add ebx,8 cmp ebx,[labels_list] @@ -907,10 +947,11 @@ purge_macro: cmp al,1Ah jne invalid_name lods byte [esi] - xor ah,ah + xor ch,ch + mov cl,al call get_macro jc macro_purged - or byte [ebx+1],80h + or byte [ebx+1],2 macro_purged: lods byte [esi] cmp al,',' @@ -923,7 +964,7 @@ use_macro: push [counter] [counter_limit] push dword [macro_status] or [macro_status],10h - or byte [ebx+1],80h + or byte [ebx+1],2 mov edx,esi mov eax,[ebx+4] movzx esi,byte [ebx] @@ -1094,6 +1135,7 @@ use_macro: jz process_macro mov ax,3Bh stos word [edi] + align 16 process_macro: lods byte [esi] cmp al,'}' @@ -1357,7 +1399,7 @@ use_macro: macro_block_processed: call close_macro_block jc process_macro_line - and byte [ebx+1],not 80h + and byte [ebx+1],not 2 pop [current_line] mov eax,[macro_constants] mov [memory_end],eax @@ -1414,6 +1456,19 @@ use_macro: pop edi jmp line_preprocessed +include_file: + lods byte [esi] + cmp al,22h + jne invalid_argument + lods dword [esi] + mov edx,esi + add esi,eax + cmp byte [esi],0 + jne extra_characters_on_line + call preprocess_file + jc file_not_found + jmp line_preprocessed + increase_counter: movzx ecx,byte [eax] counter_loop: diff --git a/SOURCE/VERSION.INC b/SOURCE/VERSION.INC index 7a18124..435ec28 100644 --- a/SOURCE/VERSION.INC +++ b/SOURCE/VERSION.INC @@ -1,6 +1,6 @@ -; flat assembler version 1.50 -; Copyright (c) 1999-2003, Tomasz Grysztar. +; flat assembler version 1.51 +; Copyright (c) 1999-2004, 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.50" +VERSION_STRING equ "1.51" VERSION_MAJOR = 1 -VERSION_MINOR = 50 +VERSION_MINOR = 51 diff --git a/SOURCE/WIN32/FASM.ASM b/SOURCE/WIN32/FASM.ASM index a74f9f1..bce5d5f 100644 --- a/SOURCE/WIN32/FASM.ASM +++ b/SOURCE/WIN32/FASM.ASM @@ -3,97 +3,97 @@ ; Copyright (c) 1999-2003, Tomasz Grysztar. ; All rights reserved. - format PE console + format PE console start: - mov esi,_logo - call display_string + mov esi,_logo + call display_string - call get_params - cmp [params],0 - je information - lea eax,[params+1] - mov [input_file],eax - movzx ecx,byte [eax-1] - add eax,ecx - cmp byte [eax],0 - je information - inc eax - mov [output_file],eax - movzx ecx,byte [eax-1] - add eax,ecx - cmp byte [eax],0 - jne information + call get_params + cmp [params],0 + je information + lea eax,[params+1] + mov [input_file],eax + movzx ecx,byte [eax-1] + add eax,ecx + cmp byte [eax],0 + 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 + call init_memory - mov edi,characters - mov ecx,100h - xor al,al + mov edi,characters + mov ecx,100h + xor al,al make_characters_table: - stosb - inc al - loop make_characters_table - mov esi,characters+'a' - mov edi,characters+'A' - mov ecx,26 - rep movsb - mov edi,characters - mov esi,symbol_characters+1 - movzx ecx,byte [esi-1] - xor eax,eax + stosb + inc al + loop make_characters_table + mov esi,characters+'a' + mov edi,characters+'A' + mov ecx,26 + rep movsb + mov edi,characters + mov esi,symbol_characters+1 + movzx ecx,byte [esi-1] + xor eax,eax convert_table: - lodsb - mov byte [edi+eax],0 - loop convert_table - mov [display_buffer],0 + lodsb + mov byte [edi+eax],0 + loop convert_table + mov [display_buffer],0 - call [GetTickCount] - mov [start_time],eax + call [GetTickCount] + mov [start_time],eax - call preprocessor - call parser - call assembler - call formatter + call preprocessor + call parser + call assembler + call formatter - call display_user_messages - movzx eax,[current_pass] - inc eax - call display_number - mov esi,_passes_suffix - call display_string - call [GetTickCount] - sub eax,[start_time] - xor edx,edx - mov ebx,100 - div ebx - or eax,eax - jz display_bytes_count - xor edx,edx - mov ebx,10 - div ebx - push edx - call display_number - mov dl,'.' - call display_character - pop eax - call display_number - mov esi,_seconds_suffix - call display_string + call display_user_messages + movzx eax,[current_pass] + inc eax + call display_number + mov esi,_passes_suffix + call display_string + call [GetTickCount] + sub eax,[start_time] + xor edx,edx + mov ebx,100 + div ebx + or eax,eax + jz display_bytes_count + xor edx,edx + mov ebx,10 + div ebx + push edx + call display_number + mov dl,'.' + call display_character + pop eax + call display_number + mov esi,_seconds_suffix + call display_string display_bytes_count: - mov eax,[written_size] - call display_number - mov esi,_bytes_suffix - call display_string - xor al,al - jmp exit_program + mov eax,[written_size] + call display_number + mov esi,_bytes_suffix + call display_string + xor al,al + jmp exit_program information: - mov esi,_usage - call display_string - mov al,1 - jmp exit_program + mov esi,_usage + call display_string + mov al,1 + jmp exit_program include 'system.inc' @@ -149,6 +149,8 @@ anonymous_forward dd ? current_locals_prefix dd ? labels_list dd ? label_hash dd ? +label_leaf dd ? +hash_tree dd ? org_origin dd ? org_registers dd ? org_start dd ? diff --git a/SOURCE/WIN32/SYSTEM.INC b/SOURCE/WIN32/SYSTEM.INC index 6320dd7..58c3d1a 100644 --- a/SOURCE/WIN32/SYSTEM.INC +++ b/SOURCE/WIN32/SYSTEM.INC @@ -49,6 +49,7 @@ init_memory: allocate_memory: mov edx,eax shr edx,3 + imul edx,3 mov ecx,eax sub ecx,edx mov [memory_end],ecx diff --git a/SOURCE/X86.INC b/SOURCE/X86.INC index ad1736c..1e606f5 100644 --- a/SOURCE/X86.INC +++ b/SOURCE/X86.INC @@ -4436,8 +4436,9 @@ fild_instruction: jmp instruction_assembled fild_mem_64bit: mov al,[postbyte_register] - cmp al,0 - je fild_mem_64bit_store + cmp al,1 + je fisttp_64bit_store + jb fild_mem_64bit_store dec [postbyte_register] cmp al,3 je fild_mem_64bit_store @@ -4447,6 +4448,11 @@ fild_instruction: mov [base_code],0DFh call store_instruction jmp instruction_assembled + fisttp_64bit_store: + mov [base_code],0DDh + call store_instruction + jmp instruction_assembled + fbld_instruction: mov [postbyte_register],al lods byte [esi] @@ -4902,6 +4908,31 @@ movdq_instruction: mov al,bl stos byte [edi] jmp instruction_assembled +lddqu_instruction: + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_mmx_register + cmp ah,16 + jne invalid_operand_size + push eax + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + pop eax + mov [postbyte_register],al + mov [mmx_prefix],0F2h + mov [base_code],0Fh + mov [extended_code],0F0h + call store_mmx_instruction + jmp instruction_assembled movq2dq_instruction: lods byte [esi] call get_size_operator @@ -5886,6 +5917,46 @@ movnti_instruction: mov [postbyte_register],al call store_instruction jmp instruction_assembled +monitor_instruction: + mov [postbyte_register],al + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_register + cmp ax,0400h + jne invalid_operand + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_register + cmp ax,0401h + jne invalid_operand + cmp [postbyte_register],0C8h + jne monitor_instruction_store + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_register + cmp ax,0402h + jne invalid_operand + monitor_instruction_store: + mov ax,010Fh + stos word [edi] + mov al,[postbyte_register] + stos byte [edi] + jmp instruction_assembled convert_register: mov ah,al @@ -7030,6 +7101,8 @@ instructions_5: dw loop_instruction_32bit-assembler db 'label',0 dw label_directive-assembler + db 'lddqu',0 + dw lddqu_instruction-assembler db 'leave',0C9h dw simple_instruction-assembler db 'lodsb',0ACh @@ -7082,6 +7155,8 @@ instructions_5: dw sse_sd_instruction-assembler db 'mulss',59h dw sse_ss_instruction-assembler + db 'mwait',0C9h + dw monitor_instruction-assembler db 'outsb',6Eh dw simple_instruction-assembler db 'outsd',6Fh @@ -7312,6 +7387,8 @@ instructions_6: dw fi_instruction-assembler db 'fidivr',7 dw fi_instruction-assembler + db 'fisttp',1 + dw fild_instruction-assembler db 'fisubr',5 dw fi_instruction-assembler db 'fldenv',4 @@ -7360,6 +7437,14 @@ instructions_6: dw ffree_instruction-assembler db 'fxsave',0 dw fxsave_instruction-assembler + db 'haddpd',07Ch + dw sse_pd_instruction-assembler + db 'haddps',07Ch + dw cvtpd2dq_instruction-assembler + db 'hsubpd',07Dh + dw sse_pd_instruction-assembler + db 'hsubps',07Dh + dw cvtpd2dq_instruction-assembler db 'invlpg',0 dw invlpg_instruction-assembler db 'lfence',0E8h @@ -7558,6 +7643,10 @@ instructions_7: dw loop_instruction_32bit-assembler db 'loopnzw',0E0h dw loop_instruction_16bit-assembler + db 'monitor',0C8h + dw monitor_instruction-assembler + db 'movddup',12h + dw sse_sd_instruction-assembler db 'movdq2q',0 dw movdq2q_instruction-assembler db 'movhlps',12h @@ -7636,6 +7725,10 @@ instructions_7: dw virtual_directive-assembler db 0 instructions_8: + db 'addsubpd',0D0h + dw sse_pd_instruction-assembler + db 'addsubps',0D0h + dw cvtpd2dq_instruction-assembler db 'cmpneqpd',4 dw cmp_pd_instruction-assembler db 'cmpneqps',4 @@ -7708,6 +7801,10 @@ instructions_8: dw movmskpd_instruction-assembler db 'movmskps',0 dw movmskps_instruction-assembler + db 'movshdup',16h + dw cvtdq2pd_instruction-assembler + db 'movsldup',12h + dw cvtdq2pd_instruction-assembler db 'packssdw',6Bh dw mmx_instruction-assembler db 'packsswb',63h diff --git a/WHATSNEW.TXT b/WHATSNEW.TXT index ca2baed..0d18e88 100644 --- a/WHATSNEW.TXT +++ b/WHATSNEW.TXT @@ -1,6 +1,13 @@ Visit http://flatassembler.net/ for more information +version 1.51 +[31-01-2004] +------------ +[+] added SSE3 instructions +[-] speed improvements +[-] few more bugs fixed + version 1.50 [08-12-2003] ------------