diff --git a/FASM.TXT b/FASM.TXT index 27d238e..a6c2f6a 100644 --- a/FASM.TXT +++ b/FASM.TXT @@ -1,12 +1,12 @@ - Üßßß - ÜÜŪÜÜ ÜÜÜÜ ÜÜÜÜÜ ÜÜÜ ÜÜ - Ū Ū Ū Ū Ū Ū - Ū ÜßßßßŪ ßßßßÜ Ū Ū Ū - Ū ßÜÜÜÜŪÜ ÜÜÜÜÜß Ū Ū Ū + Üßßß + ÜÜŪÜÜ ÜÜÜÜ ÜÜÜÜÜ ÜÜÜ ÜÜ + Ū Ū Ū Ū Ū Ū + Ū ÜßßßßŪ ßßßßÜ Ū Ū Ū + Ū ßÜÜÜÜŪÜ ÜÜÜÜÜß Ū Ū Ū - flat assembler 1.43 - Programmer's Manual + flat assembler 1.44 + Programmer's Manual Table of contents @@ -14,57 +14,57 @@ 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 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 @@ -119,23 +119,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.42 +flat assembler version 1.44 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.42 +flat assembler version 1.44 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.42 +flat assembler version 1.44 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 @@ -143,9 +143,9 @@ encountered an unrecognized instruction. When the line that caused error contains a macroinstruction, also number of erroneous line inside the macroinstruction is gived: -flat assembler version 1.42 +flat assembler version 1.44 example.asm [6] stoschar [2]: - stoschar 7 + stoschar 7 error: illegal instruction. It means that the macroinstruction in the sixth line of the "example.asm" file @@ -217,21 +217,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 dr4 dr5 dr6 dr7 ³ + ³ Debug ³ 32 ³ dr0 dr1 dr2 dr3 dr4 dr5 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 +274,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 ³ ĄÄÄÄÄÄÄÄÄÄĮÄÄÄÄÄÄÄÄĮÄÄÄÄÄÄÄÄÄŁ @@ -397,19 +397,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 ³ ĄÄÄÄÄÄÄÄÄÄÄĮÄÄÄÄÄÄÄÄÄÄÄÄÄÄŁ @@ -491,14 +491,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 @@ -508,7 +508,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 @@ -522,10 +522,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, @@ -544,9 +544,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 @@ -572,10 +572,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 @@ -588,10 +588,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 @@ -601,7 +601,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 @@ -658,11 +658,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 @@ -743,9 +743,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 @@ -758,7 +758,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 @@ -768,9 +768,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 @@ -817,7 +817,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 @@ -838,9 +838,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 @@ -877,53 +877,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 ³ jump if 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 @@ -972,8 +972,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 @@ -981,8 +981,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 @@ -1012,7 +1012,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 @@ -1022,7 +1022,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 @@ -1031,8 +1031,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 @@ -1041,26 +1041,26 @@ 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,dword [gs:esi] ; output double 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 repeated string operation. When a string operation instruction has a repeat @@ -1076,8 +1076,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 @@ -1104,14 +1104,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 @@ -1143,7 +1143,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. @@ -1204,15 +1204,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 should be a word, it can be a general register or 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 @@ -1220,7 +1220,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 @@ -1255,7 +1255,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 @@ -1301,7 +1301,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) @@ -1317,7 +1317,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 @@ -1335,7 +1335,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 @@ -1364,7 +1364,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 @@ -1418,8 +1418,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 @@ -1447,21 +1447,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 @@ -1501,7 +1501,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 @@ -1518,7 +1518,7 @@ can be also a MMX register or 64-bit memory location. "movd" copies a double word from the source operand to the destination operand. One of the operands must be a MMX register, the second one can be a -general register or 32-bit memory location. Only lo double word of MMX +general register or 32-bit memory location. Only low double word of MMX register is used. All general MMX operations have two operands, the destination operand should be a MMX register, the source operand can be a MMX register or 64-bit memory @@ -1573,7 +1573,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 @@ -1657,16 +1657,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, @@ -1685,7 +1685,7 @@ bits 4 and 5 select the value to be moved from the source operand to the third double word, and bits 6 and 7 select the value to be moved from the source operand to the high double word of the result. - shufps xmm0,xmm0,10010011b ; shuffle single precision values + shufps xmm0,xmm0,10010011b ; shuffle double words "unpckhps" performs an interleaved unpack of the values from the high parts of the source and destination operands and stores the result in the @@ -1787,7 +1787,7 @@ from the specified 512-byte memory location. The memory operand for both those instructions must be aligned on 16 byte boundary. -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 @@ -1878,7 +1878,7 @@ operand. "cvtpd2dq" and "cvttpd2dq" convert packed double precision floating point values to packed two double word integers, storing the result in the low quad word of the destination operand. "cvtdq2ps" converts packed four double word integers to packed single precision floating point values. -"cvtdq2pd" converts packed tw double word integers from the low quad word +"cvtdq2pd" converts packed two double word integers from the low quad word of the source operand to packed double precision floating point values. For all these instruction destination operand must be a SSE register, the source operand can be a 128-bit memory location or SSE register. @@ -1916,9 +1916,9 @@ of low double words from each corresponding quad words and returns the results in packed quad words. These instructions follow the same rules for operands as the general MMX operations described in 2.1.14. "pslldq" and "psrldq" perform logical shift left or right of the double -quad word in the destination operand by the amount specified in the source -operand. The destination operand should be a SSE register, source operand -should be an 8-bit immediate value. +quad word in the destination operand by the amount of bits specified in the +source operand. The destination operand should be a SSE register, source +operand should be an 8-bit immediate value. "punpckhqdq" interleaves the high quad word of the source operand and the high quad word of the destination operand and writes them to the destination SSE register. "punpcklqdq" interleaves the low quad word of the source operand @@ -1947,7 +1947,7 @@ 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 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 @@ -2027,8 +2027,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 @@ -2054,21 +2054,22 @@ logical operators are "~" for logical negation, "&" for logical and, "|" for logical or. The negation has the highest priority. Logical value can be a numerical expression, it will be false if it is equal to zero, otherwise it will be true. Two numerical expression can be compared using one of the -following operators to make the looical value: "=" (equal), "<" (less), +following operators to make the logical value: "=" (equal), "<" (less), ">" (greater), "<=" (less or equal), ">=" (greater or equal), -"<>" (not equal). The "eq" compares any two symbol whether they are exactly +"<>" (not equal). The "eq" compares any two symbols whether they are exactly the same. The "in" operator checks whether given symbol is a member of the list of symbols following this operator, the list should be enclosed between "<" and ">" characters, its members should be separated with commas. The -"defined" and "used" operators should be followed by a symbol name, "defined" -checks whether given symbol was defined, "used" checks whether given symbol is -used somewhere. +"eqtype" operator compares any two symbols whether they are of the same type. +The "defined" and "used" operators should be followed by a symbol name, +"defined" checks whether given symbol was defined, "used" checks whether +given symbol is used somewhere. The following simple example uses the "count" constant that should be 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 @@ -2077,14 +2078,14 @@ is greater than 0. "reg" is 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 @@ -2094,7 +2095,7 @@ assembled whether the value of "reg" is AX register or not. defined yet: if ~defined var & used var - var db 0 + var db 0 end if The directive that defines "var" will be processed only if such symbol was @@ -2112,8 +2113,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. @@ -2121,8 +2122,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 @@ -2134,9 +2135,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 @@ -2150,16 +2151,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 @@ -2265,8 +2266,8 @@ For example: macro stos0 { - xor al,al - stosb + xor al,al + stosb } The macroinstruction "stos0" will be replaced with these two assembly @@ -2292,10 +2293,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 } @@ -2308,10 +2309,10 @@ macroinstruction of that name, which will use the previous macroinstruction: macro mov op1,op2,op3 { if arg3 eq - mov op1,op2 + mov op1,op2 else - mov op1,op2 - mov op2,op3 + mov op1,op2 + mov op2,op3 end if } @@ -2342,8 +2343,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 @@ -2366,12 +2367,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 @@ -2396,12 +2397,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 @@ -2449,41 +2450,37 @@ 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 "jae exit" instructions. To make macroinstruction behaving differently when some of the arguments are -a quoted strings or not, you can utilize the fact that assembler distinguishes -the separate quoted strings from the quoted strings inside numerical -expressions, but it doesn't distinguish the numerical expression preceded by -the "+" sign from the same expression without a sign. So the string preceded -by the "+" sign will be treated as a numerical expression and so won't be -symbolically equal to the same string without any sign, while any other value -will be symbolically equal to the same expression preceded by the "+" sign. -Here's an example macroinstruction utilizing this feature: +of some special type, for example a quoted strings, you can use "eqtype" +comparision operator. Here's an example of utilizing it to distinguish a +quoted string from an other argument: macro message arg { - if arg eq +arg - mov dx,arg + if arg eqtype "" + local str + jmp @f + str db arg,0Dh,0Ah,24h + @@: + mov dx,str else - local str - jmp @f - str db arg,0Dh,0Ah,24h - @@: - mov dx,str + 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 -argument of this macro is some number or label, the string from at address is -displayed, but when the argument is a quoted string, the created code will -display that string followed by the carriage return and line feed. +argument of this macro is some number, label, or variable, the string from +that address is displayed, but when the argument is a quoted string, the +created code will display that string followed by the carriage return and +line feed. 2.3.4 Structures @@ -2502,8 +2499,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 @@ -2515,9 +2512,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 @@ -2539,7 +2536,8 @@ Default output format is a flat binary file, it can also be selected by using 32-bit code, omitting the default setting for selected output format. "org" directive sets address at which the following code is expected to appear in memory. It should be followed by numerical expression specifying -the address. +the address. You can also use this directive in the "$=" form followed by +numerical expression. Below are described different output formats with the directives specific to these formats. diff --git a/LICENSE.TXT b/LICENSE.TXT index e7a606b..85513e3 100644 --- a/LICENSE.TXT +++ b/LICENSE.TXT @@ -1,5 +1,5 @@ -flat assembler version 1.43 +flat assembler version 1.44 Copyright (c) 1999-2003, Tomasz Grysztar. All rights reserved. diff --git a/SOURCE/ASSEMBLE.INC b/SOURCE/ASSEMBLE.INC index b8f1f15..e1432c9 100644 --- a/SOURCE/ASSEMBLE.INC +++ b/SOURCE/ASSEMBLE.INC @@ -4,9 +4,15 @@ ; All rights reserved. assembler: - mov edi,[labels_list] mov ecx,[memory_end] - sub ecx,edi + mov edi,ecx + sub ecx,[labels_list] + shr ecx,3 + imul ecx,20 + sub edi,ecx + cmp edi,[code_start] + jbe out_of_memory + mov [labels_list],edi shr ecx,2 xor eax,eax rep stos dword [edi] @@ -68,17 +74,17 @@ assembler: jz symbol_defined_ok sub cl,[eax+9] cmp cl,1 - jne check_next_symbol + jne symbol_defined_ok and byte [eax+8],not 1 or [next_pass_needed],-1 symbol_defined_ok: + test byte [eax+8],10h + jz check_next_symbol mov cl,[current_pass] - cmp cl,[eax+18] - jne check_next_symbol - cmp byte [eax+19],1 - je check_used_prediction - cmp byte [eax+19],2 + cmp cl,[eax+17] jne check_next_symbol + test byte [eax+8],20h + jnz check_used_prediction cmp cl,[eax+16] jne check_next_symbol test byte [eax+8],8 @@ -200,6 +206,12 @@ assemble_line: jmp continue_line define_constant: lods dword [esi] + inc esi + or eax,eax + jz org_directive + cmp eax,0Fh + jb invalid_use_of_symbol + je reserved_word_used_as_symbol mov edx,[eax+8] push edx cmp [current_pass],0 @@ -213,7 +225,7 @@ assemble_line: mov [eax+8],dl get_constant_value: push eax - lods byte [esi] + mov al,byte [esi-1] push eax call get_value pop ebx diff --git a/SOURCE/DOS/SYSTEM.INC b/SOURCE/DOS/SYSTEM.INC index e361712..eb34481 100644 --- a/SOURCE/DOS/SYSTEM.INC +++ b/SOURCE/DOS/SYSTEM.INC @@ -654,7 +654,10 @@ make_timestamp: mov eax,ecx shr eax,1 add ebp,eax + cmp ecx,2 + jb months_correction_ok sub ebp,2 + months_correction_ok: cmp ecx,2 jbe day_correction_ok pop cx diff --git a/SOURCE/EXPRESSI.INC b/SOURCE/EXPRESSI.INC index ee269e2..54ba7f3 100644 --- a/SOURCE/EXPRESSI.INC +++ b/SOURCE/EXPRESSI.INC @@ -1999,6 +1999,8 @@ get_logical_value: find_eq_symbol: cmp byte [esi],81h je compare_symbols + cmp byte [esi],87h + je compare_symbol_types cmp byte [esi],83h je scan_symbols_list call check_character @@ -2031,6 +2033,40 @@ get_logical_value: call check_character jc return_true jmp symbols_different + + compare_symbol_types: + inc esi + pop ebx + type_comparision: + call check_character + jc types_compared + mov al,[esi] + cmp al,[ebx] + jne symbols_different + cmp al,'(' + jne equal_type + mov al,[esi+1] + mov ah,[ebx+1] + cmp al,ah + je equal_type + or al,al + jz symbols_different + or ah,ah + jz symbols_different + cmp al,'.' + je symbols_different + cmp ah,'.' + je symbols_different + equal_type: + call skip_symbol + xchg esi,ebx + call skip_symbol + xchg esi,ebx + jmp type_comparision + types_compared: + cmp byte [ebx],87h + jne return_false + jmp return_true scan_symbols_list: or bl,bl jnz invalid_expression @@ -2211,25 +2247,22 @@ get_logical_value: jb invalid_use_of_symbol je reserved_word_used_as_symbol inc esi + or byte [eax+8],10h test byte [eax+8],8 - jz never_used + jz not_used mov cl,[current_pass] sub cl,[eax+16] cmp cl,1 jb return_true ja not_used mov cl,[current_pass] - mov [eax+18],cl - mov byte [eax+19],1 + mov [eax+17],cl + or byte [eax+8],20h jmp return_true - never_used: - cmp [current_pass],0 - jne not_used - or [next_pass_needed],-1 not_used: mov cl,[current_pass] - mov [eax+18],cl - mov byte [eax+19],2 + mov [eax+17],cl + and byte [eax+8],not 20h return_false: xor al,al jmp logical_value_ok diff --git a/SOURCE/PARSER.INC b/SOURCE/PARSER.INC index 3d3a2c0..68c0be7 100644 --- a/SOURCE/PARSER.INC +++ b/SOURCE/PARSER.INC @@ -123,9 +123,8 @@ parse_line: call get_label_id cmp eax,10h jb label_identified - mov ebx,[eax+4] - cmp ebx,eax - je anonymous_label_name + or ebx,ebx + jz anonymous_label_name dec ebx mov [current_locals_prefix],ebx label_identified: @@ -762,37 +761,36 @@ get_label_id: or eax,eax jnz anonymous_ok mov eax,[labels_list] - sub eax,20 + sub eax,8 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 + xor ebx,ebx + jmp make_label_id anonymous_back: add esi,2 mov eax,[anonymous_reverse] or eax,eax jz invalid_value - ret + jmp anonymous_ok new_anonymous: add esi,2 mov eax,[anonymous_forward] or eax,eax jnz new_anonymous_ok mov eax,[labels_list] - sub eax,20 + sub eax,8 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 + jmp anonymous_ok standard_label: cmp ecx,1 jne find_label @@ -832,24 +830,10 @@ get_label_id: mov ebx,esi mov edx,ecx mov eax,[labels_list] - check_label: - mov esi,ebx - mov ecx,edx cmp eax,[memory_end] - je add_label - cmp ebp,[eax] - jne next_label - mov edi,[eax+4] - repe cmps byte [esi],[edi] - je label_found - next_label: - add eax,20 - jmp check_label - label_found: - add esp,4 - pop edi - ret + jne scan_hashes add_label: + mov ecx,edx pop esi cmp byte [esi-1],0 je label_name_ok @@ -880,20 +864,46 @@ get_label_id: jnc reserved_word label_name_ok: mov eax,[labels_list] - sub eax,20 + sub eax,8 mov [labels_list],eax mov [eax+4],esi + mov ebx,esi add esi,ecx mov edx,[label_hash] mov [eax],edx pop edi cmp eax,edi jbe out_of_memory - ret + 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] + sar eax,3 + imul eax,20 + add eax,[memory_end] + ret operators: db 1,'+',80h @@ -920,6 +930,7 @@ directive_operators: db 2,'at',80h db 7,'defined',88h db 2,'eq',81h + db 6,'eqtype',87h db 4,'from',82h db 2,'in',83h db 2,'on',84h diff --git a/SOURCE/PREPROCE.INC b/SOURCE/PREPROCE.INC index 7a97148..14b6610 100644 --- a/SOURCE/PREPROCE.INC +++ b/SOURCE/PREPROCE.INC @@ -293,9 +293,23 @@ preprocess_line: je preprocess_instruction cmp al,1Ah jne not_preprocessor_symbol - cmp dword [esi],3+'equ' shl 8 - je define_symbolic_constant lods byte [esi] + cmp al,3 + jne not_symbolic_constant + mov ebx,characters + movzx eax,byte [esi] + xlat byte [ebx] + ror eax,8 + mov al,[esi+1] + xlat byte [ebx] + ror eax,8 + mov al,[esi+2] + xlat byte [ebx] + ror eax,16 + cmp eax,'equ' + je define_symbolic_constant + mov al,3 + not_symbolic_constant: mov ah,1 call get_macro jc not_preprocessor_symbol @@ -370,7 +384,7 @@ process_symbolic_constants: mov ecx,eax mov esi,ebx cmp edx,[additional_memory_end] - je not_symbolic_constant + je symbolic_constants_ok cmp al,[edx] jne next_symbolic_constant mov edi,[edx+4] @@ -379,7 +393,7 @@ process_symbolic_constants: next_symbolic_constant: add edx,16 jmp scan_symbolic_constants - not_symbolic_constant: + symbolic_constants_ok: pop edi stc ret @@ -525,7 +539,7 @@ include_file: jc file_not_found jmp line_preprocessed define_symbolic_constant: - add esi,4 + add esi,3 push esi call process_symbolic_constants pop ebx diff --git a/SOURCE/VERSION.INC b/SOURCE/VERSION.INC index f2f17df..d9d8e21 100644 --- a/SOURCE/VERSION.INC +++ b/SOURCE/VERSION.INC @@ -1,5 +1,5 @@ -; flat assembler version 1.43 +; flat assembler version 1.44 ; Copyright (c) 1999-2003, 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.43" +VERSION_STRING equ "1.44" VERSION_MAJOR = 1 -VERSION_MINOR = 43 +VERSION_MINOR = 44 diff --git a/SOURCE/WIN32/FASM.ASM b/SOURCE/WIN32/FASM.ASM index 5e28da5..d8c7f4b 100644 --- a/SOURCE/WIN32/FASM.ASM +++ b/SOURCE/WIN32/FASM.ASM @@ -3,9 +3,9 @@ ; Copyright (c) 1999-2003, Tomasz Grysztar. ; All rights reserved. - format PE console on '..\dos\fasm.com' + format PE console on '..\DOS\fasm.com' - macro align value { rb (value-1) - (rva $ + value-1) mod value } + macro align value { rb (value-1) - (RVA $ + value-1) mod value } start: diff --git a/SOURCE/WIN32/SYSTEM.INC b/SOURCE/WIN32/SYSTEM.INC index 4d1e719..0e60836 100644 --- a/SOURCE/WIN32/SYSTEM.INC +++ b/SOURCE/WIN32/SYSTEM.INC @@ -463,7 +463,10 @@ make_timestamp: mov eax,ecx shr eax,1 add ebp,eax + cmp ecx,2 + jb months_correction_ok sub ebp,2 + months_correction_ok: cmp ecx,2 jbe day_correction_ok movzx ecx,word [buffer] diff --git a/SOURCE/X86.INC b/SOURCE/X86.INC index a8d03a7..4f3a514 100644 --- a/SOURCE/X86.INC +++ b/SOURCE/X86.INC @@ -7042,6 +7042,10 @@ instructions_5: dw mmx_instruction-assembler db 'pavgw',0E3h dw mmx_instruction-assembler + db 'pf2id',1Dh + dw amd3dnow_instruction-assembler + db 'pf2iw',1Ch + dw amd3dnow_instruction-assembler db 'pfacc',0AEh dw amd3dnow_instruction-assembler db 'pfadd',9Eh @@ -7060,10 +7064,6 @@ instructions_5: dw amd3dnow_instruction-assembler db 'pi2fw',0Ch dw amd3dnow_instruction-assembler - db 'pi2id',1Dh - dw amd3dnow_instruction-assembler - db 'pi2iw',1Ch - dw amd3dnow_instruction-assembler db 'popad',61h dw simple_instruction_32bit-assembler db 'popaw',61h diff --git a/WHATSNEW.TXT b/WHATSNEW.TXT index bdde0a9..c905902 100644 --- a/WHATSNEW.TXT +++ b/WHATSNEW.TXT @@ -1,8 +1,15 @@ Visit http://fasm.sourceforge.net for more information +version 1.44 +[19-01-2003] +------------ +[+] added "eqtype" operator +[-] fixed cache waste in label parser +[-] small fixes and optimizations + version 1.43 -[10-01-2002] +[30-12-2002] ------------ [+] introduced ELF output format [+] extended public and extrn syntax