diff --git a/FASM.TXT b/FASM.TXT index 1d21117..bfe9759 100644 --- a/FASM.TXT +++ b/FASM.TXT @@ -1,12 +1,12 @@ - Üßßß - ÜÜŪÜÜ ÜÜÜÜ ÜÜÜÜÜ ÜÜÜ ÜÜ - Ū Ū Ū Ū Ū Ū - Ū ÜßßßßŪ ßßßßÜ Ū Ū Ū - Ū ßÜÜÜÜŪÜ ÜÜÜÜÜß Ū Ū Ū + Üßßß + ÜÜŪÜÜ ÜÜÜÜ ÜÜÜÜÜ ÜÜÜ ÜÜ + Ū Ū Ū Ū Ū Ū + Ū ÜßßßßŪ ßßßßÜ Ū Ū Ū + Ū ßÜÜÜÜŪÜ ÜÜÜÜÜß Ū Ū Ū - flat assembler 1.45 - Programmer's Manual + flat assembler 1.46 + 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.45 +flat assembler version 1.46 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.45 +flat assembler version 1.46 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.45 +flat assembler version 1.46 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.45 +flat assembler version 1.46 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. +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 @@ -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 @@ -1405,10 +1405,10 @@ ST0 before computing the logarithm. "fprem" computes the remainder obtained from dividing the value in ST0 by the value in ST1, and stores the result in ST0. "fprem1" performs the same operation as "fprem", but it computes the remainder in the way specified by IEEE Standard 754. "fscale" truncates the -value in ST1 and adds that value to the exponent of ST0. "fxtract" separates -the value in ST0 into its exponent and significand, stores the exponent in ST0 -and pushes the significand onto the register stack. "fnop" performs no -operation. These instruction have no operands. +value in ST1 and increases the exponent of ST0 by this value. "fxtract" +separates the value in ST0 into its exponent and significand, stores the +exponent in ST0 and pushes the significand onto the register stack. "fnop" +performs no operation. These instruction have no operands. "fxch" exchanges the contents of ST0 an another FPU register. The operand should be an FPU register, if no operand is specified, the contents of ST0 and ST1 are exchanged. @@ -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 @@ -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, @@ -1726,16 +1726,6 @@ source value to integer, rules for the operands are the same. cvtss2si eax,xmm0 ; convert single precision value to integer - "pavgb" and "pavgw" compute average of packed bytes or words. "pmaxub" -return the maximum values of packed unsigned bytes, "pminub" returns the -minimum values of packed unsigned bytes, "pmaxsw" returns the maximum values -of packed signed words, "pminsw" returns the minimum values of packed signed -words. "pmulhuw" performs a unsigned multiply of the packed words and stores -the high words of the results in the destination operand. "psadbw" computes -the absolute differences of packed unsigned bytes, sums the differences, and -stores the sum in the low word of destination operand. All these instructions -follow the same rules for operands as the general MMX operations described in -previous section. "pextrw" copies the word in the source operand specified by the third operand to the destination operand. The source operand must be a MMX register, the destination operand must be a 32-bit general register (but only the low @@ -1751,6 +1741,16 @@ word of the register is used). pinsrw mm1,ebx,2 ; insert word from ebx + "pavgb" and "pavgw" compute average of packed bytes or words. "pmaxub" +return the maximum values of packed unsigned bytes, "pminub" returns the +minimum values of packed unsigned bytes, "pmaxsw" returns the maximum values +of packed signed words, "pminsw" returns the minimum values of packed signed +words. "pmulhuw" performs a unsigned multiply of the packed words and stores +the high words of the results in the destination operand. "psadbw" computes +the absolute differences of packed unsigned bytes, sums the differences, and +stores the sum in the low word of destination operand. All these instructions +follow the same rules for operands as the general MMX operations described in +previous section. "pmovmskb" creates a mask made of the most significant bit of each byte in the source operand and stores the result in the low byte of destination operand. The source operand must be a MMX register, the destination operand @@ -1784,10 +1784,11 @@ stores the contents of MXCSR into a 32-bit memory operand. and SSE registers to a 512-byte memory location specified in the destination operand. "fxrstor" reloads data previously stored with "fxsave" instruction from the specified 512-byte memory location. The memory operand for both those -instructions must be aligned on 16 byte boundary. +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 @@ -1947,7 +1948,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 +2028,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 @@ -2070,24 +2071,24 @@ expression contains only symbols that were defined prior to it. 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 is greater than 0. The next example is more complex and assumes that the symbolic constant -"reg" is defined: +"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 @@ -2097,7 +2098,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 @@ -2115,8 +2116,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. @@ -2124,8 +2125,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 @@ -2137,9 +2138,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 @@ -2153,16 +2154,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 @@ -2268,8 +2269,8 @@ For example: macro stos0 { - xor al,al - stosb + xor al,al + stosb } The macroinstruction "stos0" will be replaced with these two assembly @@ -2295,10 +2296,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 } @@ -2311,10 +2312,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 } @@ -2347,8 +2348,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 @@ -2371,12 +2372,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 @@ -2401,12 +2402,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 @@ -2454,8 +2455,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 @@ -2468,16 +2469,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 @@ -2503,8 +2504,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 @@ -2516,9 +2517,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 58c22bf..0c39a6f 100644 --- a/LICENSE.TXT +++ b/LICENSE.TXT @@ -1,5 +1,5 @@ -flat assembler version 1.45 +flat assembler version 1.46 Copyright (c) 1999-2003, Tomasz Grysztar. All rights reserved. diff --git a/SOURCE/EXPRESSI.INC b/SOURCE/EXPRESSI.INC index 5693da4..e0ab0af 100644 --- a/SOURCE/EXPRESSI.INC +++ b/SOURCE/EXPRESSI.INC @@ -1664,7 +1664,13 @@ get_byte_value: cmp word [edi+8],0 jne invalid_value cmp byte [edi+12],0 - jne invalid_use_of_symbol + je check_byte_value + cmp [error_line],0 + jne check_byte_value + mov eax,[current_line] + mov [error_line],eax + mov [error],invalid_use_of_symbol + check_byte_value: mov eax,[edi] cmp dword [edi+4],0 je byte_positive @@ -1696,7 +1702,12 @@ get_word_value: or al,al jz check_word_value test al,1 - jz invalid_use_of_symbol + jnz check_word_value + cmp [error_line],0 + jne check_word_value + mov eax,[current_line] + mov [error_line],eax + mov [error],invalid_use_of_symbol check_word_value: mov eax,[edi] cmp dword [edi+4],0 diff --git a/SOURCE/LINUX/SYSTEM.INC b/SOURCE/LINUX/SYSTEM.INC index 59e2ed9..975ecb6 100644 --- a/SOURCE/LINUX/SYSTEM.INC +++ b/SOURCE/LINUX/SYSTEM.INC @@ -199,9 +199,6 @@ lseek: mov dl,al mov eax,19 int 0x80 - test eax,eax - js file_error - clc ret display_string: diff --git a/SOURCE/VERSION.INC b/SOURCE/VERSION.INC index 305710e..e0f5d65 100644 --- a/SOURCE/VERSION.INC +++ b/SOURCE/VERSION.INC @@ -1,5 +1,5 @@ -; flat assembler version 1.45 +; flat assembler version 1.46 ; 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.45" +VERSION_STRING equ "1.46" VERSION_MAJOR = 1 -VERSION_MINOR = 45 +VERSION_MINOR = 46 diff --git a/SOURCE/WIN32/SYSTEM.INC b/SOURCE/WIN32/SYSTEM.INC index 0e60836..2cb649e 100644 --- a/SOURCE/WIN32/SYSTEM.INC +++ b/SOURCE/WIN32/SYSTEM.INC @@ -249,8 +249,6 @@ lseek: push edx push ebx call [SetFilePointer] - cmp eax,-1 - je file_error ret display_string: diff --git a/SOURCE/X86.INC b/SOURCE/X86.INC index cc861cc..3909aa7 100644 --- a/SOURCE/X86.INC +++ b/SOURCE/X86.INC @@ -278,10 +278,11 @@ basic_instruction: je basic_reg_imm_32bit or al,al jnz invalid_operand_size - cmp [current_pass],0 - jne operand_size_not_specified - cmp [next_pass_needed],0 - je operand_size_not_specified + cmp [error_line],0 + jne basic_reg_imm_32bit + mov eax,[current_line] + mov [error_line],eax + mov [error],operand_size_not_specified jmp basic_reg_imm_32bit basic_reg_imm_8bit: call get_byte_value @@ -399,10 +400,11 @@ single_operand_instruction: je single_mem_32bit or al,al jnz invalid_operand_size - cmp [current_pass],0 - jne operand_size_not_specified - cmp [next_pass_needed],0 - je operand_size_not_specified + cmp [error_line],0 + jne single_mem_8bit + mov eax,[current_line] + mov [error_line],eax + mov [error],operand_size_not_specified single_mem_8bit: call store_instruction jmp instruction_assembled @@ -590,10 +592,11 @@ mov_instruction: je mov_mem_imm_32bit or al,al jnz invalid_operand_size - cmp [current_pass],0 - jne operand_size_not_specified - cmp [next_pass_needed],0 - je operand_size_not_specified + cmp [error_line],0 + jne mov_mem_imm_32bit + mov eax,[current_line] + mov [error_line],eax + mov [error],operand_size_not_specified jmp mov_mem_imm_32bit mov_mem_imm_8bit: call get_byte_value @@ -810,10 +813,11 @@ mov_instruction: je mov_reg_imm_32bit or al,al jnz invalid_operand_size - cmp [current_pass],0 - jne operand_size_not_specified - cmp [next_pass_needed],0 - je operand_size_not_specified + cmp [error_line],0 + jne mov_reg_imm_32bit + mov eax,[current_line] + mov [error_line],eax + mov [error],operand_size_not_specified jmp mov_reg_imm_32bit mov_reg_imm_8bit: call get_byte_value @@ -1060,10 +1064,11 @@ test_instruction: je test_mem_imm_32bit or al,al jnz invalid_operand_size - cmp [current_pass],0 - jne operand_size_not_specified - cmp [next_pass_needed],0 - je operand_size_not_specified + cmp [error_line],0 + jne test_mem_imm_32bit + mov eax,[current_line] + mov [error_line],eax + mov [error],operand_size_not_specified jmp test_mem_imm_32bit test_mem_imm_8bit: call get_byte_value @@ -1152,10 +1157,11 @@ test_instruction: je test_reg_imm_32bit or al,al jnz invalid_operand_size - cmp [current_pass],0 - jne operand_size_not_specified - cmp [next_pass_needed],0 - je operand_size_not_specified + cmp [error_line],0 + jne test_reg_imm_32bit + mov eax,[current_line] + mov [error_line],eax + mov [error],operand_size_not_specified jmp test_reg_imm_32bit test_reg_imm_8bit: call get_byte_value @@ -1344,10 +1350,11 @@ push_instruction: je push_mem_16bit cmp ah,4 je push_mem_32bit - cmp [current_pass],0 - jne operand_size_not_specified - cmp [next_pass_needed],0 - je operand_size_not_specified + cmp [error_line],0 + jne push_mem_16bit + mov eax,[current_line] + mov [error_line],eax + mov [error],operand_size_not_specified push_mem_16bit: cmp ah,4 je invalid_operand_size @@ -1539,10 +1546,11 @@ pop_instruction: je pop_mem_16bit cmp ah,4 je pop_mem_32bit - cmp [current_pass],0 - jne operand_size_not_specified - cmp [next_pass_needed],0 - je operand_size_not_specified + cmp [error_line],0 + jne pop_mem_16bit + mov eax,[current_line] + mov [error_line],eax + mov [error],operand_size_not_specified pop_mem_16bit: cmp ah,4 je invalid_operand_size @@ -1663,10 +1671,11 @@ inc_instruction: je inc_mem_32bit or al,al jnz invalid_operand_size - cmp [current_pass],0 - jne operand_size_not_specified - cmp [next_pass_needed],0 - je operand_size_not_specified + cmp [error_line],0 + jne inc_mem_8bit + mov eax,[current_line] + mov [error_line],eax + mov [error],operand_size_not_specified inc_mem_8bit: mov al,0FEh xchg al,[base_code] @@ -2036,10 +2045,11 @@ sh_instruction: je sh_mem_cl_32bit or ah,ah jnz invalid_operand_size - cmp [current_pass],0 - jne operand_size_not_specified - cmp [next_pass_needed],0 - je operand_size_not_specified + cmp [error_line],0 + jne sh_mem_cl_8bit + mov eax,[current_line] + mov [error_line],eax + mov [error],operand_size_not_specified sh_mem_cl_8bit: mov [base_code],0D2h call store_instruction @@ -2072,10 +2082,11 @@ sh_instruction: je sh_mem_imm_32bit or al,al jnz invalid_operand_size - cmp [current_pass],0 - jne operand_size_not_specified - cmp [next_pass_needed],0 - je operand_size_not_specified + cmp [error_line],0 + jne sh_mem_imm_8bit + mov eax,[current_line] + mov [error_line],eax + mov [error],operand_size_not_specified sh_mem_imm_8bit: cmp byte [value],1 je sh_mem_1_8bit @@ -2467,10 +2478,11 @@ movx_instruction: je movx_32bit_mem_16bit or al,al jnz invalid_operand_size - cmp [current_pass],0 - jne operand_size_not_specified - cmp [next_pass_needed],0 - je operand_size_not_specified + cmp [error_line],0 + jne movx_32bit_mem_8bit + mov eax,[current_line] + mov [error_line],eax + mov [error],operand_size_not_specified movx_32bit_mem_8bit: call operand_32bit_prefix call store_instruction @@ -2582,10 +2594,11 @@ bt_instruction: je bt_mem_imm_32bit or al,al jnz invalid_operand_size - cmp [current_pass],0 - jne operand_size_not_specified - cmp [next_pass_needed],0 - je operand_size_not_specified + cmp [error_line],0 + jne bt_mem_imm_32bit + mov eax,[current_line] + mov [error_line],eax + mov [error],operand_size_not_specified jmp bt_mem_imm_32bit bt_mem_imm_16bit: call operand_16bit_prefix @@ -2670,10 +2683,11 @@ bt_instruction: je bt_reg_imm_32bit or al,al jnz invalid_operand_size - cmp [current_pass],0 - jne operand_size_not_specified - cmp [next_pass_needed],0 - je operand_size_not_specified + cmp [error_line],0 + jne bt_reg_imm_32bit + mov eax,[current_line] + mov [error_line],eax + mov [error],operand_size_not_specified jmp bt_reg_imm_32bit bt_reg_imm_16bit: call operand_16bit_prefix @@ -2777,6 +2791,12 @@ pm_word_instruction: pm_reg: lods byte [esi] call convert_register + mov bl,al + cmp [extended_code],1 + jne pm_reg16 + cmp [postbyte_register],4 + je smsw_reg + pm_reg16: cmp ah,2 jne invalid_operand_size mov bl,al @@ -2789,6 +2809,22 @@ pm_word_instruction: or al,11000000b stos byte [edi] jmp instruction_assembled + smsw_reg: + cmp ah,2 + je smsw_reg16 + cmp ah,4 + jne invalid_operand_size + call operand_32bit_prefix + jmp smsw_reg_store + smsw_reg16: + call operand_16bit_prefix + smsw_reg_store: + mov ax,010Fh + stos word [edi] + mov al,11100000b + or al,bl + stos byte [edi] + jmp instruction_assembled pm_pword_instruction: mov [base_code],0Fh mov [extended_code],1 @@ -2827,10 +2863,11 @@ imul_instruction: je imul_mem_32bit or al,al jnz invalid_operand_size - cmp [current_pass],0 - jne operand_size_not_specified - cmp [next_pass_needed],0 - je operand_size_not_specified + cmp [error_line],0 + jne imul_mem_8bit + mov eax,[current_line] + mov [error_line],eax + mov [error],operand_size_not_specified imul_mem_8bit: call store_instruction jmp instruction_assembled @@ -3091,6 +3128,7 @@ imul_instruction: call get_word_value pop dx bx mov word [value],ax + call operand_16bit_prefix cmp [value_type],0 jne imul_reg_reg_imm_16bit_forced cmp [imm_sized],0 @@ -3100,7 +3138,6 @@ imul_instruction: cmp ax,80h jl imul_reg_reg_imm_8bit_store imul_reg_reg_imm_16bit_forced: - call operand_16bit_prefix mov al,69h stos byte [edi] mov al,dl @@ -3117,6 +3154,7 @@ imul_instruction: call get_dword_value pop dx bx mov dword [value],eax + call operand_32bit_prefix cmp [value_type],0 jne imul_reg_reg_imm_32bit_forced cmp [imm_sized],0 @@ -3126,7 +3164,6 @@ imul_instruction: cmp eax,80h jl imul_reg_reg_imm_8bit_store imul_reg_reg_imm_32bit_forced: - call operand_32bit_prefix mov al,69h stos byte [edi] mov al,dl @@ -3666,10 +3703,11 @@ jmp_instruction: je jmp_mem_far cmp [jump_type],1 je jmp_mem_near - cmp [current_pass],0 - jne operand_size_not_specified - cmp [next_pass_needed],0 - je operand_size_not_specified + cmp [error_line],0 + jne jmp_mem_near + mov eax,[current_line] + mov [error_line],eax + mov [error],operand_size_not_specified jmp_mem_near: cmp [code_type],16 je jmp_mem_16bit @@ -4212,10 +4250,11 @@ basic_fpu_instruction: je basic_fpu_mem_64bit or al,al jnz invalid_operand_size - cmp [current_pass],0 - jne operand_size_not_specified - cmp [next_pass_needed],0 - je operand_size_not_specified + cmp [error_line],0 + jne basic_fpu_mem_32bit + mov eax,[current_line] + mov [error_line],eax + mov [error],operand_size_not_specified basic_fpu_mem_32bit: mov [base_code],0D8h call store_instruction @@ -4301,10 +4340,11 @@ fi_instruction: je fi_mem_32bit or al,al jnz invalid_operand_size - cmp [current_pass],0 - jne operand_size_not_specified - cmp [next_pass_needed],0 - je operand_size_not_specified + cmp [error_line],0 + jne fi_mem_32bit + mov eax,[current_line] + mov [error_line],eax + mov [error],operand_size_not_specified fi_mem_32bit: mov [base_code],0DAh call store_instruction @@ -4331,10 +4371,11 @@ fld_instruction: je fld_mem_80bit or al,al jnz invalid_operand_size - cmp [current_pass],0 - jne operand_size_not_specified - cmp [next_pass_needed],0 - je operand_size_not_specified + cmp [error_line],0 + jne fld_mem_32bit + mov eax,[current_line] + mov [error_line],eax + mov [error],operand_size_not_specified fld_mem_32bit: mov [base_code],0D9h call store_instruction @@ -4388,10 +4429,11 @@ fild_instruction: je fild_mem_64bit or al,al jnz invalid_operand_size - cmp [current_pass],0 - jne operand_size_not_specified - cmp [next_pass_needed],0 - je operand_size_not_specified + cmp [error_line],0 + jne fild_mem_32bit + mov eax,[current_line] + mov [error_line],eax + mov [error],operand_size_not_specified fild_mem_32bit: mov [base_code],0DBh call store_instruction @@ -5464,22 +5506,22 @@ sse_cmp_instruction: lods byte [esi] cmp al,',' jne invalid_operand + mov [operand_size],0 lods byte [esi] call get_size_operator cmp al,10h je sse_cmp_xmmreg_xmmreg cmp al,'[' jne invalid_operand - mov [operand_size],0 call get_address pop eax mov [postbyte_register],al - cmp [operand_size],0 - je sse_cmp_xmmreg_mem_store - mov al,[mmx_size] - cmp [operand_size],al + mov al,[operand_size] + or al,al + jz sse_cmp_size_ok + cmp al,[mmx_size] jne invalid_operand_size - sse_cmp_xmmreg_mem_store: + sse_cmp_size_ok: call store_mmx_instruction sse_cmp_nextbyte: mov al,[nextbyte] @@ -5919,14 +5961,14 @@ get_jump_operator: operand_16bit_prefix: cmp [code_type],16 je size_prefix_ok - mov al,66h - stos byte [edi] + mov byte [edi],66h + inc edi ret operand_32bit_prefix: cmp [code_type],32 je size_prefix_ok - mov al,66h - stos byte [edi] + mov byte [edi],66h + inc edi size_prefix_ok: ret store_segment_prefix_if_necessary: diff --git a/WHATSNEW.TXT b/WHATSNEW.TXT index bbab035..875758f 100644 --- a/WHATSNEW.TXT +++ b/WHATSNEW.TXT @@ -1,8 +1,13 @@ -Visit http://fasm.sourceforge.net for more information +Visit http://fasm.sourceforge.net/ for more information + +version 1.46 +[09-04-2003] +------------ +[-] several little fixes version 1.45 -[06-02-2003] +[09-02-2003] ------------ [+] checking any expression with "defined" operator allowed [-] less strict intermediate passes