Codebase list fasm / f77805f
Imported Upstream version 1.71.22 Tomasz Buchert 9 years ago
64 changed file(s) with 39923 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0
1 macro Elf32_Sym name,value,size,bind,type,other,shndx
2 {
3 dd name+0
4 dd value+0
5 dd size+0
6 db (bind+0) shl 4 + (type+0)
7 db other+0
8 dw shndx+0
9 }
10
11 virtual at 0
12 Elf32_Sym
13 sizeof.Elf32_Sym = $
14 end virtual
15
16 macro Elf32_Rel offset,symbol,type
17 {
18 dd offset+0
19 dd (symbol+0) shl 8 + (type+0)
20 }
21
22 virtual at 0
23 Elf32_Rel
24 sizeof.Elf32_Rel = $
25 end virtual
26
27 macro Elf32_Rela offset,symbol,type,addend
28 {
29 dd offset+0
30 dd (symbol+0) shl 8 + (type+0)
31 dd addend+0
32 }
33
34 virtual at 0
35 Elf32_Rela
36 sizeof.Elf32_Rela = $
37 end virtual
38
39 macro Elf64_Sym name,value,size,bind,type,other,shndx
40 {
41 dd name+0
42 db (bind+0) shl 4 + (type+0)
43 db other+0
44 dw shndx+0
45 dq value+0
46 dq size+0
47 }
48
49 virtual at 0
50 Elf64_Sym
51 sizeof.Elf64_Sym = $
52 end virtual
53
54 macro Elf64_Rel offset,symbol,type
55 {
56 dq offset+0
57 dq (symbol+0) shl 32 + (type+0)
58 }
59
60 virtual at 0
61 Elf64_Rel
62 sizeof.Elf64_Rel = $
63 end virtual
64
65 macro Elf64_Rela offset,symbol,type,addend
66 {
67 dq offset+0
68 dq (symbol+0) shl 32 + (type+0)
69 dq addend+0
70 }
71
72 virtual at 0
73 Elf64_Rela
74 sizeof.Elf64_Rela = $
75 end virtual
76
77 DT_NULL = 0
78 DT_NEEDED = 1
79 DT_HASH = 4
80 DT_STRTAB = 5
81 DT_SYMTAB = 6
82 DT_RELA = 7
83 DT_RELASZ = 8
84 DT_RELAENT = 9
85 DT_STRSZ = 10
86 DT_SYMENT = 11
87 DT_REL = 17
88 DT_RELSZ = 18
89 DT_RELENT = 19
90
91 STB_LOCAL = 0
92 STB_GLOBAL = 1
93 STB_WEAK = 2
94
95 STT_NOTYPE = 0
96 STT_OBJECT = 1
97 STT_FUNC = 2
98 STT_SECTION = 3
99 STT_FILE = 4
100
101 R_386_NONE = 0
102 R_386_32 = 1
103 R_386_PC32 = 2
104 R_386_GOT32 = 3
105 R_386_PLT32 = 4
106 R_386_COPY = 5
107 R_386_GLOB_DAT = 6
108 R_386_JMP_SLOT = 7
109 R_386_RELATIVE = 8
110 R_386_GOTOFF = 9
111 R_386_GOTPC = 10
112
113 R_X86_64_NONE = 0
114 R_X86_64_64 = 1
115 R_X86_64_PC32 = 2
116 R_X86_64_GOT32 = 3
117 R_X86_64_PLT32 = 4
118 R_X86_64_COPY = 5
119 R_X86_64_GLOB_DAT = 6
120 R_X86_64_JUMP_SLOT = 7
121 R_X86_64_RELATIVE = 8
122 R_X86_64_GOTPCREL = 9
123 R_X86_64_32 = 10
124 R_X86_64_32S = 11
125 R_X86_64_16 = 12
126 R_X86_64_PC16 = 13
127 R_X86_64_8 = 14
128 R_X86_64_PC8 = 15
129 R_X86_64_DPTMOD64 = 16
130 R_X86_64_DTPOFF64 = 17
131 R_X86_64_TPOFF64 = 18
132 R_X86_64_TLSGD = 19
133 R_X86_64_TLSLD = 20
134 R_X86_64_DTPOFF32 = 21
135 R_X86_64_GOTTPOFF = 22
136 R_X86_64_TPOFF32 = 23
137 R_X86_64_PC64 = 24
138 R_X86_64_GOTOFF64 = 25
139 R_X86_64_GOTPC32 = 26
0
1 format ELF executable 3
2 entry start
3
4 include 'import32.inc'
5 include 'proc32.inc'
6
7 interpreter '/lib/ld-linux.so.2'
8 needed 'libc.so.6'
9 import printf,exit
10
11 segment readable executable
12
13 start:
14 cinvoke printf,msg
15 cinvoke exit
16
17 segment readable writeable
18
19 msg db 'Hello world!',0xA,0
0
1 format ELF64 executable 3
2 entry start
3
4 include 'import64.inc'
5
6 interpreter '/lib64/ld-linux-x86-64.so.2'
7 needed 'libc.so.6'
8 import printf,exit
9
10 segment readable executable
11
12 start:
13
14 lea rdi,[msg]
15 xor eax,eax
16 call [printf]
17
18 call [exit]
19
20 segment readable writeable
21
22 msg db 'Hello world!',0xA,0
0
1 include 'elf.inc'
2
3 macro interpreter [library]
4 {
5 segment interpreter readable
6 db library,0
7 }
8
9 macro needed [library]
10 {
11 local str
12 match needed,needed@dynamic \{ define needed@dynamic needed,str:library \}
13 match ,needed@dynamic \{ define needed@dynamic str:library \}
14 }
15 define needed@dynamic
16
17 macro import [name]
18 {
19 common
20 local strtab,strsz,symtab,rel,relsz,hash
21 segment dynamic readable
22 match needed,needed@dynamic
23 \{ irp item,needed \\{ match str:library,item \\\{ dd DT_NEEDED,str-strtab \\\} \\} \}
24 dd DT_STRTAB,strtab
25 dd DT_STRSZ,strsz
26 dd DT_SYMTAB,symtab
27 dd DT_SYMENT,sizeof.Elf32_Sym
28 dd DT_REL,rel
29 dd DT_RELSZ,relsz
30 dd DT_RELENT,sizeof.Elf32_Rel
31 dd DT_HASH,hash
32 dd DT_NULL,0
33 segment readable writeable
34 symtab: Elf32_Sym
35 forward
36 local fstr
37 Elf32_Sym fstr-strtab,0,0,STB_GLOBAL,STT_FUNC,0,0
38 common
39 rel:
40 local counter
41 counter = 1
42 forward
43 Elf32_Rel name,counter,R_386_32
44 counter = counter+1
45 common
46 relsz = $-rel
47 hash:
48 dd 1,counter
49 dd 0
50 repeat counter
51 if %=counter
52 dd 0
53 else
54 dd %
55 end if
56 end repeat
57 strtab db 0
58 forward
59 fstr db `name,0
60 common
61 match needed,needed@dynamic
62 \{ irp item,needed \\{ match str:library,item \\\{ str db library,0 \\\} \\} \}
63 strsz = $-strtab
64 forward
65 name dd 0
66 }
0
1 include 'elf.inc'
2
3 macro interpreter [library]
4 {
5 segment interpreter readable
6 db library,0
7 }
8
9 macro needed [library]
10 {
11 local str
12 match needed,needed@dynamic \{ define needed@dynamic needed,str:library \}
13 match ,needed@dynamic \{ define needed@dynamic str:library \}
14 }
15 define needed@dynamic
16
17 macro import [name]
18 {
19 common
20 local strtab,strsz,symtab,rel,relsz,hash
21 segment dynamic readable
22 match needed,needed@dynamic
23 \{ irp item,needed \\{ match str:library,item \\\{ dq DT_NEEDED,str-strtab \\\} \\} \}
24 dq DT_STRTAB,strtab
25 dq DT_STRSZ,strsz
26 dq DT_SYMTAB,symtab
27 dq DT_SYMENT,sizeof.Elf64_Sym
28 dq DT_RELA,rela
29 dq DT_RELASZ,relasz
30 dq DT_RELAENT,sizeof.Elf64_Rela
31 dq DT_HASH,hash
32 dq DT_NULL,0
33 segment readable writeable
34 symtab: Elf64_Sym
35 forward
36 local fstr
37 Elf64_Sym fstr-strtab,0,0,STB_GLOBAL,STT_FUNC,0,0
38 common
39 rela:
40 local counter
41 counter = 1
42 forward
43 Elf64_Rela name,counter,R_X86_64_64
44 counter = counter+1
45 common
46 relasz = $-rela
47 hash:
48 dd 1,counter
49 dd 0
50 repeat counter
51 if %=counter
52 dd 0
53 else
54 dd %
55 end if
56 end repeat
57 strtab db 0
58 forward
59 fstr db `name,0
60 common
61 match needed,needed@dynamic
62 \{ irp item,needed \\{ match str:library,item \\\{ str db library,0 \\\} \\} \}
63 strsz = $-strtab
64 forward
65 name dq 0
66 }
0
1 ; Macroinstructions for defining and calling procedures
2
3 macro stdcall proc,[arg] ; directly call STDCALL procedure
4 { common
5 if ~ arg eq
6 reverse
7 pushd arg
8 common
9 end if
10 call proc }
11
12 macro invoke proc,[arg] ; indirectly call STDCALL procedure
13 { common
14 if ~ arg eq
15 reverse
16 pushd arg
17 common
18 end if
19 call [proc] }
20
21 macro ccall proc,[arg] ; directly call CDECL procedure
22 { common
23 size@ccall = 0
24 if ~ arg eq
25 reverse
26 pushd arg
27 size@ccall = size@ccall+4
28 common
29 end if
30 call proc
31 if size@ccall
32 add esp,size@ccall
33 end if }
34
35 macro cinvoke proc,[arg] ; indirectly call CDECL procedure
36 { common
37 size@ccall = 0
38 if ~ arg eq
39 reverse
40 pushd arg
41 size@ccall = size@ccall+4
42 common
43 end if
44 call [proc]
45 if size@ccall
46 add esp,size@ccall
47 end if }
48
49 macro proc [args] ; define procedure
50 { common
51 match name params, args>
52 \{ define@proc name,<params \} }
53
54 prologue@proc equ prologuedef
55
56 macro prologuedef procname,flag,parmbytes,localbytes,reglist
57 { local loc
58 loc = (localbytes+3) and (not 3)
59 parmbase@proc equ ebp+8
60 localbase@proc equ ebp-loc
61 if parmbytes | localbytes
62 push ebp
63 mov ebp,esp
64 if localbytes
65 sub esp,loc
66 end if
67 end if
68 irps reg, reglist \{ push reg \} }
69
70 epilogue@proc equ epiloguedef
71
72 macro epiloguedef procname,flag,parmbytes,localbytes,reglist
73 { irps reg, reglist \{ reverse pop reg \}
74 if parmbytes | localbytes
75 leave
76 end if
77 if flag and 10000b
78 retn
79 else
80 retn parmbytes
81 end if }
82
83 close@proc equ
84
85 macro define@proc name,statement
86 { local params,flag,regs,parmbytes,localbytes,current
87 if used name
88 name:
89 match =stdcall args, statement \{ params equ args
90 flag = 11b \}
91 match =stdcall, statement \{ params equ
92 flag = 11b \}
93 match =c args, statement \{ params equ args
94 flag = 10001b \}
95 match =c, statement \{ params equ
96 flag = 10001b \}
97 match =params, params \{ params equ statement
98 flag = 0 \}
99 match =uses reglist=,args, params \{ regs equ reglist
100 params equ args \}
101 match =regs =uses reglist, regs params \{ regs equ reglist
102 params equ \}
103 match =regs, regs \{ regs equ \}
104 match prologue:reglist, prologue@proc:<regs> \{ prologue name,flag,parmbytes,localbytes,reglist \}
105 virtual at parmbase@proc
106 match =,args, params \{ defargs@proc args \}
107 match =args@proc args, args@proc params \{ defargs@proc args \}
108 parmbytes = $-(parmbase@proc)
109 end virtual
110 name # % = parmbytes/4
111 all@vars equ
112 current = 0
113 macro locals
114 \{ virtual at localbase@proc+current
115 macro label def \\{ match . type,def> \\\{ deflocal@proc .,label,<type \\\} \\}
116 struc db [val] \\{ \common deflocal@proc .,db,val \\}
117 struc du [val] \\{ \common deflocal@proc .,du,val \\}
118 struc dw [val] \\{ \common deflocal@proc .,dw,val \\}
119 struc dp [val] \\{ \common deflocal@proc .,dp,val \\}
120 struc dd [val] \\{ \common deflocal@proc .,dd,val \\}
121 struc dt [val] \\{ \common deflocal@proc .,dt,val \\}
122 struc dq [val] \\{ \common deflocal@proc .,dq,val \\}
123 struc rb cnt \\{ deflocal@proc .,rb cnt, \\}
124 struc rw cnt \\{ deflocal@proc .,rw cnt, \\}
125 struc rp cnt \\{ deflocal@proc .,rp cnt, \\}
126 struc rd cnt \\{ deflocal@proc .,rd cnt, \\}
127 struc rt cnt \\{ deflocal@proc .,rt cnt, \\}
128 struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \}
129 macro endl
130 \{ purge label
131 restruc db,du,dw,dp,dd,dt,dq
132 restruc rb,rw,rp,rd,rt,rq
133 current = $-(localbase@proc)
134 end virtual \}
135 macro ret operand
136 \{ match any, operand \\{ retn operand \\}
137 match , operand \\{ match epilogue:reglist, epilogue@proc:<regs> \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
138 macro finish@proc
139 \{ localbytes = current
140 match close:reglist, close@proc:<regs> \\{ close name,flag,parmbytes,localbytes,reglist \\}
141 end if \} }
142
143 macro defargs@proc [arg]
144 { common
145 if ~ arg eq
146 forward
147 local ..arg,current@arg
148 match argname:type, arg
149 \{ current@arg equ argname
150 label ..arg type
151 argname equ ..arg
152 if dqword eq type
153 dd ?,?,?,?
154 else if tbyte eq type
155 dd ?,?,?
156 else if qword eq type | pword eq type
157 dd ?,?
158 else
159 dd ?
160 end if \}
161 match =current@arg,current@arg
162 \{ current@arg equ arg
163 arg equ ..arg
164 ..arg dd ? \}
165 common
166 args@proc equ current@arg
167 forward
168 restore current@arg
169 common
170 end if }
171
172 macro deflocal@proc name,def,[val] { name def val }
173
174 macro deflocal@proc name,def,[val]
175 { common
176 match vars, all@vars \{ all@vars equ all@vars, \}
177 all@vars equ all@vars name
178 forward
179 local ..var,..tmp
180 ..var def val
181 match =?, val \{ ..tmp equ \}
182 match any =?, val \{ ..tmp equ \}
183 match any (=?), val \{ ..tmp equ \}
184 match =label, def \{ ..tmp equ \}
185 match tmp : value, ..tmp : val
186 \{ tmp: end virtual
187 initlocal@proc ..var,def value
188 virtual at tmp\}
189 common
190 match first rest, ..var, \{ name equ first \} }
191
192 struc label type { label . type }
193
194 macro initlocal@proc name,def
195 { virtual at name
196 def
197 size@initlocal = $ - name
198 end virtual
199 position@initlocal = 0
200 while size@initlocal > position@initlocal
201 virtual at name
202 def
203 if size@initlocal - position@initlocal < 2
204 current@initlocal = 1
205 load byte@initlocal byte from name+position@initlocal
206 else if size@initlocal - position@initlocal < 4
207 current@initlocal = 2
208 load word@initlocal word from name+position@initlocal
209 else
210 current@initlocal = 4
211 load dword@initlocal dword from name+position@initlocal
212 end if
213 end virtual
214 if current@initlocal = 1
215 mov byte [name+position@initlocal],byte@initlocal
216 else if current@initlocal = 2
217 mov word [name+position@initlocal],word@initlocal
218 else
219 mov dword [name+position@initlocal],dword@initlocal
220 end if
221 position@initlocal = position@initlocal + current@initlocal
222 end while }
223
224 macro endp
225 { purge ret,locals,endl
226 finish@proc
227 purge finish@proc
228 restore regs@proc
229 match all,args@proc \{ restore all \}
230 restore args@proc
231 match all,all@vars \{ restore all \} }
232
233 macro local [var]
234 { common
235 locals
236 forward done@local equ
237 match varname[count]:vartype, var
238 \{ match =BYTE, vartype \\{ varname rb count
239 restore done@local \\}
240 match =WORD, vartype \\{ varname rw count
241 restore done@local \\}
242 match =DWORD, vartype \\{ varname rd count
243 restore done@local \\}
244 match =PWORD, vartype \\{ varname rp count
245 restore done@local \\}
246 match =QWORD, vartype \\{ varname rq count
247 restore done@local \\}
248 match =TBYTE, vartype \\{ varname rt count
249 restore done@local \\}
250 match =DQWORD, vartype \\{ label varname dqword
251 rq count+count
252 restore done@local \\}
253 match , done@local \\{ virtual
254 varname vartype
255 end virtual
256 rb count*sizeof.\#vartype
257 restore done@local \\} \}
258 match :varname:vartype, done@local:var
259 \{ match =BYTE, vartype \\{ varname db ?
260 restore done@local \\}
261 match =WORD, vartype \\{ varname dw ?
262 restore done@local \\}
263 match =DWORD, vartype \\{ varname dd ?
264 restore done@local \\}
265 match =PWORD, vartype \\{ varname dp ?
266 restore done@local \\}
267 match =QWORD, vartype \\{ varname dq ?
268 restore done@local \\}
269 match =TBYTE, vartype \\{ varname dt ?
270 restore done@local \\}
271 match =DQWORD, vartype \\{ label varname dqword
272 dq ?,?
273 restore done@local \\}
274 match , done@local \\{ varname vartype
275 restore done@local \\} \}
276 match ,done@local
277 \{ var
278 restore done@local \}
279 common
280 endl }
Binary diff not shown
0
1 ; fasm demonstration of writing simple ELF executable
2
3 format ELF executable 3
4 entry start
5
6 segment readable executable
7
8 start:
9
10 mov eax,4
11 mov ebx,1
12 mov ecx,msg
13 mov edx,msg_size
14 int 0x80
15
16 mov eax,1
17 xor ebx,ebx
18 int 0x80
19
20 segment readable writeable
21
22 msg db 'Hello world!',0xA
23 msg_size = $-msg
Binary diff not shown
0
1 ; fasm demonstration of writing 64-bit ELF executable
2 ; (thanks to František Gábriš)
3
4 ; syscall numbers: /usr/src/linux/include/asm-x86_64/unistd.h
5 ; parameters order:
6 ; r9 ; 6th param
7 ; r8 ; 5th param
8 ; r10 ; 4th param
9 ; rdx ; 3rd param
10 ; rsi ; 2nd param
11 ; rdi ; 1st param
12 ; eax ; syscall_number
13 ; syscall
14
15 format ELF64 executable 3
16
17 segment readable executable
18
19 entry $
20
21 mov edx,msg_size ; CPU zero extends 32-bit operation to 64-bit
22 ; we can use less bytes than in case mov rdx,...
23 lea rsi,[msg]
24 mov edi,1 ; STDOUT
25 mov eax,1 ; sys_write
26 syscall
27
28 xor edi,edi ; exit code 0
29 mov eax,60 ; sys_exit
30 syscall
31
32 segment readable writeable
33
34 msg db 'Hello 64-bit world!',0xA
35 msg_size = $-msg
0
1 ; fasm demonstration of assembling object files
2
3 ; compile the program using commands like:
4 ; fasm msgdemo.asm msgdemo.o
5 ; fasm writemsg.asm writemsg.o
6 ; ld msgdemo.o writemsg.o -o msgdemo
7
8 format ELF
9
10 section '.text' executable
11
12 public _start
13 _start:
14
15 extrn writemsg
16
17 mov esi,msg
18 call writemsg
19
20 mov eax,1
21 xor ebx,ebx
22 int 0x80
23
24 section '.data' writeable
25
26 msg db "Elves are coming!",0xA,0
Binary diff not shown
0
1 format ELF
2
3 section '.text' executable
4
5 public writemsg
6
7 writemsg:
8 mov ecx,esi
9 find_end:
10 lodsb
11 or al,al
12 jnz find_end
13 mov edx,esi
14 sub edx,ecx
15 mov eax,4
16 mov ebx,1
17 int 0x80
18 ret
Binary diff not shown
0
1 macro ccall proc,[arg]
2 { common
3 local size
4 size = 0
5 mov ebp,esp
6 if ~ arg eq
7 forward
8 size = size + 4
9 common
10 sub esp,size
11 end if
12 and esp,-16
13 if ~ arg eq
14 add esp,size
15 reverse
16 pushd arg
17 common
18 end if
19 call proc
20 mov esp,ebp }
21
0
1 ; fasm example of using the C library in Unix systems
2
3 ; compile the source with commands like:
4 ; fasm libcdemo.asm libcdemo.o
5 ; gcc libcdemo.o -o libcdemo
6 ; strip libcdemo
7
8 format ELF
9
10 include 'ccall.inc'
11
12 section '.text' executable
13
14 public main
15 extrn printf
16 extrn getpid
17
18 main:
19 call getpid
20 ccall printf, msg,eax
21 ret
22
23 section '.data' writeable
24
25 msg db "Current process ID is %d.",0xA,0
Binary diff not shown
0
1 ,'''
2 ,,;,, ,,,, ,,,,, ,,, ,,
3 ; ; ; ; ; ;
4 ; ,''''; '''', ; ; ;
5 ; ',,,,;, ,,,,,' ; ; ;
6
7 flat assembler 1.71
8 Programmer's Manual
9
10
11 Table of contents
12 -----------------
13
14 Chapter 1 Introduction
15
16 1.1 Compiler overview
17 1.1.1 System requirements
18 1.1.2 Executing compiler from command line
19 1.1.3 Compiler messages
20 1.1.4 Output formats
21
22 1.2 Assembly syntax
23 1.2.1 Instruction syntax
24 1.2.2 Data definitions
25 1.2.3 Constants and labels
26 1.2.4 Numerical expressions
27 1.2.5 Jumps and calls
28 1.2.6 Size settings
29
30 Chapter 2 Instruction set
31
32 2.1 The x86 architecture instructions
33 2.1.1 Data movement instructions
34 2.1.2 Type conversion instructions
35 2.1.3 Binary arithmetic instructions
36 2.1.4 Decimal arithmetic instructions
37 2.1.5 Logical instructions
38 2.1.6 Control transfer instructions
39 2.1.7 I/O instructions
40 2.1.8 Strings operations
41 2.1.9 Flag control instructions
42 2.1.10 Conditional operations
43 2.1.11 Miscellaneous instructions
44 2.1.12 System instructions
45 2.1.13 FPU instructions
46 2.1.14 MMX instructions
47 2.1.15 SSE instructions
48 2.1.16 SSE2 instructions
49 2.1.17 SSE3 instructions
50 2.1.18 AMD 3DNow! instructions
51 2.1.19 The x86-64 long mode instructions
52 2.1.20 SSE4 instructions
53 2.1.21 AVX instructions
54 2.1.22 AVX2 instructions
55 2.1.23 Auxiliary sets of computational instructions
56 2.1.24 Other extensions of instruction set
57
58 2.2 Control directives
59 2.2.1 Numerical constants
60 2.2.2 Conditional assembly
61 2.2.3 Repeating blocks of instructions
62 2.2.4 Addressing spaces
63 2.2.5 Other directives
64 2.2.6 Multiple passes
65
66 2.3 Preprocessor directives
67 2.3.1 Including source files
68 2.3.2 Symbolic constants
69 2.3.3 Macroinstructions
70 2.3.4 Structures
71 2.3.5 Repeating macroinstructions
72 2.3.6 Conditional preprocessing
73 2.3.7 Order of processing
74
75 2.4 Formatter directives
76 2.4.1 MZ executable
77 2.4.2 Portable Executable
78 2.4.3 Common Object File Format
79 2.4.4 Executable and Linkable Format
80
81
82
83 Chapter 1 Introduction
84 -----------------------
85
86 This chapter contains all the most important information you need to begin
87 using the flat assembler. If you are experienced assembly language programmer,
88 you should read at least this chapter before using this compiler.
89
90
91 1.1 Compiler overview
92
93 Flat assembler is a fast assembly language compiler for the x86 architecture
94 processors, which does multiple passes to optimize the size of generated
95 machine code. It is self-compilable and versions for different operating
96 systems are provided. All the versions are designed to be used from the system
97 command line and they should not differ in behavior.
98
99
100 1.1.1 System requirements
101
102 All versions require the x86 architecture 32-bit processor (at least 80386),
103 although they can produce programs for the x86 architecture 16-bit processors,
104 too. DOS version requires an OS compatible with MS DOS 2.0 and either true
105 real mode environment or DPMI. Windows version requires a Win32 console
106 compatible with 3.1 version.
107
108
109 1.1.2 Executing compiler from command line
110
111 To execute flat assembler from the command line you need to provide two
112 parameters - first should be name of source file, second should be name of
113 destination file. If no second parameter is given, the name for output
114 file will be guessed automatically. After displaying short information about
115 the program name and version, compiler will read the data from source file and
116 compile it. When the compilation is successful, compiler will write the
117 generated code to the destination file and display the summary of compilation
118 process; otherwise it will display the information about error that occurred.
119 The source file should be a text file, and can be created in any text
120 editor. Line breaks are accepted in both DOS and Unix standards, tabulators
121 are treated as spaces.
122 In the command line you can also include "-m" option followed by a number,
123 which specifies how many kilobytes of memory flat assembler should maximally
124 use. In case of DOS version this options limits only the usage of extended
125 memory. The "-p" option followed by a number can be used to specify the limit
126 for number of passes the assembler performs. If code cannot be generated
127 within specified amount of passes, the assembly will be terminated with an
128 error message. The maximum value of this setting is 65536, while the default
129 limit, used when no such option is included in command line, is 100.
130 It is also possible to limit the number of passes the assembler
131 performs, with the "-p" option followed by a number specifying the maximum
132 number of passes.
133 There are no command line options that would affect the output of compiler,
134 flat assembler requires only the source code to include the information it
135 really needs. For example, to specify output format you specify it by using
136 the "format" directive at the beginning of source.
137
138
139 1.1.3 Compiler messages
140
141 As it is stated above, after the successful compilation, the compiler displays
142 the compilation summary. It includes the information of how many passes was
143 done, how much time it took, and how many bytes were written into the
144 destination file.
145 The following is an example of the compilation summary:
146
147 flat assembler version 1.70 (16384 kilobytes memory)
148 38 passes, 5.3 seconds, 77824 bytes.
149
150 In case of error during the compilation process, the program will display an
151 error message. For example, when compiler can't find the input file, it will
152 display the following message:
153
154 flat assembler version 1.70 (16384 kilobytes memory)
155 error: source file not found.
156
157 If the error is connected with a specific part of source code, the source line
158 that caused the error will be also displayed. Also placement of this line in
159 the source is given to help you finding this error, for example:
160
161 flat assembler version 1.70 (16384 kilobytes memory)
162 example.asm [3]:
163 mob ax,1
164 error: illegal instruction.
165
166 It means that in the third line of the "example.asm" file compiler has
167 encountered an unrecognized instruction. When the line that caused error
168 contains a macroinstruction, also the line in macroinstruction definition
169 that generated the erroneous instruction is displayed:
170
171 flat assembler version 1.70 (16384 kilobytes memory)
172 example.asm [6]:
173 stoschar 7
174 example.asm [3] stoschar [1]:
175 mob al,char
176 error: illegal instruction.
177
178 It means that the macroinstruction in the sixth line of the "example.asm" file
179 generated an unrecognized instruction with the first line of its definition.
180
181
182 1.1.4 Output formats
183
184 By default, when there is no "format" directive in source file, flat
185 assembler simply puts generated instruction codes into output, creating this
186 way flat binary file. By default it generates 16-bit code, but you can always
187 turn it into the 16-bit or 32-bit mode by using "use16" or "use32" directive.
188 Some of the output formats switch into 32-bit mode, when selected - more
189 information about formats which you can choose can be found in 2.4.
190 All output code is always in the order in which it was entered into the
191 source file.
192
193
194 1.2 Assembly syntax
195
196 The information provided below is intended mainly for the assembler
197 programmers that have been using some other assembly compilers before.
198 If you are beginner, you should look for the assembly programming tutorials.
199 Flat assembler by default uses the Intel syntax for the assembly
200 instructions, although you can customize it using the preprocessor
201 capabilities (macroinstructions and symbolic constants). It also has its own
202 set of the directives - the instructions for compiler.
203 All symbols defined inside the sources are case-sensitive.
204
205
206 1.2.1 Instruction syntax
207
208 Instructions in assembly language are separated by line breaks, and one
209 instruction is expected to fill the one line of text. If a line contains
210 a semicolon, except for the semicolons inside the quoted strings, the rest of
211 this line is the comment and compiler ignores it. If a line ends with "\"
212 character (eventually the semicolon and comment may follow it), the next line
213 is attached at this point.
214 Each line in source is the sequence of items, which may be one of the three
215 types. One type are the symbol characters, which are the special characters
216 that are individual items even when are not spaced from the other ones.
217 Any of the "+-*/=<>()[]{}:,|&~#`" is the symbol character. The sequence of
218 other characters, separated from other items with either blank spaces or
219 symbol characters, is a symbol. If the first character of symbol is either a
220 single or double quote, it integrates any sequence of characters following it,
221 even the special ones, into a quoted string, which should end with the same
222 character, with which it began (the single or double quote) - however if there
223 are two such characters in a row (without any other character between them),
224 they are integrated into quoted string as just one of them and the quoted
225 string continues then. The symbols other than symbol characters and quoted
226 strings can be used as names, so are also called the name symbols.
227 Every instruction consists of the mnemonic and the various number of
228 operands, separated with commas. The operand can be register, immediate value
229 or a data addressed in memory, it can also be preceded by size operator to
230 define or override its size (table 1.1). Names of available registers you can
231 find in table 1.2, their sizes cannot be overridden. Immediate value can be
232 specified by any numerical expression.
233 When operand is a data in memory, the address of that data (also any
234 numerical expression, but it may contain registers) should be enclosed in
235 square brackets or preceded by "ptr" operator. For example instruction
236 "mov eax,3" will put the immediate value 3 into the EAX register, instruction
237 "mov eax,[7]" will put the 32-bit value from the address 7 into EAX and the
238 instruction "mov byte [7],3" will put the immediate value 3 into the byte at
239 address 7, it can also be written as "mov byte ptr 7,3". To specify which
240 segment register should be used for addressing, segment register name followed
241 by a colon should be put just before the address value (inside the square
242 brackets or after the "ptr" operator).
243
244 Table 1.1 Size operators
245 /-------------------------\
246 | Operator | Bits | Bytes |
247 |==========|======|=======|
248 | byte | 8 | 1 |
249 | word | 16 | 2 |
250 | dword | 32 | 4 |
251 | fword | 48 | 6 |
252 | pword | 48 | 6 |
253 | qword | 64 | 8 |
254 | tbyte | 80 | 10 |
255 | tword | 80 | 10 |
256 | dqword | 128 | 16 |
257 | xword | 128 | 16 |
258 | qqword | 256 | 32 |
259 | yword | 256 | 32 |
260 \-------------------------/
261
262 Table 1.2 Registers
263 /-----------------------------------------------------------------\
264 | Type | Bits | |
265 |=========|======|================================================|
266 | | 8 | al cl dl bl ah ch dh bh |
267 | General | 16 | ax cx dx bx sp bp si di |
268 | | 32 | eax ecx edx ebx esp ebp esi edi |
269 |---------|------|------------------------------------------------|
270 | Segment | 16 | es cs ss ds fs gs |
271 |---------|------|------------------------------------------------|
272 | Control | 32 | cr0 cr2 cr3 cr4 |
273 |---------|------|------------------------------------------------|
274 | Debug | 32 | dr0 dr1 dr2 dr3 dr6 dr7 |
275 |---------|------|------------------------------------------------|
276 | FPU | 80 | st0 st1 st2 st3 st4 st5 st6 st7 |
277 |---------|------|------------------------------------------------|
278 | MMX | 64 | mm0 mm1 mm2 mm3 mm4 mm5 mm6 mm7 |
279 |---------|------|------------------------------------------------|
280 | SSE | 128 | xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7 |
281 |---------|------|------------------------------------------------|
282 | AVX | 256 | ymm0 ymm1 ymm2 ymm3 ymm4 ymm5 ymm6 ymm7 |
283 \-----------------------------------------------------------------/
284
285
286 1.2.2 Data definitions
287
288 To define data or reserve a space for it, use one of the directives listed in
289 table 1.3. The data definition directive should be followed by one or more of
290 numerical expressions, separated with commas. These expressions define the
291 values for data cells of size depending on which directive is used. For
292 example "db 1,2,3" will define the three bytes of values 1, 2 and 3
293 respectively.
294 The "db" and "du" directives also accept the quoted string values of any
295 length, which will be converted into chain of bytes when "db" is used and into
296 chain of words with zeroed high byte when "du" is used. For example "db 'abc'"
297 will define the three bytes of values 61, 62 and 63.
298 The "dp" directive and its synonym "df" accept the values consisting of two
299 numerical expressions separated with colon, the first value will become the
300 high word and the second value will become the low double word of the far
301 pointer value. Also "dd" accepts such pointers consisting of two word values
302 separated with colon, and "dt" accepts the word and quad word value separated
303 with colon, the quad word is stored first. The "dt" directive with single
304 expression as parameter accepts only floating point values and creates data in
305 FPU double extended precision format.
306 Any of the above directive allows the usage of special "dup" operator to
307 make multiple copies of given values. The count of duplicates should precede
308 this operator and the value to duplicate should follow - it can even be the
309 chain of values separated with commas, but such set of values needs to be
310 enclosed with parenthesis, like "db 5 dup (1,2)", which defines five copies
311 of the given two byte sequence.
312 The "file" is a special directive and its syntax is different. This
313 directive includes a chain of bytes from file and it should be followed by the
314 quoted file name, then optionally numerical expression specifying offset in
315 file preceded by the colon, and - also optionally - comma and numerical
316 expression specifying count of bytes to include (if no count is specified, all
317 data up to the end of file is included). For example "file 'data.bin'" will
318 include the whole file as binary data and "file 'data.bin':10h,4" will include
319 only four bytes starting at offset 10h.
320 The data reservation directive should be followed by only one numerical
321 expression, and this value defines how many cells of the specified size should
322 be reserved. All data definition directives also accept the "?" value, which
323 means that this cell should not be initialized to any value and the effect is
324 the same as by using the data reservation directive. The uninitialized data
325 may not be included in the output file, so its values should be always
326 considered unknown.
327
328 Table 1.3 Data directives
329 /----------------------------\
330 | Size | Define | Reserve |
331 | (bytes) | data | data |
332 |=========|========|=========|
333 | 1 | db | rb |
334 | | file | |
335 |---------|--------|---------|
336 | 2 | dw | rw |
337 | | du | |
338 |---------|--------|---------|
339 | 4 | dd | rd |
340 |---------|--------|---------|
341 | 6 | dp | rp |
342 | | df | rf |
343 |---------|--------|---------|
344 | 8 | dq | rq |
345 |---------|--------|---------|
346 | 10 | dt | rt |
347 \----------------------------/
348
349
350 1.2.3 Constants and labels
351
352 In the numerical expressions you can also use constants or labels instead of
353 numbers. To define the constant or label you should use the specific
354 directives. Each label can be defined only once and it is accessible from the
355 any place of source (even before it was defined). Constant can be redefined
356 many times, but in this case it is accessible only after it was defined, and
357 is always equal to the value from last definition before the place where it's
358 used. When a constant is defined only once in source, it is - like the label -
359 accessible from anywhere.
360 The definition of constant consists of name of the constant followed by the
361 "=" character and numerical expression, which after calculation will become
362 the value of constant. This value is always calculated at the time the
363 constant is defined. For example you can define "count" constant by using the
364 directive "count = 17", and then use it in the assembly instructions, like
365 "mov cx,count" - which will become "mov cx,17" during the compilation process.
366 There are different ways to define labels. The simplest is to follow the
367 name of label by the colon, this directive can even be followed by the other
368 instruction in the same line. It defines the label whose value is equal to
369 offset of the point where it's defined. This method is usually used to label
370 the places in code. The other way is to follow the name of label (without a
371 colon) by some data directive. It defines the label with value equal to
372 offset of the beginning of defined data, and remembered as a label for data
373 with cell size as specified for that data directive in table 1.3.
374 The label can be treated as constant of value equal to offset of labeled
375 code or data. For example when you define data using the labeled directive
376 "char db 224", to put the offset of this data into BX register you should use
377 "mov bx,char" instruction, and to put the value of byte addressed by "char"
378 label to DL register, you should use "mov dl,[char]" (or "mov dl,ptr char").
379 But when you try to assemble "mov ax,[char]", it will cause an error, because
380 fasm compares the sizes of operands, which should be equal. You can force
381 assembling that instruction by using size override: "mov ax,word [char]", but
382 remember that this instruction will read the two bytes beginning at "char"
383 address, while it was defined as a one byte.
384 The last and the most flexible way to define labels is to use "label"
385 directive. This directive should be followed by the name of label, then
386 optionally size operator (it can be preceded by a colon) and then - also
387 optionally "at" operator and the numerical expression defining the address at
388 which this label should be defined. For example "label wchar word at char"
389 will define a new label for the 16-bit data at the address of "char". Now the
390 instruction "mov ax,[wchar]" will be after compilation the same as
391 "mov ax,word [char]". If no address is specified, "label" directive defines
392 the label at current offset. Thus "mov [wchar],57568" will copy two bytes
393 while "mov [char],224" will copy one byte to the same address.
394 The label whose name begins with dot is treated as local label, and its name
395 is attached to the name of last global label (with name beginning with
396 anything but dot) to make the full name of this label. So you can use the
397 short name (beginning with dot) of this label anywhere before the next global
398 label is defined, and in the other places you have to use the full name. Label
399 beginning with two dots are the exception - they are like global, but they
400 don't become the new prefix for local labels.
401 The "@@" name means anonymous label, you can have defined many of them in
402 the source. Symbol "@b" (or equivalent "@r") references the nearest preceding
403 anonymous label, symbol "@f" references the nearest following anonymous label.
404 These special symbol are case-insensitive.
405
406
407 1.2.4 Numerical expressions
408
409 In the above examples all the numerical expressions were the simple numbers,
410 constants or labels. But they can be more complex, by using the arithmetical
411 or logical operators for calculations at compile time. All these operators
412 with their priority values are listed in table 1.4. The operations with higher
413 priority value will be calculated first, you can of course change this
414 behavior by putting some parts of expression into parenthesis. The "+", "-",
415 "*" and "/" are standard arithmetical operations, "mod" calculates the
416 remainder from division. The "and", "or", "xor", "shl", "shr" and "not"
417 perform the same logical operations as assembly instructions of those names.
418 The "rva" and "plt" are special unary operators that perform conversions
419 between different kinds of addresses, they can be used only with few of the
420 output formats and their meaning may vary (see 2.4).
421 The arithmetical and logical calculations are usually processed as if they
422 operated on infinite precision 2-adic numbers, and assembler signalizes an
423 overflow error if because of its limitations it is not table to perform the
424 required calculation, or if the result is too large number to fit in either
425 signed or unsigned range for the destination unit size. However "not", "xor"
426 and "shr" operators are exceptions from this rule - if the value specified
427 by numerical expression has to fit in a unit of specified size, and the
428 arguments for operation fit into that size, the operation will be performed
429 with precision limited to that size.
430 The numbers in the expression are by default treated as a decimal, binary
431 numbers should have the "b" letter attached at the end, octal number should
432 end with "o" letter, hexadecimal numbers should begin with "0x" characters
433 (like in C language) or with the "$" character (like in Pascal language) or
434 they should end with "h" letter. Also quoted string, when encountered in
435 expression, will be converted into number - the first character will become
436 the least significant byte of number.
437 The numerical expression used as an address value can also contain any of
438 general registers used for addressing, they can be added and multiplied by
439 appropriate values, as it is allowed for the x86 architecture instructions.
440 The numerical calculations inside address definition by default operate with
441 target size assumed to be the same as the current bitness of code, even if
442 generated instruction encoding will use a different address size.
443 There are also some special symbols that can be used inside the numerical
444 expression. First is "$", which is always equal to the value of current
445 offset, while "$$" is equal to base address of current addressing space. The
446 other one is "%", which is the number of current repeat in parts of code that
447 are repeated using some special directives (see 2.2) and zero anywhere else.
448 There's also "%t" symbol, which is always equal to the current time stamp.
449 Any numerical expression can also consist of single floating point value
450 (flat assembler does not allow any floating point operations at compilation
451 time) in the scientific notation, they can end with the "f" letter to be
452 recognized, otherwise they should contain at least one of the "." or "E"
453 characters. So "1.0", "1E0" and "1f" define the same floating point value,
454 while simple "1" defines an integer value.
455
456 Table 1.4 Arithmetical and logical operators by priority
457 /-------------------------\
458 | Priority | Operators |
459 |==========|==============|
460 | 0 | + - |
461 |----------|--------------|
462 | 1 | * / |
463 |----------|--------------|
464 | 2 | mod |
465 |----------|--------------|
466 | 3 | and or xor |
467 |----------|--------------|
468 | 4 | shl shr |
469 |----------|--------------|
470 | 5 | not |
471 |----------|--------------|
472 | 6 | rva plt |
473 \-------------------------/
474
475
476 1.2.5 Jumps and calls
477
478 The operand of any jump or call instruction can be preceded not only by the
479 size operator, but also by one of the operators specifying type of the jump:
480 "short", "near" or "far". For example, when assembler is in 16-bit mode,
481 instruction "jmp dword [0]" will become the far jump and when assembler is
482 in 32-bit mode, it will become the near jump. To force this instruction to be
483 treated differently, use the "jmp near dword [0]" or "jmp far dword [0]" form.
484 When operand of near jump is the immediate value, assembler will generate
485 the shortest variant of this jump instruction if possible (but will not create
486 32-bit instruction in 16-bit mode nor 16-bit instruction in 32-bit mode,
487 unless there is a size operator stating it). By specifying the jump type
488 you can force it to always generate long variant (for example "jmp near 0")
489 or to always generate short variant and terminate with an error when it's
490 impossible (for example "jmp short 0").
491
492
493 1.2.6 Size settings
494
495 When instruction uses some memory addressing, by default the smallest form of
496 instruction is generated by using the short displacement if only address
497 value fits in the range. This can be overridden using the "word" or "dword"
498 operator before the address inside the square brackets (or after the "ptr"
499 operator), which forces the long displacement of appropriate size to be made.
500 In case when address is not relative to any registers, those operators allow
501 also to choose the appropriate mode of absolute addressing.
502 Instructions "adc", "add", "and", "cmp", "or", "sbb", "sub" and "xor" with
503 first operand being 16-bit or 32-bit are by default generated in shortened
504 8-bit form when the second operand is immediate value fitting in the range
505 for signed 8-bit values. It also can be overridden by putting the "word" or
506 "dword" operator before the immediate value. The similar rules applies to the
507 "imul" instruction with the last operand being immediate value.
508 Immediate value as an operand for "push" instruction without a size operator
509 is by default treated as a word value if assembler is in 16-bit mode and as a
510 double word value if assembler is in 32-bit mode, shorter 8-bit form of this
511 instruction is used if possible, "word" or "dword" size operator forces the
512 "push" instruction to be generated in longer form for specified size. "pushw"
513 and "pushd" mnemonics force assembler to generate 16-bit or 32-bit code
514 without forcing it to use the longer form of instruction.
515
516
517 Chapter 2 Instruction set
518 --------------------------
519
520 This chapter provides the detailed information about the instructions and
521 directives supported by flat assembler. Directives for defining labels were
522 already discussed in 1.2.3, all other directives will be described later in
523 this chapter.
524
525
526 2.1 The x86 architecture instructions
527
528 In this section you can find both the information about the syntax and
529 purpose the assembly language instructions. If you need more technical
530 information, look for the Intel Architecture Software Developer's Manual.
531 Assembly instructions consist of the mnemonic (instruction's name) and from
532 zero to three operands. If there are two or more operands, usually first is
533 the destination operand and second is the source operand. Each operand can be
534 register, memory or immediate value (see 1.2 for details about syntax of
535 operands). After the description of each instruction there are examples
536 of different combinations of operands, if the instruction has any.
537 Some instructions act as prefixes and can be followed by other instruction
538 in the same line, and there can be more than one prefix in a line. Each name
539 of the segment register is also a mnemonic of instruction prefix, altough it
540 is recommended to use segment overrides inside the square brackets instead of
541 these prefixes.
542
543
544 2.1.1 Data movement instructions
545
546 "mov" transfers a byte, word or double word from the source operand to the
547 destination operand. It can transfer data between general registers, from
548 the general register to memory, or from memory to general register, but it
549 cannot move from memory to memory. It can also transfer an immediate value to
550 general register or memory, segment register to general register or memory,
551 general register or memory to segment register, control or debug register to
552 general register and general register to control or debug register. The "mov"
553 can be assembled only if the size of source operand and size of destination
554 operand are the same. Below are the examples for each of the allowed
555 combinations:
556
557 mov bx,ax ; general register to general register
558 mov [char],al ; general register to memory
559 mov bl,[char] ; memory to general register
560 mov dl,32 ; immediate value to general register
561 mov [char],32 ; immediate value to memory
562 mov ax,ds ; segment register to general register
563 mov [bx],ds ; segment register to memory
564 mov ds,ax ; general register to segment register
565 mov ds,[bx] ; memory to segment register
566 mov eax,cr0 ; control register to general register
567 mov cr3,ebx ; general register to control register
568
569 "xchg" swaps the contents of two operands. It can swap two byte operands,
570 two word operands or two double word operands. Order of operands is not
571 important. The operands may be two general registers, or general register
572 with memory. For example:
573
574 xchg ax,bx ; swap two general registers
575 xchg al,[char] ; swap register with memory
576
577 "push" decrements the stack frame pointer (ESP register), then transfers
578 the operand to the top of stack indicated by ESP. The operand can be memory,
579 general register, segment register or immediate value of word or double word
580 size. If operand is an immediate value and no size is specified, it is by
581 default treated as a word value if assembler is in 16-bit mode and as a double
582 word value if assembler is in 32-bit mode. "pushw" and "pushd" mnemonics are
583 variants of this instruction that store the values of word or double word size
584 respectively. If more operands follow in the same line (separated only with
585 spaces, not commas), compiler will assemble chain of the "push" instructions
586 with these operands. The examples are with single operands:
587
588 push ax ; store general register
589 push es ; store segment register
590 pushw [bx] ; store memory
591 push 1000h ; store immediate value
592
593 "pusha" saves the contents of the eight general register on the stack.
594 This instruction has no operands. There are two version of this instruction,
595 one 16-bit and one 32-bit, assembler automatically generates the appropriate
596 version for current mode, but it can be overridden by using "pushaw" or
597 "pushad" mnemonic to always get the 16-bit or 32-bit version. The 16-bit
598 version of this instruction pushes general registers on the stack in the
599 following order: AX, CX, DX, BX, the initial value of SP before AX was pushed,
600 BP, SI and DI. The 32-bit version pushes equivalent 32-bit general registers
601 in the same order.
602 "pop" transfers the word or double word at the current top of stack to the
603 destination operand, and then increments ESP to point to the new top of stack.
604 The operand can be memory, general register or segment register. "popw" and
605 "popd" mnemonics are variants of this instruction for restoring the values of
606 word or double word size respectively. If more operands separated with spaces
607 follow in the same line, compiler will assemble chain of the "pop"
608 instructions with these operands.
609
610 pop bx ; restore general register
611 pop ds ; restore segment register
612 popw [si] ; restore memory
613
614 "popa" restores the registers saved on the stack by "pusha" instruction,
615 except for the saved value of SP (or ESP), which is ignored. This instruction
616 has no operands. To force assembling 16-bit or 32-bit version of this
617 instruction use "popaw" or "popad" mnemonic.
618
619
620 2.1.2 Type conversion instructions
621
622 The type conversion instructions convert bytes into words, words into double
623 words, and double words into quad words. These conversions can be done using
624 the sign extension or zero extension. The sign extension fills the extra bits
625 of the larger item with the value of the sign bit of the smaller item, the
626 zero extension simply fills them with zeros.
627 "cwd" and "cdq" double the size of value AX or EAX register respectively
628 and store the extra bits into the DX or EDX register. The conversion is done
629 using the sign extension. These instructions have no operands.
630 "cbw" extends the sign of the byte in AL throughout AX, and "cwde" extends
631 the sign of the word in AX throughout EAX. These instructions also have no
632 operands.
633 "movsx" converts a byte to word or double word and a word to double word
634 using the sign extension. "movzx" does the same, but it uses the zero
635 extension. The source operand can be general register or memory, while the
636 destination operand must be a general register. For example:
637
638 movsx ax,al ; byte register to word register
639 movsx edx,dl ; byte register to double word register
640 movsx eax,ax ; word register to double word register
641 movsx ax,byte [bx] ; byte memory to word register
642 movsx edx,byte [bx] ; byte memory to double word register
643 movsx eax,word [bx] ; word memory to double word register
644
645
646 2.1.3 Binary arithmetic instructions
647
648 "add" replaces the destination operand with the sum of the source and
649 destination operands and sets CF if overflow has occurred. The operands may
650 be bytes, words or double words. The destination operand can be general
651 register or memory, the source operand can be general register or immediate
652 value, it can also be memory if the destination operand is register.
653
654 add ax,bx ; add register to register
655 add ax,[si] ; add memory to register
656 add [di],al ; add register to memory
657 add al,48 ; add immediate value to register
658 add [char],48 ; add immediate value to memory
659
660 "adc" sums the operands, adds one if CF is set, and replaces the destination
661 operand with the result. Rules for the operands are the same as for the "add"
662 instruction. An "add" followed by multiple "adc" instructions can be used to
663 add numbers longer than 32 bits.
664 "inc" adds one to the operand, it does not affect CF. The operand can be a
665 general register or memory, and the size of the operand can be byte, word or
666 double word.
667
668 inc ax ; increment register by one
669 inc byte [bx] ; increment memory by one
670
671 "sub" subtracts the source operand from the destination operand and replaces
672 the destination operand with the result. If a borrow is required, the CF is
673 set. Rules for the operands are the same as for the "add" instruction.
674 "sbb" subtracts the source operand from the destination operand, subtracts
675 one if CF is set, and stores the result to the destination operand. Rules for
676 the operands are the same as for the "add" instruction. A "sub" followed by
677 multiple "sbb" instructions may be used to subtract numbers longer than 32
678 bits.
679 "dec" subtracts one from the operand, it does not affect CF. Rules for the
680 operand are the same as for the "inc" instruction.
681 "cmp" subtracts the source operand from the destination operand. It updates
682 the flags as the "sub" instruction, but does not alter the source and
683 destination operands. Rules for the operands are the same as for the "sub"
684 instruction.
685 "neg" subtracts a signed integer operand from zero. The effect of this
686 instructon is to reverse the sign of the operand from positive to negative or
687 from negative to positive. Rules for the operand are the same as for the "inc"
688 instruction.
689 "xadd" exchanges the destination operand with the source operand, then loads
690 the sum of the two values into the destination operand. Rules for the operands
691 are the same as for the "add" instruction.
692 All the above binary arithmetic instructions update SF, ZF, PF and OF flags.
693 SF is always set to the same value as the result's sign bit, ZF is set when
694 all the bits of result are zero, PF is set when low order eight bits of result
695 contain an even number of set bits, OF is set if result is too large for a
696 positive number or too small for a negative number (excluding sign bit) to fit
697 in destination operand.
698 "mul" performs an unsigned multiplication of the operand and the
699 accumulator. If the operand is a byte, the processor multiplies it by the
700 contents of AL and returns the 16-bit result to AH and AL. If the operand is a
701 word, the processor multiplies it by the contents of AX and returns the 32-bit
702 result to DX and AX. If the operand is a double word, the processor multiplies
703 it by the contents of EAX and returns the 64-bit result in EDX and EAX. "mul"
704 sets CF and OF when the upper half of the result is nonzero, otherwise they
705 are cleared. Rules for the operand are the same as for the "inc" instruction.
706 "imul" performs a signed multiplication operation. This instruction has
707 three variations. First has one operand and behaves in the same way as the
708 "mul" instruction. Second has two operands, in this case destination operand
709 is multiplied by the source operand and the result replaces the destination
710 operand. Destination operand must be a general register, it can be word or
711 double word, source operand can be general register, memory or immediate
712 value. Third form has three operands, the destination operand must be a
713 general register, word or double word in size, source operand can be general
714 register or memory, and third operand must be an immediate value. The source
715 operand is multiplied by the immediate value and the result is stored in the
716 destination register. All the three forms calculate the product to twice the
717 size of operands and set CF and OF when the upper half of the result is
718 nonzero, but second and third form truncate the product to the size of
719 operands. So second and third forms can be also used for unsigned operands
720 because, whether the operands are signed or unsigned, the lower half of the
721 product is the same. Below are the examples for all three forms:
722
723 imul bl ; accumulator by register
724 imul word [si] ; accumulator by memory
725 imul bx,cx ; register by register
726 imul bx,[si] ; register by memory
727 imul bx,10 ; register by immediate value
728 imul ax,bx,10 ; register by immediate value to register
729 imul ax,[si],10 ; memory by immediate value to register
730
731 "div" performs an unsigned division of the accumulator by the operand.
732 The dividend (the accumulator) is twice the size of the divisor (the operand),
733 the quotient and remainder have the same size as the divisor. If divisor is
734 byte, the dividend is taken from AX register, the quotient is stored in AL and
735 the remainder is stored in AH. If divisor is word, the upper half of dividend
736 is taken from DX, the lower half of dividend is taken from AX, the quotient is
737 stored in AX and the remainder is stored in DX. If divisor is double word,
738 the upper half of dividend is taken from EDX, the lower half of dividend is
739 taken from EAX, the quotient is stored in EAX and the remainder is stored in
740 EDX. Rules for the operand are the same as for the "mul" instruction.
741 "idiv" performs a signed division of the accumulator by the operand.
742 It uses the same registers as the "div" instruction, and the rules for
743 the operand are the same.
744
745
746 2.1.4 Decimal arithmetic instructions
747
748 Decimal arithmetic is performed by combining the binary arithmetic
749 instructions (already described in the prior section) with the decimal
750 arithmetic instructions. The decimal arithmetic instructions are used to
751 adjust the results of a previous binary arithmetic operation to produce a
752 valid packed or unpacked decimal result, or to adjust the inputs to a
753 subsequent binary arithmetic operation so the operation will produce a valid
754 packed or unpacked decimal result.
755 "daa" adjusts the result of adding two valid packed decimal operands in
756 AL. "daa" must always follow the addition of two pairs of packed decimal
757 numbers (one digit in each half-byte) to obtain a pair of valid packed
758 decimal digits as results. The carry flag is set if carry was needed.
759 This instruction has no operands.
760 "das" adjusts the result of subtracting two valid packed decimal operands
761 in AL. "das" must always follow the subtraction of one pair of packed decimal
762 numbers (one digit in each half-byte) from another to obtain a pair of valid
763 packed decimal digits as results. The carry flag is set if a borrow was
764 needed. This instruction has no operands.
765 "aaa" changes the contents of register AL to a valid unpacked decimal
766 number, and zeroes the top four bits. "aaa" must always follow the addition
767 of two unpacked decimal operands in AL. The carry flag is set and AH is
768 incremented if a carry is necessary. This instruction has no operands.
769 "aas" changes the contents of register AL to a valid unpacked decimal
770 number, and zeroes the top four bits. "aas" must always follow the
771 subtraction of one unpacked decimal operand from another in AL. The carry flag
772 is set and AH decremented if a borrow is necessary. This instruction has no
773 operands.
774 "aam" corrects the result of a multiplication of two valid unpacked decimal
775 numbers. "aam" must always follow the multiplication of two decimal numbers
776 to produce a valid decimal result. The high order digit is left in AH, the
777 low order digit in AL. The generalized version of this instruction allows
778 adjustment of the contents of the AX to create two unpacked digits of any
779 number base. The standard version of this instruction has no operands, the
780 generalized version has one operand - an immediate value specifying the
781 number base for the created digits.
782 "aad" modifies the numerator in AH and AL to prepare for the division of two
783 valid unpacked decimal operands so that the quotient produced by the division
784 will be a valid unpacked decimal number. AH should contain the high order
785 digit and AL the low order digit. This instruction adjusts the value and
786 places the result in AL, while AH will contain zero. The generalized version
787 of this instruction allows adjustment of two unpacked digits of any number
788 base. Rules for the operand are the same as for the "aam" instruction.
789
790
791 2.1.5 Logical instructions
792
793 "not" inverts the bits in the specified operand to form a one's complement
794 of the operand. It has no effect on the flags. Rules for the operand are the
795 same as for the "inc" instruction.
796 "and", "or" and "xor" instructions perform the standard logical operations.
797 They update the SF, ZF and PF flags. Rules for the operands are the same as
798 for the "add" instruction.
799 "bt", "bts", "btr" and "btc" instructions operate on a single bit which can
800 be in memory or in a general register. The location of the bit is specified
801 as an offset from the low order end of the operand. The value of the offset
802 is the taken from the second operand, it either may be an immediate byte or
803 a general register. These instructions first assign the value of the selected
804 bit to CF. "bt" instruction does nothing more, "bts" sets the selected bit to
805 1, "btr" resets the selected bit to 0, "btc" changes the bit to its
806 complement. The first operand can be word or double word.
807
808 bt ax,15 ; test bit in register
809 bts word [bx],15 ; test and set bit in memory
810 btr ax,cx ; test and reset bit in register
811 btc word [bx],cx ; test and complement bit in memory
812
813 "bsf" and "bsr" instructions scan a word or double word for first set bit
814 and store the index of this bit into destination operand, which must be
815 general register. The bit string being scanned is specified by source operand,
816 it may be either general register or memory. The ZF flag is set if the entire
817 string is zero (no set bits are found); otherwise it is cleared. If no set bit
818 is found, the value of the destination register is undefined. "bsf" scans from
819 low order to high order (starting from bit index zero). "bsr" scans from high
820 order to low order (starting from bit index 15 of a word or index 31 of a
821 double word).
822
823 bsf ax,bx ; scan register forward
824 bsr ax,[si] ; scan memory reverse
825
826 "shl" shifts the destination operand left by the number of bits specified
827 in the second operand. The destination operand can be byte, word, or double
828 word general register or memory. The second operand can be an immediate value
829 or the CL register. The processor shifts zeros in from the right (low order)
830 side of the operand as bits exit from the left side. The last bit that exited
831 is stored in CF. "sal" is a synonym for "shl".
832
833 shl al,1 ; shift register left by one bit
834 shl byte [bx],1 ; shift memory left by one bit
835 shl ax,cl ; shift register left by count from cl
836 shl word [bx],cl ; shift memory left by count from cl
837
838 "shr" and "sar" shift the destination operand right by the number of bits
839 specified in the second operand. Rules for operands are the same as for the
840 "shl" instruction. "shr" shifts zeros in from the left side of the operand as
841 bits exit from the right side. The last bit that exited is stored in CF.
842 "sar" preserves the sign of the operand by shifting in zeros on the left side
843 if the value is positive or by shifting in ones if the value is negative.
844 "shld" shifts bits of the destination operand to the left by the number
845 of bits specified in third operand, while shifting high order bits from the
846 source operand into the destination operand on the right. The source operand
847 remains unmodified. The destination operand can be a word or double word
848 general register or memory, the source operand must be a general register,
849 third operand can be an immediate value or the CL register.
850
851 shld ax,bx,1 ; shift register left by one bit
852 shld [di],bx,1 ; shift memory left by one bit
853 shld ax,bx,cl ; shift register left by count from cl
854 shld [di],bx,cl ; shift memory left by count from cl
855
856 "shrd" shifts bits of the destination operand to the right, while shifting
857 low order bits from the source operand into the destination operand on the
858 left. The source operand remains unmodified. Rules for operands are the same
859 as for the "shld" instruction.
860 "rol" and "rcl" rotate the byte, word or double word destination operand
861 left by the number of bits specified in the second operand. For each rotation
862 specified, the high order bit that exits from the left of the operand returns
863 at the right to become the new low order bit. "rcl" additionally puts in CF
864 each high order bit that exits from the left side of the operand before it
865 returns to the operand as the low order bit on the next rotation cycle. Rules
866 for operands are the same as for the "shl" instruction.
867 "ror" and "rcr" rotate the byte, word or double word destination operand
868 right by the number of bits specified in the second operand. For each rotation
869 specified, the low order bit that exits from the right of the operand returns
870 at the left to become the new high order bit. "rcr" additionally puts in CF
871 each low order bit that exits from the right side of the operand before it
872 returns to the operand as the high order bit on the next rotation cycle.
873 Rules for operands are the same as for the "shl" instruction.
874 "test" performs the same action as the "and" instruction, but it does not
875 alter the destination operand, only updates flags. Rules for the operands are
876 the same as for the "and" instruction.
877 "bswap" reverses the byte order of a 32-bit general register: bits 0 through
878 7 are swapped with bits 24 through 31, and bits 8 through 15 are swapped with
879 bits 16 through 23. This instruction is provided for converting little-endian
880 values to big-endian format and vice versa.
881
882 bswap edx ; swap bytes in register
883
884
885 2.1.6 Control transfer instructions
886
887 "jmp" unconditionally transfers control to the target location. The
888 destination address can be specified directly within the instruction or
889 indirectly through a register or memory, the acceptable size of this address
890 depends on whether the jump is near or far (it can be specified by preceding
891 the operand with "near" or "far" operator) and whether the instruction is
892 16-bit or 32-bit. Operand for near jump should be "word" size for 16-bit
893 instruction or the "dword" size for 32-bit instruction. Operand for far jump
894 should be "dword" size for 16-bit instruction or "pword" size for 32-bit
895 instruction. A direct "jmp" instruction includes the destination address as
896 part of the instruction (and can be preceded by "short", "near" or "far"
897 operator), the operand specifying address should be the numerical expression
898 for near or short jump, or two numerical expressions separated with colon for
899 far jump, the first specifies selector of segment, the second is the offset
900 within segment. The "pword" operator can be used to force the 32-bit far call,
901 and "dword" to force the 16-bit far call. An indirect "jmp" instruction
902 obtains the destination address indirectly through a register or a pointer
903 variable, the operand should be general register or memory. See also 1.2.5 for
904 some more details.
905
906 jmp 100h ; direct near jump
907 jmp 0FFFFh:0 ; direct far jump
908 jmp ax ; indirect near jump
909 jmp pword [ebx] ; indirect far jump
910
911 "call" transfers control to the procedure, saving on the stack the address
912 of the instruction following the "call" for later use by a "ret" (return)
913 instruction. Rules for the operands are the same as for the "jmp" instruction,
914 but the "call" has no short variant of direct instruction and thus it not
915 optimized.
916 "ret", "retn" and "retf" instructions terminate the execution of a procedure
917 and transfers control back to the program that originally invoked the
918 procedure using the address that was stored on the stack by the "call"
919 instruction. "ret" is the equivalent for "retn", which returns from the
920 procedure that was executed using the near call, while "retf" returns from
921 the procedure that was executed using the far call. These instructions default
922 to the size of address appropriate for the current code setting, but the size
923 of address can be forced to 16-bit by using the "retw", "retnw" and "retfw"
924 mnemonics, and to 32-bit by using the "retd", "retnd" and "retfd" mnemonics.
925 All these instructions may optionally specify an immediate operand, by adding
926 this constant to the stack pointer, they effectively remove any arguments that
927 the calling program pushed on the stack before the execution of the "call"
928 instruction.
929 "iret" returns control to an interrupted procedure. It differs from "ret" in
930 that it also pops the flags from the stack into the flags register. The flags
931 are stored on the stack by the interrupt mechanism. It defaults to the size of
932 return address appropriate for the current code setting, but it can be forced
933 to use 16-bit or 32-bit address by using the "iretw" or "iretd" mnemonic.
934 The conditional transfer instructions are jumps that may or may not transfer
935 control, depending on the state of the CPU flags when the instruction
936 executes. The mnemonics for conditional jumps may be obtained by attaching
937 the condition mnemonic (see table 2.1) to the "j" mnemonic,
938 for example "jc" instruction will transfer the control when the CF flag is
939 set. The conditional jumps can be short or near, and direct only, and can be
940 optimized (see 1.2.5), the operand should be an immediate value specifying
941 target address.
942
943 Table 2.1 Conditions
944 /-----------------------------------------------------------\
945 | Mnemonic | Condition tested | Description |
946 |==========|=======================|========================|
947 | o | OF = 1 | overflow |
948 |----------|-----------------------|------------------------|
949 | no | OF = 0 | not overflow |
950 |----------|-----------------------|------------------------|
951 | c | | carry |
952 | b | CF = 1 | below |
953 | nae | | not above nor equal |
954 |----------|-----------------------|------------------------|
955 | nc | | not carry |
956 | ae | CF = 0 | above or equal |
957 | nb | | not below |
958 |----------|-----------------------|------------------------|
959 | e | ZF = 1 | equal |
960 | z | | zero |
961 |----------|-----------------------|------------------------|
962 | ne | ZF = 0 | not equal |
963 | nz | | not zero |
964 |----------|-----------------------|------------------------|
965 | be | CF or ZF = 1 | below or equal |
966 | na | | not above |
967 |----------|-----------------------|------------------------|
968 | a | CF or ZF = 0 | above |
969 | nbe | | not below nor equal |
970 |----------|-----------------------|------------------------|
971 | s | SF = 1 | sign |
972 |----------|-----------------------|------------------------|
973 | ns | SF = 0 | not sign |
974 |----------|-----------------------|------------------------|
975 | p | PF = 1 | parity |
976 | pe | | parity even |
977 |----------|-----------------------|------------------------|
978 | np | PF = 0 | not parity |
979 | po | | parity odd |
980 |----------|-----------------------|------------------------|
981 | l | SF xor OF = 1 | less |
982 | nge | | not greater nor equal |
983 |----------|-----------------------|------------------------|
984 | ge | SF xor OF = 0 | greater or equal |
985 | nl | | not less |
986 |----------|-----------------------|------------------------|
987 | le | (SF xor OF) or ZF = 1 | less or equal |
988 | ng | | not greater |
989 |----------|-----------------------|------------------------|
990 | g | (SF xor OF) or ZF = 0 | greater |
991 | nle | | not less nor equal |
992 \-----------------------------------------------------------/
993
994 The "loop" instructions are conditional jumps that use a value placed in
995 CX (or ECX) to specify the number of repetitions of a software loop. All
996 "loop" instructions automatically decrement CX (or ECX) and terminate the
997 loop (don't transfer the control) when CX (or ECX) is zero. It uses CX or ECX
998 whether the current code setting is 16-bit or 32-bit, but it can be forced to
999 us CX with the "loopw" mnemonic or to use ECX with the "loopd" mnemonic.
1000 "loope" and "loopz" are the synonyms for the same instruction, which acts as
1001 the standard "loop", but also terminates the loop when ZF flag is set.
1002 "loopew" and "loopzw" mnemonics force them to use CX register while "looped"
1003 and "loopzd" force them to use ECX register. "loopne" and "loopnz" are the
1004 synonyms for the same instructions, which acts as the standard "loop", but
1005 also terminate the loop when ZF flag is not set. "loopnew" and "loopnzw"
1006 mnemonics force them to use CX register while "loopned" and "loopnzd" force
1007 them to use ECX register. Every "loop" instruction needs an operand being an
1008 immediate value specifying target address, it can be only short jump (in the
1009 range of 128 bytes back and 127 bytes forward from the address of instruction
1010 following the "loop" instruction).
1011 "jcxz" branches to the label specified in the instruction if it finds a
1012 value of zero in CX, "jecxz" does the same, but checks the value of ECX
1013 instead of CX. Rules for the operands are the same as for the "loop"
1014 instruction.
1015 "int" activates the interrupt service routine that corresponds to the
1016 number specified as an operand to the instruction, the number should be in
1017 range from 0 to 255. The interrupt service routine terminates with an "iret"
1018 instruction that returns control to the instruction that follows "int".
1019 "int3" mnemonic codes the short (one byte) trap that invokes the interrupt 3.
1020 "into" instruction invokes the interrupt 4 if the OF flag is set.
1021 "bound" verifies that the signed value contained in the specified register
1022 lies within specified limits. An interrupt 5 occurs if the value contained in
1023 the register is less than the lower bound or greater than the upper bound. It
1024 needs two operands, the first operand specifies the register being tested,
1025 the second operand should be memory address for the two signed limit values.
1026 The operands can be "word" or "dword" in size.
1027
1028 bound ax,[bx] ; check word for bounds
1029 bound eax,[esi] ; check double word for bounds
1030
1031
1032 2.1.7 I/O instructions
1033
1034 "in" transfers a byte, word, or double word from an input port to AL, AX,
1035 or EAX. I/O ports can be addressed either directly, with the immediate byte
1036 value coded in instruction, or indirectly via the DX register. The destination
1037 operand should be AL, AX, or EAX register. The source operand should be an
1038 immediate value in range from 0 to 255, or DX register.
1039
1040 in al,20h ; input byte from port 20h
1041 in ax,dx ; input word from port addressed by dx
1042
1043 "out" transfers a byte, word, or double word to an output port from AL, AX,
1044 or EAX. The program can specify the number of the port using the same methods
1045 as the "in" instruction. The destination operand should be an immediate value
1046 in range from 0 to 255, or DX register. The source operand should be AL, AX,
1047 or EAX register.
1048
1049 out 20h,ax ; output word to port 20h
1050 out dx,al ; output byte to port addressed by dx
1051
1052
1053 2.1.8 Strings operations
1054
1055 The string operations operate on one element of a string. A string element
1056 may be a byte, a word, or a double word. The string elements are addressed by
1057 SI and DI (or ESI and EDI) registers. After every string operation SI and/or
1058 DI (or ESI and/or EDI) are automatically updated to point to the next element
1059 of the string. If DF (direction flag) is zero, the index registers are
1060 incremented, if DF is one, they are decremented. The amount of the increment
1061 or decrement is 1, 2, or 4 depending on the size of the string element. Every
1062 string operation instruction has short forms which have no operands and use
1063 SI and/or DI when the code type is 16-bit, and ESI and/or EDI when the code
1064 type is 32-bit. SI and ESI by default address data in the segment selected
1065 by DS, DI and EDI always address data in the segment selected by ES. Short
1066 form is obtained by attaching to the mnemonic of string operation letter
1067 specifying the size of string element, it should be "b" for byte element,
1068 "w" for word element, and "d" for double word element. Full form of string
1069 operation needs operands providing the size operator and the memory addresses,
1070 which can be SI or ESI with any segment prefix, DI or EDI always with ES
1071 segment prefix.
1072 "movs" transfers the string element pointed to by SI (or ESI) to the
1073 location pointed to by DI (or EDI). Size of operands can be byte, word, or
1074 double word. The destination operand should be memory addressed by DI or EDI,
1075 the source operand should be memory addressed by SI or ESI with any segment
1076 prefix.
1077
1078 movs byte [di],[si] ; transfer byte
1079 movs word [es:di],[ss:si] ; transfer word
1080 movsd ; transfer double word
1081
1082 "cmps" subtracts the destination string element from the source string
1083 element and updates the flags AF, SF, PF, CF and OF, but it does not change
1084 any of the compared elements. If the string elements are equal, ZF is set,
1085 otherwise it is cleared. The first operand for this instruction should be the
1086 source string element addressed by SI or ESI with any segment prefix, the
1087 second operand should be the destination string element addressed by DI or
1088 EDI.
1089
1090 cmpsb ; compare bytes
1091 cmps word [ds:si],[es:di] ; compare words
1092 cmps dword [fs:esi],[edi] ; compare double words
1093
1094 "scas" subtracts the destination string element from AL, AX, or EAX
1095 (depending on the size of string element) and updates the flags AF, SF, ZF,
1096 PF, CF and OF. If the values are equal, ZF is set, otherwise it is cleared.
1097 The operand should be the destination string element addressed by DI or EDI.
1098
1099 scas byte [es:di] ; scan byte
1100 scasw ; scan word
1101 scas dword [es:edi] ; scan double word
1102
1103 "stos" places the value of AL, AX, or EAX into the destination string
1104 element. Rules for the operand are the same as for the "scas" instruction.
1105 "lods" places the source string element into AL, AX, or EAX. The operand
1106 should be the source string element addressed by SI or ESI with any segment
1107 prefix.
1108
1109 lods byte [ds:si] ; load byte
1110 lods word [cs:si] ; load word
1111 lodsd ; load double word
1112
1113 "ins" transfers a byte, word, or double word from an input port addressed
1114 by DX register to the destination string element. The destination operand
1115 should be memory addressed by DI or EDI, the source operand should be the DX
1116 register.
1117
1118 insb ; input byte
1119 ins word [es:di],dx ; input word
1120 ins dword [edi],dx ; input double word
1121
1122 "outs" transfers the source string element to an output port addressed by
1123 DX register. The destination operand should be the DX register and the source
1124 operand should be memory addressed by SI or ESI with any segment prefix.
1125
1126 outs dx,byte [si] ; output byte
1127 outsw ; output word
1128 outs dx,dword [gs:esi] ; output double word
1129
1130 The repeat prefixes "rep", "repe"/"repz", and "repne"/"repnz" specify
1131 repeated string operation. When a string operation instruction has a repeat
1132 prefix, the operation is executed repeatedly, each time using a different
1133 element of the string. The repetition terminates when one of the conditions
1134 specified by the prefix is satisfied. All three prefixes automatically
1135 decrease CX or ECX register (depending whether string operation instruction
1136 uses the 16-bit or 32-bit addressing) after each operation and repeat the
1137 associated operation until CX or ECX is zero. "repe"/"repz" and
1138 "repne"/"repnz" are used exclusively with the "scas" and "cmps" instructions
1139 (described below). When these prefixes are used, repetition of the next
1140 instruction depends on the zero flag (ZF) also, "repe" and "repz" terminate
1141 the execution when the ZF is zero, "repne" and "repnz" terminate the execution
1142 when the ZF is set.
1143
1144 rep movsd ; transfer multiple double words
1145 repe cmpsb ; compare bytes until not equal
1146
1147
1148 2.1.9 Flag control instructions
1149
1150 The flag control instructions provide a method for directly changing the
1151 state of bits in the flag register. All instructions described in this
1152 section have no operands.
1153 "stc" sets the CF (carry flag) to 1, "clc" zeroes the CF, "cmc" changes the
1154 CF to its complement. "std" sets the DF (direction flag) to 1, "cld" zeroes
1155 the DF, "sti" sets the IF (interrupt flag) to 1 and therefore enables the
1156 interrupts, "cli" zeroes the IF and therefore disables the interrupts.
1157 "lahf" copies SF, ZF, AF, PF, and CF to bits 7, 6, 4, 2, and 0 of the
1158 AH register. The contents of the remaining bits are undefined. The flags
1159 remain unaffected.
1160 "sahf" transfers bits 7, 6, 4, 2, and 0 from the AH register into SF, ZF,
1161 AF, PF, and CF.
1162 "pushf" decrements "esp" by two or four and stores the low word or
1163 double word of flags register at the top of stack, size of stored data
1164 depends on the current code setting. "pushfw" variant forces storing the
1165 word and "pushfd" forces storing the double word.
1166 "popf" transfers specific bits from the word or double word at the top
1167 of stack, then increments "esp" by two or four, this value depends on
1168 the current code setting. "popfw" variant forces restoring from the word
1169 and "popfd" forces restoring from the double word.
1170
1171
1172 2.1.10 Conditional operations
1173
1174 The instructions obtained by attaching the condition mnemonic (see table
1175 2.1) to the "set" mnemonic set a byte to one if the condition is true and set
1176 the byte to zero otherwise. The operand should be an 8-bit be general register
1177 or the byte in memory.
1178
1179 setne al ; set al if zero flag cleared
1180 seto byte [bx] ; set byte if overflow
1181
1182 "salc" instruction sets the all bits of AL register when the carry flag is
1183 set and zeroes the AL register otherwise. This instruction has no arguments.
1184 The instructions obtained by attaching the condition mnemonic to "cmov"
1185 mnemonic transfer the word or double word from the general register or memory
1186 to the general register only when the condition is true. The destination
1187 operand should be general register, the source operand can be general register
1188 or memory.
1189
1190 cmove ax,bx ; move when zero flag set
1191 cmovnc eax,[ebx] ; move when carry flag cleared
1192
1193 "cmpxchg" compares the value in the AL, AX, or EAX register with the
1194 destination operand. If the two values are equal, the source operand is
1195 loaded into the destination operand. Otherwise, the destination operand is
1196 loaded into the AL, AX, or EAX register. The destination operand may be a
1197 general register or memory, the source operand must be a general register.
1198
1199 cmpxchg dl,bl ; compare and exchange with register
1200 cmpxchg [bx],dx ; compare and exchange with memory
1201
1202 "cmpxchg8b" compares the 64-bit value in EDX and EAX registers with the
1203 destination operand. If the values are equal, the 64-bit value in ECX and EBX
1204 registers is stored in the destination operand. Otherwise, the value in the
1205 destination operand is loaded into EDX and EAX registers. The destination
1206 operand should be a quad word in memory.
1207
1208 cmpxchg8b [bx] ; compare and exchange 8 bytes
1209
1210
1211 2.1.11 Miscellaneous instructions
1212
1213 "nop" instruction occupies one byte but affects nothing but the instruction
1214 pointer. This instruction has no operands and doesn't perform any operation.
1215 "ud2" instruction generates an invalid opcode exception. This instruction
1216 is provided for software testing to explicitly generate an invalid opcode.
1217 This is instruction has no operands.
1218 "xlat" replaces a byte in the AL register with a byte indexed by its value
1219 in a translation table addressed by BX or EBX. The operand should be a byte
1220 memory addressed by BX or EBX with any segment prefix. This instruction has
1221 also a short form "xlatb" which has no operands and uses the BX or EBX address
1222 in the segment selected by DS depending on the current code setting.
1223 "lds" transfers a pointer variable from the source operand to DS and the
1224 destination register. The source operand must be a memory operand, and the
1225 destination operand must be a general register. The DS register receives the
1226 segment selector of the pointer while the destination register receives the
1227 offset part of the pointer. "les", "lfs", "lgs" and "lss" operate identically
1228 to "lds" except that rather than DS register the ES, FS, GS and SS is used
1229 respectively.
1230
1231 lds bx,[si] ; load pointer to ds:bx
1232
1233 "lea" transfers the offset of the source operand (rather than its value)
1234 to the destination operand. The source operand must be a memory operand, and
1235 the destination operand must be a general register.
1236
1237 lea dx,[bx+si+1] ; load effective address to dx
1238
1239 "cpuid" returns processor identification and feature information in the
1240 EAX, EBX, ECX, and EDX registers. The information returned is selected by
1241 entering a value in the EAX register before the instruction is executed.
1242 This instruction has no operands.
1243 "pause" instruction delays the execution of the next instruction an
1244 implementation specific amount of time. It can be used to improve the
1245 performance of spin wait loops. This instruction has no operands.
1246 "enter" creates a stack frame that may be used to implement the scope rules
1247 of block-structured high-level languages. A "leave" instruction at the end of
1248 a procedure complements an "enter" at the beginning of the procedure to
1249 simplify stack management and to control access to variables for nested
1250 procedures. The "enter" instruction includes two parameters. The first
1251 parameter specifies the number of bytes of dynamic storage to be allocated on
1252 the stack for the routine being entered. The second parameter corresponds to
1253 the lexical nesting level of the routine, it can be in range from 0 to 31.
1254 The specified lexical level determines how many sets of stack frame pointers
1255 the CPU copies into the new stack frame from the preceding frame. This list
1256 of stack frame pointers is sometimes called the display. The first word (or
1257 double word when code is 32-bit) of the display is a pointer to the last stack
1258 frame. This pointer enables a "leave" instruction to reverse the action of the
1259 previous "enter" instruction by effectively discarding the last stack frame.
1260 After "enter" creates the new display for a procedure, it allocates the
1261 dynamic storage space for that procedure by decrementing ESP by the number of
1262 bytes specified in the first parameter. To enable a procedure to address its
1263 display, "enter" leaves BP (or EBP) pointing to the beginning of the new stack
1264 frame. If the lexical level is zero, "enter" pushes BP (or EBP), copies SP to
1265 BP (or ESP to EBP) and then subtracts the first operand from ESP. For nesting
1266 levels greater than zero, the processor pushes additional frame pointers on
1267 the stack before adjusting the stack pointer.
1268
1269 enter 2048,0 ; enter and allocate 2048 bytes on stack
1270
1271
1272 2.1.12 System instructions
1273
1274 "lmsw" loads the operand into the machine status word (bits 0 through 15 of
1275 CR0 register), while "smsw" stores the machine status word into the
1276 destination operand. The operand for both those instructions can be 16-bit
1277 general register or memory, for "smsw" it can also be 32-bit general
1278 register.
1279
1280 lmsw ax ; load machine status from register
1281 smsw [bx] ; store machine status to memory
1282
1283 "lgdt" and "lidt" instructions load the values in operand into the global
1284 descriptor table register or the interrupt descriptor table register
1285 respectively. "sgdt" and "sidt" store the contents of the global descriptor
1286 table register or the interrupt descriptor table register in the destination
1287 operand. The operand should be a 6 bytes in memory.
1288
1289 lgdt [ebx] ; load global descriptor table
1290
1291 "lldt" loads the operand into the segment selector field of the local
1292 descriptor table register and "sldt" stores the segment selector from the
1293 local descriptor table register in the operand. "ltr" loads the operand into
1294 the segment selector field of the task register and "str" stores the segment
1295 selector from the task register in the operand. Rules for operand are the same
1296 as for the "lmsw" and "smsw" instructions.
1297 "lar" loads the access rights from the segment descriptor specified by
1298 the selector in source operand into the destination operand and sets the ZF
1299 flag. The destination operand can be a 16-bit or 32-bit general register.
1300 The source operand should be a 16-bit general register or memory.
1301
1302 lar ax,[bx] ; load access rights into word
1303 lar eax,dx ; load access rights into double word
1304
1305 "lsl" loads the segment limit from the segment descriptor specified by the
1306 selector in source operand into the destination operand and sets the ZF flag.
1307 Rules for operand are the same as for the "lar" instruction.
1308 "verr" and "verw" verify whether the code or data segment specified with
1309 the operand is readable or writable from the current privilege level. The
1310 operand should be a word, it can be general register or memory. If the segment
1311 is accessible and readable (for "verr") or writable (for "verw") the ZF flag
1312 is set, otherwise it's cleared. Rules for operand are the same as for the
1313 "lldt" instruction.
1314 "arpl" compares the RPL (requestor's privilege level) fields of two segment
1315 selectors. The first operand contains one segment selector and the second
1316 operand contains the other. If the RPL field of the destination operand is
1317 less than the RPL field of the source operand, the ZF flag is set and the RPL
1318 field of the destination operand is increased to match that of the source
1319 operand. Otherwise, the ZF flag is cleared and no change is made to the
1320 destination operand. The destination operand can be a word general register
1321 or memory, the source operand must be a general register.
1322
1323 arpl bx,ax ; adjust RPL of selector in register
1324 arpl [bx],ax ; adjust RPL of selector in memory
1325
1326 "clts" clears the TS (task switched) flag in the CR0 register. This
1327 instruction has no operands.
1328 "lock" prefix causes the processor's bus-lock signal to be asserted during
1329 execution of the accompanying instruction. In a multiprocessor environment,
1330 the bus-lock signal insures that the processor has exclusive use of any shared
1331 memory while the signal is asserted. The "lock" prefix can be prepended only
1332 to the following instructions and only to those forms of the instructions
1333 where the destination operand is a memory operand: "add", "adc", "and", "btc",
1334 "btr", "bts", "cmpxchg", "cmpxchg8b", "dec", "inc", "neg", "not", "or", "sbb",
1335 "sub", "xor", "xadd" and "xchg". If the "lock" prefix is used with one of
1336 these instructions and the source operand is a memory operand, an undefined
1337 opcode exception may be generated. An undefined opcode exception will also be
1338 generated if the "lock" prefix is used with any instruction not in the above
1339 list. The "xchg" instruction always asserts the bus-lock signal regardless of
1340 the presence or absence of the "lock" prefix.
1341 "hlt" stops instruction execution and places the processor in a halted
1342 state. An enabled interrupt, a debug exception, the BINIT, INIT or the RESET
1343 signal will resume execution. This instruction has no operands.
1344 "invlpg" invalidates (flushes) the TLB (translation lookaside buffer) entry
1345 specified with the operand, which should be a memory. The processor determines
1346 the page that contains that address and flushes the TLB entry for that page.
1347 "rdmsr" loads the contents of a 64-bit MSR (model specific register) of the
1348 address specified in the ECX register into registers EDX and EAX. "wrmsr"
1349 writes the contents of registers EDX and EAX into the 64-bit MSR of the
1350 address specified in the ECX register. "rdtsc" loads the current value of the
1351 processor's time stamp counter from the 64-bit MSR into the EDX and EAX
1352 registers. The processor increments the time stamp counter MSR every clock
1353 cycle and resets it to 0 whenever the processor is reset. "rdpmc" loads the
1354 contents of the 40-bit performance monitoring counter specified in the ECX
1355 register into registers EDX and EAX. These instructions have no operands.
1356 "wbinvd" writes back all modified cache lines in the processor's internal
1357 cache to main memory and invalidates (flushes) the internal caches. The
1358 instruction then issues a special function bus cycle that directs external
1359 caches to also write back modified data and another bus cycle to indicate that
1360 the external caches should be invalidated. This instruction has no operands.
1361 "rsm" return program control from the system management mode to the program
1362 that was interrupted when the processor received an SMM interrupt. This
1363 instruction has no operands.
1364 "sysenter" executes a fast call to a level 0 system procedure, "sysexit"
1365 executes a fast return to level 3 user code. The addresses used by these
1366 instructions are stored in MSRs. These instructions have no operands.
1367
1368
1369 2.1.13 FPU instructions
1370
1371 The FPU (Floating-Point Unit) instructions operate on the floating-point
1372 values in three formats: single precision (32-bit), double precision (64-bit)
1373 and double extended precision (80-bit). The FPU registers form the stack and
1374 each of them holds the double extended precision floating-point value. When
1375 some values are pushed onto the stack or are removed from the top, the FPU
1376 registers are shifted, so ST0 is always the value on the top of FPU stack, ST1
1377 is the first value below the top, etc. The ST0 name has also the synonym ST.
1378 "fld" pushes the floating-point value onto the FPU register stack. The
1379 operand can be 32-bit, 64-bit or 80-bit memory location or the FPU register,
1380 its value is then loaded onto the top of FPU register stack (the ST0
1381 register) and is automatically converted into the double extended precision
1382 format.
1383
1384 fld dword [bx] ; load single prevision value from memory
1385 fld st2 ; push value of st2 onto register stack
1386
1387 "fld1", "fldz", "fldl2t", "fldl2e", "fldpi", "fldlg2" and "fldln2" load the
1388 commonly used contants onto the FPU register stack. The loaded constants are
1389 +1.0, +0.0, lb 10, lb e, pi, lg 2 and ln 2 respectively. These instructions
1390 have no operands.
1391 "fild" converts the signed integer source operand into double extended
1392 precision floating-point format and pushes the result onto the FPU register
1393 stack. The source operand can be a 16-bit, 32-bit or 64-bit memory location.
1394
1395 fild qword [bx] ; load 64-bit integer from memory
1396
1397 "fst" copies the value of ST0 register to the destination operand, which
1398 can be 32-bit or 64-bit memory location or another FPU register. "fstp"
1399 performs the same operation as "fst" and then pops the register stack,
1400 getting rid of ST0. "fstp" accepts the same operands as the "fst" instruction
1401 and can also store value in the 80-bit memory.
1402
1403 fst st3 ; copy value of st0 into st3 register
1404 fstp tword [bx] ; store value in memory and pop stack
1405
1406 "fist" converts the value in ST0 to a signed integer and stores the result
1407 in the destination operand. The operand can be 16-bit or 32-bit memory
1408 location. "fistp" performs the same operation and then pops the register
1409 stack, it accepts the same operands as the "fist" instruction and can also
1410 store integer value in the 64-bit memory, so it has the same rules for
1411 operands as "fild" instruction.
1412 "fbld" converts the packed BCD integer into double extended precision
1413 floating-point format and pushes this value onto the FPU stack. "fbstp"
1414 converts the value in ST0 to an 18-digit packed BCD integer, stores the result
1415 in the destination operand, and pops the register stack. The operand should be
1416 an 80-bit memory location.
1417 "fadd" adds the destination and source operand and stores the sum in the
1418 destination location. The destination operand is always an FPU register, if
1419 the source is a memory location, the destination is ST0 register and only
1420 source operand should be specified. If both operands are FPU registers, at
1421 least one of them should be ST0 register. An operand in memory can be a
1422 32-bit or 64-bit value.
1423
1424 fadd qword [bx] ; add double precision value to st0
1425 fadd st2,st0 ; add st0 to st2
1426
1427 "faddp" adds the destination and source operand, stores the sum in the
1428 destination location and then pops the register stack. The destination operand
1429 must be an FPU register and the source operand must be the ST0. When no
1430 operands are specified, ST1 is used as a destination operand.
1431
1432 faddp ; add st0 to st1 and pop the stack
1433 faddp st2,st0 ; add st0 to st2 and pop the stack
1434
1435 "fiadd" instruction converts an integer source operand into double extended
1436 precision floating-point value and adds it to the destination operand. The
1437 operand should be a 16-bit or 32-bit memory location.
1438
1439 fiadd word [bx] ; add word integer to st0
1440
1441 "fsub", "fsubr", "fmul", "fdiv", "fdivr" instruction are similar to "fadd",
1442 have the same rules for operands and differ only in the perfomed computation.
1443 "fsub" substracts the source operand from the destination operand, "fsubr"
1444 substract the destination operand from the source operand, "fmul" multiplies
1445 the destination and source operands, "fdiv" divides the destination operand by
1446 the source operand and "fdivr" divides the source operand by the destination
1447 operand. "fsubp", "fsubrp", "fmulp", "fdivp", "fdivrp" perform the same
1448 operations and pop the register stack, the rules for operand are the same as
1449 for the "faddp" instruction. "fisub", "fisubr", "fimul", "fidiv", "fidivr"
1450 perform these operations after converting the integer source operand into
1451 floating-point value, they have the same rules for operands as "fiadd"
1452 instruction.
1453 "fsqrt" computes the square root of the value in ST0 register, "fsin"
1454 computes the sine of that value, "fcos" computes the cosine of that value,
1455 "fchs" complements its sign bit, "fabs" clears its sign to create the absolute
1456 value, "frndint" rounds it to the nearest integral value, depending on the
1457 current rounding mode. "f2xm1" computes the exponential value of 2 to the
1458 power of ST0 and substracts the 1.0 from it, the value of ST0 must lie in the
1459 range -1.0 to +1.0. All these instructions store the result in ST0 and have no
1460 operands.
1461 "fsincos" computes both the sine and the cosine of the value in ST0
1462 register, stores the sine in ST0 and pushes the cosine on the top of FPU
1463 register stack. "fptan" computes the tangent of the value in ST0, stores the
1464 result in ST0 and pushes a 1.0 onto the FPU register stack. "fpatan" computes
1465 the arctangent of the value in ST1 divided by the value in ST0, stores the
1466 result in ST1 and pops the FPU register stack. "fyl2x" computes the binary
1467 logarithm of ST0, multiplies it by ST1, stores the result in ST1 and pops the
1468 FPU register stack; "fyl2xp1" performs the same operation but it adds 1.0 to
1469 ST0 before computing the logarithm. "fprem" computes the remainder obtained
1470 from dividing the value in ST0 by the value in ST1, and stores the result
1471 in ST0. "fprem1" performs the same operation as "fprem", but it computes the
1472 remainder in the way specified by IEEE Standard 754. "fscale" truncates the
1473 value in ST1 and increases the exponent of ST0 by this value. "fxtract"
1474 separates the value in ST0 into its exponent and significand, stores the
1475 exponent in ST0 and pushes the significand onto the register stack. "fnop"
1476 performs no operation. These instructions have no operands.
1477 "fxch" exchanges the contents of ST0 an another FPU register. The operand
1478 should be an FPU register, if no operand is specified, the contents of ST0 and
1479 ST1 are exchanged.
1480 "fcom" and "fcomp" compare the contents of ST0 and the source operand and
1481 set flags in the FPU status word according to the results. "fcomp"
1482 additionally pops the register stack after performing the comparison. The
1483 operand can be a single or double precision value in memory or the FPU
1484 register. When no operand is specified, ST1 is used as a source operand.
1485
1486 fcom ; compare st0 with st1
1487 fcomp st2 ; compare st0 with st2 and pop stack
1488
1489 "fcompp" compares the contents of ST0 and ST1, sets flags in the FPU status
1490 word according to the results and pops the register stack twice. This
1491 instruction has no operands.
1492 "fucom", "fucomp" and "fucompp" performs an unordered comparison of two FPU
1493 registers. Rules for operands are the same as for the "fcom", "fcomp" and
1494 "fcompp", but the source operand must be an FPU register.
1495 "ficom" and "ficomp" compare the value in ST0 with an integer source operand
1496 and set the flags in the FPU status word according to the results. "ficomp"
1497 additionally pops the register stack after performing the comparison. The
1498 integer value is converted to double extended precision floating-point format
1499 before the comparison is made. The operand should be a 16-bit or 32-bit
1500 memory location.
1501
1502 ficom word [bx] ; compare st0 with 16-bit integer
1503
1504 "fcomi", "fcomip", "fucomi", "fucomip" perform the comparison of ST0 with
1505 another FPU register and set the ZF, PF and CF flags according to the results.
1506 "fcomip" and "fucomip" additionaly pop the register stack after performing the
1507 comparison. The instructions obtained by attaching the FPU condition mnemonic
1508 (see table 2.2) to the "fcmov" mnemonic transfer the specified FPU register
1509 into ST0 register if the given test condition is true. These instructions
1510 allow two different syntaxes, one with single operand specifying the source
1511 FPU register, and one with two operands, in that case destination operand
1512 should be ST0 register and the second operand specifies the source FPU
1513 register.
1514
1515 fcomi st2 ; compare st0 with st2 and set flags
1516 fcmovb st0,st2 ; transfer st2 to st0 if below
1517
1518 Table 2.2 FPU conditions
1519 /------------------------------------------------------\
1520 | Mnemonic | Condition tested | Description |
1521 |==========|==================|========================|
1522 | b | CF = 1 | below |
1523 | e | ZF = 1 | equal |
1524 | be | CF or ZF = 1 | below or equal |
1525 | u | PF = 1 | unordered |
1526 | nb | CF = 0 | not below |
1527 | ne | ZF = 0 | not equal |
1528 | nbe | CF and ZF = 0 | not below nor equal |
1529 | nu | PF = 0 | not unordered |
1530 \------------------------------------------------------/
1531
1532 "ftst" compares the value in ST0 with 0.0 and sets the flags in the FPU
1533 status word according to the results. "fxam" examines the contents of the ST0
1534 and sets the flags in FPU status word to indicate the class of value in the
1535 register. These instructions have no operands.
1536 "fstsw" and "fnstsw" store the current value of the FPU status word in the
1537 destination location. The destination operand can be either a 16-bit memory or
1538 the AX register. "fstsw" checks for pending unmasked FPU exceptions before
1539 storing the status word, "fnstsw" does not.
1540 "fstcw" and "fnstcw" store the current value of the FPU control word at the
1541 specified destination in memory. "fstcw" checks for pending umasked FPU
1542 exceptions before storing the control word, "fnstcw" does not. "fldcw" loads
1543 the operand into the FPU control word. The operand should be a 16-bit memory
1544 location.
1545 "fstenv" and "fnstenv" store the current FPU operating environment at the
1546 memory location specified with the destination operand, and then mask all FPU
1547 exceptions. "fstenv" checks for pending umasked FPU exceptions before
1548 proceeding, "fnstenv" does not. "fldenv" loads the complete operating
1549 environment from memory into the FPU. "fsave" and "fnsave" store the current
1550 FPU state (operating environment and register stack) at the specified
1551 destination in memory and reinitializes the FPU. "fsave" check for pending
1552 unmasked FPU exceptions before proceeding, "fnsave" does not. "frstor"
1553 loads the FPU state from the specified memory location. All these instructions
1554 need an operand being a memory location. For each of these instructions
1555 exist two additional mnemonics that allow to precisely select the type of the
1556 operation. The "fstenvw", "fnstenvw", "fldenvw", "fsavew", "fnsavew" and
1557 "frstorw" mnemonics force the instruction to perform operation as in the 16-bit
1558 mode, while "fstenvd", "fnstenvd", "fldenvd", "fsaved", "fnsaved" and "frstord"
1559 force the operation as in 32-bit mode.
1560 "finit" and "fninit" set the FPU operating environment into its default
1561 state. "finit" checks for pending unmasked FPU exception before proceeding,
1562 "fninit" does not. "fclex" and "fnclex" clear the FPU exception flags in the
1563 FPU status word. "fclex" checks for pending unmasked FPU exception before
1564 proceeding, "fnclex" does not. "wait" and "fwait" are synonyms for the same
1565 instruction, which causes the processor to check for pending unmasked FPU
1566 exceptions and handle them before proceeding. These instructions have no
1567 operands.
1568 "ffree" sets the tag associated with specified FPU register to empty. The
1569 operand should be an FPU register.
1570 "fincstp" and "fdecstp" rotate the FPU stack by one by adding or
1571 substracting one to the pointer of the top of stack. These instructions have no
1572 operands.
1573
1574
1575 2.1.14 MMX instructions
1576
1577 The MMX instructions operate on the packed integer types and use the MMX
1578 registers, which are the low 64-bit parts of the 80-bit FPU registers. Because
1579 of this MMX instructions cannot be used at the same time as FPU instructions.
1580 They can operate on packed bytes (eight 8-bit integers), packed words (four
1581 16-bit integers) or packed double words (two 32-bit integers), use of packed
1582 formats allows to perform operations on multiple data at one time.
1583 "movq" copies a quad word from the source operand to the destination
1584 operand. At least one of the operands must be a MMX register, the second one
1585 can be also a MMX register or 64-bit memory location.
1586
1587 movq mm0,mm1 ; move quad word from register to register
1588 movq mm2,[ebx] ; move quad word from memory to register
1589
1590 "movd" copies a double word from the source operand to the destination
1591 operand. One of the operands must be a MMX register, the second one can be a
1592 general register or 32-bit memory location. Only low double word of MMX
1593 register is used.
1594 All general MMX operations have two operands, the destination operand should
1595 be a MMX register, the source operand can be a MMX register or 64-bit memory
1596 location. Operation is performed on the corresponding data elements of the
1597 source and destination operand and stored in the data elements of the
1598 destination operand. "paddb", "paddw" and "paddd" perform the addition of
1599 packed bytes, packed words, or packed double words. "psubb", "psubw" and
1600 "psubd" perform the substraction of appropriate types. "paddsb", "paddsw",
1601 "psubsb" and "psubsw" perform the addition or substraction of packed bytes
1602 or packed words with the signed saturation. "paddusb", "paddusw", "psubusb",
1603 "psubusw" are analoguous, but with unsigned saturation. "pmulhw" and "pmullw"
1604 performs a signed multiplication of the packed words and store the high or low
1605 words of the results in the destination operand. "pmaddwd" performs a multiply
1606 of the packed words and adds the four intermediate double word products in
1607 pairs to produce result as a packed double words. "pand", "por" and "pxor"
1608 perform the logical operations on the quad words, "pandn" peforms also a
1609 logical negation of the destination operand before performing the "and"
1610 operation. "pcmpeqb", "pcmpeqw" and "pcmpeqd" compare for equality of packed
1611 bytes, packed words or packed double words. If a pair of data elements is
1612 equal, the corresponding data element in the destination operand is filled with
1613 bits of value 1, otherwise it's set to 0. "pcmpgtb", "pcmpgtw" and "pcmpgtd"
1614 perform the similar operation, but they check whether the data elements in the
1615 destination operand are greater than the correspoding data elements in the
1616 source operand. "packsswb" converts packed signed words into packed signed
1617 bytes, "packssdw" converts packed signed double words into packed signed
1618 words, using saturation to handle overflow conditions. "packuswb" converts
1619 packed signed words into packed unsigned bytes. Converted data elements from
1620 the source operand are stored in the low part of the destination operand,
1621 while converted data elements from the destination operand are stored in the
1622 high part. "punpckhbw", "punpckhwd" and "punpckhdq" interleaves the data
1623 elements from the high parts of the source and destination operands and
1624 stores the result into the destination operand. "punpcklbw", "punpcklwd" and
1625 "punpckldq" perform the same operation, but the low parts of the source and
1626 destination operand are used.
1627
1628 paddsb mm0,[esi] ; add packed bytes with signed saturation
1629 pcmpeqw mm3,mm7 ; compare packed words for equality
1630
1631 "psllw", "pslld" and "psllq" perform logical shift left of the packed words,
1632 packed double words or a single quad word in the destination operand by the
1633 amount specified in the source operand. "psrlw", "psrld" and "psrlq" perform
1634 logical shift right of the packed words, packed double words or a single quad
1635 word. "psraw" and "psrad" perform arithmetic shift of the packed words or
1636 double words. The destination operand should be a MMX register, while source
1637 operand can be a MMX register, 64-bit memory location, or 8-bit immediate
1638 value.
1639
1640 psllw mm2,mm4 ; shift words left logically
1641 psrad mm4,[ebx] ; shift double words right arithmetically
1642
1643 "emms" makes the FPU registers usable for the FPU instructions, it must be
1644 used before using the FPU instructions if any MMX instructions were used.
1645
1646
1647 2.1.15 SSE instructions
1648
1649 The SSE extension adds more MMX instructions and also introduces the
1650 operations on packed single precision floating point values. The 128-bit
1651 packed single precision format consists of four single precision floating
1652 point values. The 128-bit SSE registers are designed for the purpose of
1653 operations on this data type.
1654 "movaps" and "movups" transfer a double quad word operand containing packed
1655 single precision values from source operand to destination operand. At least
1656 one of the operands have to be a SSE register, the second one can be also a
1657 SSE register or 128-bit memory location. Memory operands for "movaps"
1658 instruction must be aligned on boundary of 16 bytes, operands for "movups"
1659 instruction don't have to be aligned.
1660
1661 movups xmm0,[ebx] ; move unaligned double quad word
1662
1663 "movlps" moves packed two single precision values between the memory and the
1664 low quad word of SSE register. "movhps" moved packed two single precision
1665 values between the memory and the high quad word of SSE register. One of the
1666 operands must be a SSE register, and the other operand must be a 64-bit memory
1667 location.
1668
1669 movlps xmm0,[ebx] ; move memory to low quad word of xmm0
1670 movhps [esi],xmm7 ; move high quad word of xmm7 to memory
1671
1672 "movlhps" moves packed two single precision values from the low quad word
1673 of source register to the high quad word of destination register. "movhlps"
1674 moves two packed single precision values from the high quad word of source
1675 register to the low quad word of destination register. Both operands have to
1676 be a SSE registers.
1677 "movmskps" transfers the most significant bit of each of the four single
1678 precision values in the SSE register into low four bits of a general register.
1679 The source operand must be a SSE register, the destination operand must be a
1680 general register.
1681 "movss" transfers a single precision value between source and destination
1682 operand (only the low double word is trasferred). At least one of the operands
1683 have to be a SSE register, the second one can be also a SSE register or 32-bit
1684 memory location.
1685
1686 movss [edi],xmm3 ; move low double word of xmm3 to memory
1687
1688 Each of the SSE arithmetic operations has two variants. When the mnemonic
1689 ends with "ps", the source operand can be a 128-bit memory location or a SSE
1690 register, the destination operand must be a SSE register and the operation is
1691 performed on packed four single precision values, for each pair of the
1692 corresponding data elements separately, the result is stored in the
1693 destination register. When the mnemonic ends with "ss", the source operand
1694 can be a 32-bit memory location or a SSE register, the destination operand
1695 must be a SSE register and the operation is performed on single precision
1696 values, only low double words of SSE registers are used in this case, the
1697 result is stored in the low double word of destination register. "addps" and
1698 "addss" add the values, "subps" and "subss" substract the source value from
1699 destination value, "mulps" and "mulss" multiply the values, "divps" and
1700 "divss" divide the destination value by the source value, "rcpps" and "rcpss"
1701 compute the approximate reciprocal of the source value, "sqrtps" and "sqrtss"
1702 compute the square root of the source value, "rsqrtps" and "rsqrtss" compute
1703 the approximate reciprocal of square root of the source value, "maxps" and
1704 "maxss" compare the source and destination values and return the greater one,
1705 "minps" and "minss" compare the source and destination values and return the
1706 lesser one.
1707
1708 mulss xmm0,[ebx] ; multiply single precision values
1709 addps xmm3,xmm7 ; add packed single precision values
1710
1711 "andps", "andnps", "orps" and "xorps" perform the logical operations on
1712 packed single precision values. The source operand can be a 128-bit memory
1713 location or a SSE register, the destination operand must be a SSE register.
1714 "cmpps" compares packed single precision values and returns a mask result
1715 into the destination operand, which must be a SSE register. The source operand
1716 can be a 128-bit memory location or SSE register, the third operand must be an
1717 immediate operand selecting code of one of the eight compare conditions
1718 (table 2.3). "cmpss" performs the same operation on single precision values,
1719 only low double word of destination register is affected, in this case source
1720 operand can be a 32-bit memory location or SSE register. These two
1721 instructions have also variants with only two operands and the condition
1722 encoded within mnemonic. Their mnemonics are obtained by attaching the
1723 mnemonic from table 2.3 to the "cmp" mnemonic and then attaching the "ps" or
1724 "ss" at the end.
1725
1726 cmpps xmm2,xmm4,0 ; compare packed single precision values
1727 cmpltss xmm0,[ebx] ; compare single precision values
1728
1729 Table 2.3 SSE conditions
1730 /-------------------------------------------\
1731 | Code | Mnemonic | Description |
1732 |======|==========|=========================|
1733 | 0 | eq | equal |
1734 | 1 | lt | less than |
1735 | 2 | le | less than or equal |
1736 | 3 | unord | unordered |
1737 | 4 | neq | not equal |
1738 | 5 | nlt | not less than |
1739 | 6 | nle | not less than nor equal |
1740 | 7 | ord | ordered |
1741 \-------------------------------------------/
1742
1743 "comiss" and "ucomiss" compare the single precision values and set the ZF,
1744 PF and CF flags to show the result. The destination operand must be a SSE
1745 register, the source operand can be a 32-bit memory location or SSE register.
1746 "shufps" moves any two of the four single precision values from the
1747 destination operand into the low quad word of the destination operand, and any
1748 two of the four values from the source operand into the high quad word of the
1749 destination operand. The destination operand must be a SSE register, the
1750 source operand can be a 128-bit memory location or SSE register, the third
1751 operand must be an 8-bit immediate value selecting which values will be moved
1752 into the destination operand. Bits 0 and 1 select the value to be moved from
1753 destination operand to the low double word of the result, bits 2 and 3 select
1754 the value to be moved from the destination operand to the second double word,
1755 bits 4 and 5 select the value to be moved from the source operand to the third
1756 double word, and bits 6 and 7 select the value to be moved from the source
1757 operand to the high double word of the result.
1758
1759 shufps xmm0,xmm0,10010011b ; shuffle double words
1760
1761 "unpckhps" performs an interleaved unpack of the values from the high parts
1762 of the source and destination operands and stores the result in the
1763 destination operand, which must be a SSE register. The source operand can be
1764 a 128-bit memory location or a SSE register. "unpcklps" performs an
1765 interleaved unpack of the values from the low parts of the source and
1766 destination operand and stores the result in the destination operand,
1767 the rules for operands are the same.
1768 "cvtpi2ps" converts packed two double word integers into the the packed two
1769 single precision floating point values and stores the result in the low quad
1770 word of the destination operand, which should be a SSE register. The source
1771 operand can be a 64-bit memory location or MMX register.
1772
1773 cvtpi2ps xmm0,mm0 ; convert integers to single precision values
1774
1775 "cvtsi2ss" converts a double word integer into a single precision floating
1776 point value and stores the result in the low double word of the destination
1777 operand, which should be a SSE register. The source operand can be a 32-bit
1778 memory location or 32-bit general register.
1779
1780 cvtsi2ss xmm0,eax ; convert integer to single precision value
1781
1782 "cvtps2pi" converts packed two single precision floating point values into
1783 packed two double word integers and stores the result in the destination
1784 operand, which should be a MMX register. The source operand can be a 64-bit
1785 memory location or SSE register, only low quad word of SSE register is used.
1786 "cvttps2pi" performs the similar operation, except that truncation is used to
1787 round a source values to integers, rules for the operands are the same.
1788
1789 cvtps2pi mm0,xmm0 ; convert single precision values to integers
1790
1791 "cvtss2si" convert a single precision floating point value into a double
1792 word integer and stores the result in the destination operand, which should be
1793 a 32-bit general register. The source operand can be a 32-bit memory location
1794 or SSE register, only low double word of SSE register is used. "cvttss2si"
1795 performs the similar operation, except that truncation is used to round a
1796 source value to integer, rules for the operands are the same.
1797
1798 cvtss2si eax,xmm0 ; convert single precision value to integer
1799
1800 "pextrw" copies the word in the source operand specified by the third
1801 operand to the destination operand. The source operand must be a MMX register,
1802 the destination operand must be a 32-bit general register (the high word of
1803 the destination is cleared), the third operand must an 8-bit immediate value.
1804
1805 pextrw eax,mm0,1 ; extract word into eax
1806
1807 "pinsrw" inserts a word from the source operand in the destination operand
1808 at the location specified with the third operand, which must be an 8-bit
1809 immediate value. The destination operand must be a MMX register, the source
1810 operand can be a 16-bit memory location or 32-bit general register (only low
1811 word of the register is used).
1812
1813 pinsrw mm1,ebx,2 ; insert word from ebx
1814
1815 "pavgb" and "pavgw" compute average of packed bytes or words. "pmaxub"
1816 return the maximum values of packed unsigned bytes, "pminub" returns the
1817 minimum values of packed unsigned bytes, "pmaxsw" returns the maximum values
1818 of packed signed words, "pminsw" returns the minimum values of packed signed
1819 words. "pmulhuw" performs a unsigned multiplication of the packed words and
1820 stores the high words of the results in the destination operand. "psadbw"
1821 computes the absolute differences of packed unsigned bytes, sums the
1822 differences, and stores the sum in the low word of destination operand. All
1823 these instructions follow the same rules for operands as the general MMX
1824 operations described in previous section.
1825 "pmovmskb" creates a mask made of the most significant bit of each byte in
1826 the source operand and stores the result in the low byte of destination
1827 operand. The source operand must be a MMX register, the destination operand
1828 must a 32-bit general register.
1829 "pshufw" inserts words from the source operand in the destination operand
1830 from the locations specified with the third operand. The destination operand
1831 must be a MMX register, the source operand can be a 64-bit memory location or
1832 MMX register, third operand must an 8-bit immediate value selecting which
1833 values will be moved into destination operand, in the similar way as the third
1834 operand of the "shufps" instruction.
1835 "movntq" moves the quad word from the source operand to memory using a
1836 non-temporal hint to minimize cache pollution. The source operand should be a
1837 MMX register, the destination operand should be a 64-bit memory location.
1838 "movntps" stores packed single precision values from the SSE register to
1839 memory using a non-temporal hint. The source operand should be a SSE register,
1840 the destination operand should be a 128-bit memory location. "maskmovq" stores
1841 selected bytes from the first operand into a 64-bit memory location using a
1842 non-temporal hint. Both operands should be a MMX registers, the second operand
1843 selects wich bytes from the source operand are written to memory. The
1844 memory location is pointed by DI (or EDI) register in the segment selected
1845 by DS.
1846 "prefetcht0", "prefetcht1", "prefetcht2" and "prefetchnta" fetch the line
1847 of data from memory that contains byte specified with the operand to a
1848 specified location in hierarchy. The operand should be an 8-bit memory
1849 location.
1850 "sfence" performs a serializing operation on all instruction storing to
1851 memory that were issued prior to it. This instruction has no operands.
1852 "ldmxcsr" loads the 32-bit memory operand into the MXCSR register. "stmxcsr"
1853 stores the contents of MXCSR into a 32-bit memory operand.
1854 "fxsave" saves the current state of the FPU, MXCSR register, and all the FPU
1855 and SSE registers to a 512-byte memory location specified in the destination
1856 operand. "fxrstor" reloads data previously stored with "fxsave" instruction
1857 from the specified 512-byte memory location. The memory operand for both those
1858 instructions must be aligned on 16 byte boundary, it should declare operand
1859 of no specified size.
1860
1861
1862 2.1.16 SSE2 instructions
1863
1864 The SSE2 extension introduces the operations on packed double precision
1865 floating point values, extends the syntax of MMX instructions, and adds also
1866 some new instructions.
1867 "movapd" and "movupd" transfer a double quad word operand containing packed
1868 double precision values from source operand to destination operand. These
1869 instructions are analogous to "movaps" and "movups" and have the same rules
1870 for operands.
1871 "movlpd" moves double precision value between the memory and the low quad
1872 word of SSE register. "movhpd" moved double precision value between the memory
1873 and the high quad word of SSE register. These instructions are analogous to
1874 "movlps" and "movhps" and have the same rules for operands.
1875 "movmskpd" transfers the most significant bit of each of the two double
1876 precision values in the SSE register into low two bits of a general register.
1877 This instruction is analogous to "movmskps" and has the same rules for
1878 operands.
1879 "movsd" transfers a double precision value between source and destination
1880 operand (only the low quad word is trasferred). At least one of the operands
1881 have to be a SSE register, the second one can be also a SSE register or 64-bit
1882 memory location.
1883 Arithmetic operations on double precision values are: "addpd", "addsd",
1884 "subpd", "subsd", "mulpd", "mulsd", "divpd", "divsd", "sqrtpd", "sqrtsd",
1885 "maxpd", "maxsd", "minpd", "minsd", and they are analoguous to arithmetic
1886 operations on single precision values described in previous section. When the
1887 mnemonic ends with "pd" instead of "ps", the operation is performed on packed
1888 two double precision values, but rules for operands are the same. When the
1889 mnemonic ends with "sd" instead of "ss", the source operand can be a 64-bit
1890 memory location or a SSE register, the destination operand must be a SSE
1891 register and the operation is performed on double precision values, only low
1892 quad words of SSE registers are used in this case.
1893 "andpd", "andnpd", "orpd" and "xorpd" perform the logical operations on
1894 packed double precision values. They are analoguous to SSE logical operations
1895 on single prevision values and have the same rules for operands.
1896 "cmppd" compares packed double precision values and returns and returns a
1897 mask result into the destination operand. This instruction is analoguous to
1898 "cmpps" and has the same rules for operands. "cmpsd" performs the same
1899 operation on double precision values, only low quad word of destination
1900 register is affected, in this case source operand can be a 64-bit memory or
1901 SSE register. Variant with only two operands are obtained by attaching the
1902 condition mnemonic from table 2.3 to the "cmp" mnemonic and then attaching
1903 the "pd" or "sd" at the end.
1904 "comisd" and "ucomisd" compare the double precision values and set the ZF,
1905 PF and CF flags to show the result. The destination operand must be a SSE
1906 register, the source operand can be a 128-bit memory location or SSE register.
1907 "shufpd" moves any of the two double precision values from the destination
1908 operand into the low quad word of the destination operand, and any of the two
1909 values from the source operand into the high quad word of the destination
1910 operand. This instruction is analoguous to "shufps" and has the same rules for
1911 operand. Bit 0 of the third operand selects the value to be moved from the
1912 destination operand, bit 1 selects the value to be moved from the source
1913 operand, the rest of bits are reserved and must be zeroed.
1914 "unpckhpd" performs an unpack of the high quad words from the source and
1915 destination operands, "unpcklpd" performs an unpack of the low quad words from
1916 the source and destination operands. They are analoguous to "unpckhps" and
1917 "unpcklps", and have the same rules for operands.
1918 "cvtps2pd" converts the packed two single precision floating point values to
1919 two packed double precision floating point values, the destination operand
1920 must be a SSE register, the source operand can be a 64-bit memory location or
1921 SSE register. "cvtpd2ps" converts the packed two double precision floating
1922 point values to packed two single precision floating point values, the
1923 destination operand must be a SSE register, the source operand can be a
1924 128-bit memory location or SSE register. "cvtss2sd" converts the single
1925 precision floating point value to double precision floating point value, the
1926 destination operand must be a SSE register, the source operand can be a 32-bit
1927 memory location or SSE register. "cvtsd2ss" converts the double precision
1928 floating point value to single precision floating point value, the destination
1929 operand must be a SSE register, the source operand can be 64-bit memory
1930 location or SSE register.
1931 "cvtpi2pd" converts packed two double word integers into the the packed
1932 double precision floating point values, the destination operand must be a SSE
1933 register, the source operand can be a 64-bit memory location or MMX register.
1934 "cvtsi2sd" converts a double word integer into a double precision floating
1935 point value, the destination operand must be a SSE register, the source
1936 operand can be a 32-bit memory location or 32-bit general register. "cvtpd2pi"
1937 converts packed double precision floating point values into packed two double
1938 word integers, the destination operand should be a MMX register, the source
1939 operand can be a 128-bit memory location or SSE register. "cvttpd2pi" performs
1940 the similar operation, except that truncation is used to round a source values
1941 to integers, rules for operands are the same. "cvtsd2si" converts a double
1942 precision floating point value into a double word integer, the destination
1943 operand should be a 32-bit general register, the source operand can be a
1944 64-bit memory location or SSE register. "cvttsd2si" performs the similar
1945 operation, except that truncation is used to round a source value to integer,
1946 rules for operands are the same.
1947 "cvtps2dq" and "cvttps2dq" convert packed single precision floating point
1948 values to packed four double word integers, storing them in the destination
1949 operand. "cvtpd2dq" and "cvttpd2dq" convert packed double precision floating
1950 point values to packed two double word integers, storing the result in the low
1951 quad word of the destination operand. "cvtdq2ps" converts packed four
1952 double word integers to packed single precision floating point values.
1953 For all these instructions destination operand must be a SSE register, the
1954 source operand can be a 128-bit memory location or SSE register.
1955 "cvtdq2pd" converts packed two double word integers from the source operand to
1956 packed double precision floating point values, the source can be a 64-bit
1957 memory location or SSE register, destination has to be SSE register.
1958 "movdqa" and "movdqu" transfer a double quad word operand containing packed
1959 integers from source operand to destination operand. At least one of the
1960 operands have to be a SSE register, the second one can be also a SSE register
1961 or 128-bit memory location. Memory operands for "movdqa" instruction must be
1962 aligned on boundary of 16 bytes, operands for "movdqu" instruction don't have
1963 to be aligned.
1964 "movq2dq" moves the contents of the MMX source register to the low quad word
1965 of destination SSE register. "movdq2q" moves the low quad word from the source
1966 SSE register to the destination MMX register.
1967
1968 movq2dq xmm0,mm1 ; move from MMX register to SSE register
1969 movdq2q mm0,xmm1 ; move from SSE register to MMX register
1970
1971 All MMX instructions operating on the 64-bit packed integers (those with
1972 mnemonics starting with "p") are extended to operate on 128-bit packed
1973 integers located in SSE registers. Additional syntax for these instructions
1974 needs an SSE register where MMX register was needed, and the 128-bit memory
1975 location or SSE register where 64-bit memory location or MMX register were
1976 needed. The exception is "pshufw" instruction, which doesn't allow extended
1977 syntax, but has two new variants: "pshufhw" and "pshuflw", which allow only
1978 the extended syntax, and perform the same operation as "pshufw" on the high
1979 or low quad words of operands respectively. Also the new instruction "pshufd"
1980 is introduced, which performs the same operation as "pshufw", but on the
1981 double words instead of words, it allows only the extended syntax.
1982
1983 psubb xmm0,[esi] ; substract 16 packed bytes
1984 pextrw eax,xmm0,7 ; extract highest word into eax
1985
1986 "paddq" performs the addition of packed quad words, "psubq" performs the
1987 substraction of packed quad words, "pmuludq" performs an unsigned
1988 multiplication of low double words from each corresponding quad words and
1989 returns the results in packed quad words. These instructions follow the same
1990 rules for operands as the general MMX operations described in 2.1.14.
1991 "pslldq" and "psrldq" perform logical shift left or right of the double
1992 quad word in the destination operand by the amount of bytes specified in the
1993 source operand. The destination operand should be a SSE register, source
1994 operand should be an 8-bit immediate value.
1995 "punpckhqdq" interleaves the high quad word of the source operand and the
1996 high quad word of the destination operand and writes them to the destination
1997 SSE register. "punpcklqdq" interleaves the low quad word of the source operand
1998 and the low quad word of the destination operand and writes them to the
1999 destination SSE register. The source operand can be a 128-bit memory location
2000 or SSE register.
2001 "movntdq" stores packed integer data from the SSE register to memory using
2002 non-temporal hint. The source operand should be a SSE register, the
2003 destination operand should be a 128-bit memory location. "movntpd" stores
2004 packed double precision values from the SSE register to memory using a
2005 non-temporal hint. Rules for operand are the same. "movnti" stores integer
2006 from a general register to memory using a non-temporal hint. The source
2007 operand should be a 32-bit general register, the destination operand should
2008 be a 32-bit memory location. "maskmovdqu" stores selected bytes from the first
2009 operand into a 128-bit memory location using a non-temporal hint. Both
2010 operands should be a SSE registers, the second operand selects wich bytes from
2011 the source operand are written to memory. The memory location is pointed by DI
2012 (or EDI) register in the segment selected by DS and does not need to be
2013 aligned.
2014 "clflush" writes and invalidates the cache line associated with the address
2015 of byte specified with the operand, which should be a 8-bit memory location.
2016 "lfence" performs a serializing operation on all instruction loading from
2017 memory that were issued prior to it. "mfence" performs a serializing operation
2018 on all instruction accesing memory that were issued prior to it, and so it
2019 combines the functions of "sfence" (described in previous section) and
2020 "lfence" instructions. These instructions have no operands.
2021
2022
2023 2.1.17 SSE3 instructions
2024
2025 Prescott technology introduced some new instructions to improve the performance
2026 of SSE and SSE2 - this extension is called SSE3.
2027 "fisttp" behaves like the "fistp" instruction and accepts the same operands,
2028 the only difference is that it always used truncation, irrespective of the
2029 rounding mode.
2030 "movshdup" loads into destination operand the 128-bit value obtained from
2031 the source value of the same size by filling the each quad word with the two
2032 duplicates of the value in its high double word. "movsldup" performs the same
2033 action, except it duplicates the values of low double words. The destination
2034 operand should be SSE register, the source operand can be SSE register or
2035 128-bit memory location.
2036 "movddup" loads the 64-bit source value and duplicates it into high and low
2037 quad word of the destination operand. The destination operand should be SSE
2038 register, the source operand can be SSE register or 64-bit memory location.
2039 "lddqu" is functionally equivalent to "movdqu" with memory as source
2040 operand, but it may improve performance when the source operand crosses a
2041 cacheline boundary. The destination operand has to be SSE register, the source
2042 operand must be 128-bit memory location.
2043 "addsubps" performs single precision addition of second and fourth pairs and
2044 single precision substracion of the first and third pairs of floating point
2045 values in the operands. "addsubpd" performs double precision addition of the
2046 second pair and double precision substraction of the first pair of floating
2047 point values in the operand. "haddps" performs the addition of two single
2048 precision values within the each quad word of source and destination operands,
2049 and stores the results of such horizontal addition of values from destination
2050 operand into low quad word of destination operand, and the results from the
2051 source operand into high quad word of destination operand. "haddpd" performs
2052 the addition of two double precision values within each operand, and stores
2053 the result from destination operand into low quad word of destination operand,
2054 and the result from source operand into high quad word of destination operand.
2055 All these instructions need the destination operand to be SSE register, source
2056 operand can be SSE register or 128-bit memory location.
2057 "monitor" sets up an address range for monitoring of write-back stores. It
2058 need its three operands to be EAX, ECX and EDX register in that order. "mwait"
2059 waits for a write-back store to the address range set up by the "monitor"
2060 instruction. It uses two operands with additional parameters, first being the
2061 EAX and second the ECX register.
2062 The functionality of SSE3 is further extended by the set of Supplemental
2063 SSE3 instructions (SSSE3). They generally follow the same rules for operands
2064 as all the MMX operations extended by SSE.
2065 "phaddw" and "phaddd" perform the horizontal additional of the pairs of
2066 adjacent values from both the source and destination operand, and stores the
2067 sums into the destination (sums from the source operand go into lower part of
2068 destination register). They operate on 16-bit or 32-bit chunks, respectively.
2069 "phaddsw" performs the same operation on signed 16-bit packed values, but the
2070 result of each addition is saturated. "phsubw" and "phsubd" analogously
2071 perform the horizontal substraction of 16-bit or 32-bit packed value, and
2072 "phsubsw" performs the horizontal substraction of signed 16-bit packed values
2073 with saturation.
2074 "pabsb", "pabsw" and "pabsd" calculate the absolute value of each signed
2075 packed signed value in source operand and stores them into the destination
2076 register. They operator on 8-bit, 16-bit and 32-bit elements respectively.
2077 "pmaddubsw" multiplies signed 8-bit values from the source operand with the
2078 corresponding unsigned 8-bit values from the destination operand to produce
2079 intermediate 16-bit values, and every adjacent pair of those intermediate
2080 values is then added horizontally and those 16-bit sums are stored into the
2081 destination operand.
2082 "pmulhrsw" multiplies corresponding 16-bit integers from the source and
2083 destination operand to produce intermediate 32-bit values, and the 16 bits
2084 next to the highest bit of each of those values are then rounded and packed
2085 into the destination operand.
2086 "pshufb" shuffles the bytes in the destination operand according to the
2087 mask provided by source operand - each of the bytes in source operand is
2088 an index of the target position for the corresponding byte in the destination.
2089 "psignb", "psignw" and "psignd" perform the operation on 8-bit, 16-bit or
2090 32-bit integers in destination operand, depending on the signs of the values
2091 in the source. If the value in source is negative, the corresponding value in
2092 the destination register is negated, if the value in source is positive, no
2093 operation is performed on the corresponding value is performed, and if the
2094 value in source is zero, the value in destination is zeroed, too.
2095 "palignr" appends the source operand to the destination operand to form the
2096 intermediate value of twice the size, and then extracts into the destination
2097 register the 64 or 128 bits that are right-aligned to the byte offset
2098 specified by the third operand, which should be an 8-bit immediate value. This
2099 is the only SSSE3 instruction that takes three arguments.
2100
2101
2102 2.1.18 AMD 3DNow! instructions
2103
2104 The 3DNow! extension adds a new MMX instructions to those described in 2.1.14,
2105 and introduces operation on the 64-bit packed floating point values, each
2106 consisting of two single precision floating point values.
2107 These instructions follow the same rules as the general MMX operations, the
2108 destination operand should be a MMX register, the source operand can be a MMX
2109 register or 64-bit memory location. "pavgusb" computes the rounded averages
2110 of packed unsigned bytes. "pmulhrw" performs a signed multiplication of the
2111 packed words, round the high word of each double word results and stores them
2112 in the destination operand. "pi2fd" converts packed double word integers into
2113 packed floating point values. "pf2id" converts packed floating point values
2114 into packed double word integers using truncation. "pi2fw" converts packed
2115 word integers into packed floating point values, only low words of each
2116 double word in source operand are used. "pf2iw" converts packed floating
2117 point values to packed word integers, results are extended to double words
2118 using the sign extension. "pfadd" adds packed floating point values. "pfsub"
2119 and "pfsubr" substracts packed floating point values, the first one substracts
2120 source values from destination values, the second one substracts destination
2121 values from the source values. "pfmul" multiplies packed floating point
2122 values. "pfacc" adds the low and high floating point values of the destination
2123 operand, storing the result in the low double word of destination, and adds
2124 the low and high floating point values of the source operand, storing the
2125 result in the high double word of destination. "pfnacc" substracts the high
2126 floating point value of the destination operand from the low, storing the
2127 result in the low double word of destination, and substracts the high floating
2128 point value of the source operand from the low, storing the result in the high
2129 double word of destination. "pfpnacc" substracts the high floating point value
2130 of the destination operand from the low, storing the result in the low double
2131 word of destination, and adds the low and high floating point values of the
2132 source operand, storing the result in the high double word of destination.
2133 "pfmax" and "pfmin" compute the maximum and minimum of floating point values.
2134 "pswapd" reverses the high and low double word of the source operand. "pfrcp"
2135 returns an estimates of the reciprocals of floating point values from the
2136 source operand, "pfrsqrt" returns an estimates of the reciprocal square
2137 roots of floating point values from the source operand, "pfrcpit1" performs
2138 the first step in the Newton-Raphson iteration to refine the reciprocal
2139 approximation produced by "pfrcp" instruction, "pfrsqit1" performs the first
2140 step in the Newton-Raphson iteration to refine the reciprocal square root
2141 approximation produced by "pfrsqrt" instruction, "pfrcpit2" performs the
2142 second final step in the Newton-Raphson iteration to refine the reciprocal
2143 approximation or the reciprocal square root approximation. "pfcmpeq",
2144 "pfcmpge" and "pfcmpgt" compare the packed floating point values and sets
2145 all bits or zeroes all bits of the correspoding data element in the
2146 destination operand according to the result of comparison, first checks
2147 whether values are equal, second checks whether destination value is greater
2148 or equal to source value, third checks whether destination value is greater
2149 than source value.
2150 "prefetch" and "prefetchw" load the line of data from memory that contains
2151 byte specified with the operand into the data cache, "prefetchw" instruction
2152 should be used when the data in the cache line is expected to be modified,
2153 otherwise the "prefetch" instruction should be used. The operand should be an
2154 8-bit memory location.
2155 "femms" performs a fast clear of MMX state. This instruction has no
2156 operands.
2157
2158
2159 2.1.19 The x86-64 long mode instructions
2160
2161 The AMD64 and EM64T architectures (we will use the common name x86-64 for them
2162 both) extend the x86 instruction set for the 64-bit processing. While legacy
2163 and compatibility modes use the same set of registers and instructions, the
2164 new long mode extends the x86 operations to 64 bits and introduces several new
2165 registers. You can turn on generating the code for this mode with the "use64"
2166 directive.
2167 Each of the general purpose registers is extended to 64 bits and the eight
2168 whole new general purpose registers and also eight new SSE registers are added.
2169 See table 2.4 for the summary of new registers (only the ones that was not
2170 listed in table 1.2). The general purpose registers of smallers sizes are the
2171 low order portions of the larger ones. You can still access the "ah", "bh",
2172 "ch" and "dh" registers in long mode, but you cannot use them in the same
2173 instruction with any of the new registers.
2174
2175 Table 2.4 New registers in long mode
2176 /--------------------------------------------------\
2177 | Type | General | SSE | AVX |
2178 |------|---------------------------|-------|-------|
2179 | Bits | 8 | 16 | 32 | 64 | 128 | 256 |
2180 |======|======|======|======|======|=======|=======|
2181 | | | | | rax | | |
2182 | | | | | rcx | | |
2183 | | | | | rdx | | |
2184 | | | | | rbx | | |
2185 | | spl | | | rsp | | |
2186 | | bpl | | | rbp | | |
2187 | | sil | | | rsi | | |
2188 | | dil | | | rdi | | |
2189 | | r8b | r8w | r8d | r8 | xmm8 | ymm8 |
2190 | | r9b | r9w | r9d | r9 | xmm9 | ymm9 |
2191 | | r10b | r10w | r10d | r10 | xmm10 | ymm10 |
2192 | | r11b | r11w | r11d | r11 | xmm11 | ymm11 |
2193 | | r12b | r12w | r12d | r12 | xmm12 | ymm12 |
2194 | | r13b | r13w | r13d | r13 | xmm13 | ymm13 |
2195 | | r14b | r14w | r14d | r14 | xmm14 | ymm14 |
2196 | | r15b | r15w | r15d | r15 | xmm15 | ymm15 |
2197 \--------------------------------------------------/
2198
2199 In general any instruction from x86 architecture, which allowed 16-bit or
2200 32-bit operand sizes, in long mode allows also the 64-bit operands. The 64-bit
2201 registers should be used for addressing in long mode, the 32-bit addressing
2202 is also allowed, but it's not possible to use the addresses based on 16-bit
2203 registers. Below are the samples of new operations possible in long mode on the
2204 example of "mov" instruction:
2205
2206 mov rax,r8 ; transfer 64-bit general register
2207 mov al,[rbx] ; transfer memory addressed by 64-bit register
2208
2209 The long mode uses also the instruction pointer based addresses, you can
2210 specify it manually with the special RIP register symbol, but such addressing
2211 is also automatically generated by flat assembler, since there is no 64-bit
2212 absolute addressing in long mode. You can still force the assembler to use the
2213 32-bit absolute addressing by putting the "dword" size override for address
2214 inside the square brackets. There is also one exception, where the 64-bit
2215 absolute addressing is possible, it's the "mov" instruction with one of the
2216 operand being accumulator register, and second being the memory operand.
2217 To force the assembler to use the 64-bit absolute addressing there, use the
2218 "qword" size operator for address inside the square brackets. When no size
2219 operator is applied to address, assembler generates the optimal form
2220 automatically.
2221
2222 mov [qword 0],rax ; absolute 64-bit addressing
2223 mov [dword 0],r15d ; absolute 32-bit addressing
2224 mov [0],rsi ; automatic RIP-relative addressing
2225 mov [rip+3],sil ; manual RIP-relative addressing
2226
2227 Also as the immediate operands for 64-bit operations only the signed 32-bit
2228 values are possible, with the only exception being the "mov" instruction with
2229 destination operand being 64-bit general purpose register. Trying to force the
2230 64-bit immediate with any other instruction will cause an error.
2231 If any operation is performed on the 32-bit general registers in long mode,
2232 the upper 32 bits of the 64-bit registers containing them are filled with
2233 zeros. This is unlike the operations on 16-bit or 8-bit portions of those
2234 registers, which preserve the upper bits.
2235 Three new type conversion instructions are available. The "cdqe" sign
2236 extends the double word in EAX into quad word and stores the result in RAX
2237 register. "cqo" sign extends the quad word in RAX into double quad word and
2238 stores the extra bits in the RDX register. These instructions have no
2239 operands. "movsxd" sign extends the double word source operand, being either
2240 the 32-bit register or memory, into 64-bit destination operand, which has to
2241 be register. No analogous instruction is needed for the zero extension, since
2242 it is done automatically by any operations on 32-bit registers, as noted in
2243 previous paragraph. And the "movzx" and "movsx" instructions, conforming to
2244 the general rule, can be used with 64-bit destination operand, allowing
2245 extension of byte or word values into quad words.
2246 All the binary arithmetic and logical instruction have been promoted to
2247 allow 64-bit operands in long mode. The use of decimal arithmetic instructions
2248 in long mode is prohibited.
2249 The stack operations, like "push" and "pop" in long mode default to 64-bit
2250 operands and it's not possible to use 32-bit operands with them. The "pusha"
2251 and "popa" are disallowed in long mode.
2252 The indirect near jumps and calls in long mode default to 64-bit operands
2253 and it's not possible to use the 32-bit operands with them. On the other hand,
2254 the indirect far jumps and calls allow any operands that were allowed by the
2255 x86 architecture and also 80-bit memory operand is allowed (though only EM64T
2256 seems to implement such variant), with the first eight bytes defining the
2257 offset and two last bytes specifying the selector. The direct far jumps and
2258 calls are not allowed in long mode.
2259 The I/O instructions, "in", "out", "ins" and "outs" are the exceptional
2260 instructions that are not extended to accept quad word operands in long mode.
2261 But all other string operations are, and there are new short forms "movsq",
2262 "cmpsq", "scasq", "lodsq" and "stosq" introduced for the variants of string
2263 operations for 64-bit string elements. The RSI and RDI registers are used by
2264 default to address the string elements.
2265 The "lfs", "lgs" and "lss" instructions are extended to accept 80-bit source
2266 memory operand with 64-bit destination register (though only EM64T seems to
2267 implement such variant). The "lds" and "les" are disallowed in long mode.
2268 The system instructions like "lgdt" which required the 48-bit memory operand,
2269 in long mode require the 80-bit memory operand.
2270 The "cmpxchg16b" is the 64-bit equivalent of "cmpxchg8b" instruction, it uses
2271 the double quad word memory operand and 64-bit registers to perform the
2272 analoguous operation.
2273 The "fxsave64" and "fxrstor64" are new variants of "fxsave" and "fxrstor"
2274 instructions, available only in long mode, which use a different format of
2275 storage area in order to store some pointers in full 64-bit size.
2276 "swapgs" is the new instruction, which swaps the contents of GS register and
2277 the KernelGSbase model-specific register (MSR address 0C0000102h).
2278 "syscall" and "sysret" is the pair of new instructions that provide the
2279 functionality similar to "sysenter" and "sysexit" in long mode, where the
2280 latter pair is disallowed. The "sysexitq" and "sysretq" mnemonics provide the
2281 64-bit versions of "sysexit" and "sysret" instructions.
2282 The "rdmsrq" and "wrmsrq" mnemonics are the 64-bit variants of the "rdmsr"
2283 and "wrmsr" instructions.
2284
2285
2286 2.1.20 SSE4 instructions
2287
2288 There are actually three different sets of instructions under the name SSE4.
2289 Intel designed two of them, SSE4.1 and SSE4.2, with latter extending the
2290 former into the full Intel's SSE4 set. On the other hand, the implementation
2291 by AMD includes only a few instructions from this set, but also contains
2292 some additional instructions, that are called the SSE4a set.
2293 The SSE4.1 instructions mostly follow the same rules for operands, as
2294 the basic SSE operations, so they require destination operand to be SSE
2295 register and source operand to be 128-bit memory location or SSE register,
2296 and some operations require a third operand, the 8-bit immediate value.
2297 "pmulld" performs a signed multiplication of the packed double words and
2298 stores the low double words of the results in the destination operand.
2299 "pmuldq" performs a two signed multiplications of the corresponding double
2300 words in the lower quad words of operands, and stores the results as
2301 packed quad words into the destination register. "pminsb" and "pmaxsb"
2302 return the minimum or maximum values of packed signed bytes, "pminuw" and
2303 "pmaxuw" return the minimum and maximum values of packed unsigned words,
2304 "pminud", "pmaxud", "pminsd" and "pmaxsd" return minimum or maximum values
2305 of packed unsigned or signed words. These instructions complement the
2306 instructions computing packed minimum or maximum introduced by SSE.
2307 "ptest" sets the ZF flag to one when the result of bitwise AND of the
2308 both operands is zero, and zeroes the ZF otherwise. It also sets CF flag
2309 to one, when the result of bitwise AND of the destination operand with
2310 the bitwise NOT of the source operand is zero, and zeroes the CF otherwise.
2311 "pcmpeqq" compares packed quad words for equality, and fills the
2312 corresponding elements of destination operand with either ones or zeros,
2313 depending on the result of comparison.
2314 "packusdw" converts packed signed double words from both the source and
2315 destination operand into the unsigned words using saturation, and stores
2316 the eight resulting word values into the destination register.
2317 "phminposuw" finds the minimum unsigned word value in source operand and
2318 places it into the lowest word of destination operand, setting the remaining
2319 upper bits of destination to zero.
2320 "roundps", "roundss", "roundpd" and "roundsd" perform the rounding of packed
2321 or individual floating point value of single or double precision, using the
2322 rounding mode specified by the third operand.
2323
2324 roundsd xmm0,xmm1,0011b ; round toward zero
2325
2326 "dpps" calculates dot product of packed single precision floating point
2327 values, that is it multiplies the corresponding pairs of values from source and
2328 destination operand and then sums the products up. The high four bits of the
2329 8-bit immediate third operand control which products are calculated and taken
2330 to the sum, and the low four bits control, into which elements of destination
2331 the resulting dot product is copied (the other elements are filled with zero).
2332 "dppd" calculates dot product of packed double precision floating point values.
2333 The bits 4 and 5 of third operand control, which products are calculated and
2334 added, and bits 0 and 1 of this value control, which elements in destination
2335 register should get filled with the result. "mpsadbw" calculates multiple sums
2336 of absolute differences of unsigned bytes. The third operand controls, with
2337 value in bits 0-1, which of the four-byte blocks in source operand is taken to
2338 calculate the absolute differencies, and with value in bit 2, at which of the
2339 two first four-byte block in destination operand start calculating multiple
2340 sums. The sum is calculated from four absolute differencies between the
2341 corresponding unsigned bytes in the source and destination block, and each next
2342 sum is calculated in the same way, but taking the four bytes from destination
2343 at the position one byte after the position of previous block. The four bytes
2344 from the source stay the same each time. This way eight sums of absolute
2345 differencies are calculated and stored as packed word values into the
2346 destination operand. The instructions described in this paragraph follow the
2347 same rules for operands, as "roundps" instruction.
2348 "blendps", "blendvps", "blendpd" and "blendvpd" conditionally copy the
2349 values from source operand into the destination operand, depending on the bits
2350 of the mask provided by third operand. If a mask bit is set, the corresponding
2351 element of source is copied into the same place in destination, otherwise this
2352 position is destination is left unchanged. The rules for the first two operands
2353 are the same, as for general SSE instructions. "blendps" and "blendpd" need
2354 third operand to be 8-bit immediate, and they operate on single or double
2355 precision values, respectively. "blendvps" and "blendvpd" require third operand
2356 to be the XMM0 register.
2357
2358 blendvps xmm3,xmm7,xmm0 ; blend according to mask
2359
2360 "pblendw" conditionally copies word elements from the source operand into the
2361 destination, depending on the bits of mask provided by third operand, which
2362 needs to be 8-bit immediate value. "pblendvb" conditionally copies byte
2363 elements from the source operands into destination, depending on mask defined
2364 by the third operand, which has to be XMM0 register. These instructions follow
2365 the same rules for operands as "blendps" and "blendvps" instructions,
2366 respectively.
2367 "insertps" inserts a single precision floating point value taken from the
2368 position in source operand specified by bits 6-7 of third operand into location
2369 in destination register selected by bits 4-5 of third operand. Additionally,
2370 the low four bits of third operand control, which elements in destination
2371 register will be set to zero. The first two operands follow the same rules as
2372 for the general SSE operation, the third operand should be 8-bit immediate.
2373 "extractps" extracts a single precision floating point value taken from the
2374 location in source operand specified by low two bits of third operand, and
2375 stores it into the destination operand. The destination can be a 32-bit memory
2376 value or general purpose register, the source operand must be SSE register,
2377 and the third operand should be 8-bit immediate value.
2378
2379 extractps edx,xmm3,3 ; extract the highest value
2380
2381 "pinsrb", "pinsrd" and "pinsrq" copy a byte, double word or quad word from
2382 the source operand into the location of destination operand determined by the
2383 third operand. The destination operand has to be SSE register, the source
2384 operand can be a memory location of appropriate size, or the 32-bit general
2385 purpose register (but 64-bit general purpose register for "pinsrq", which is
2386 only available in long mode), and the third operand has to be 8-bit immediate
2387 value. These instructions complement the "pinsrw" instruction operating on SSE
2388 register destination, which was introduced by SSE2.
2389
2390 pinsrd xmm4,eax,1 ; insert double word into second position
2391
2392 "pextrb", "pextrw", "pextrd" and "pextrq" copy a byte, word, double word or
2393 quad word from the location in source operand specified by third operand, into
2394 the destination. The source operand should be SSE register, the third operand
2395 should be 8-bit immediate, and the destination operand can be memory location
2396 of appropriate size, or the 32-bit general purpose register (but 64-bit general
2397 purpose register for "pextrq", which is only available in long mode). The
2398 "pextrw" instruction with SSE register as source was already introduced by
2399 SSE2, but SSE4 extends it to allow memory operand as destination.
2400
2401 pextrw [ebx],xmm3,7 ; extract highest word into memory
2402
2403 "pmovsxbw" and "pmovzxbw" perform sign extension or zero extension of eight
2404 byte values from the source operand into packed word values in destination
2405 operand, which has to be SSE register. The source can be 64-bit memory or SSE
2406 register - when it is register, only its low portion is used. "pmovsxbd" and
2407 "pmovzxbd" perform sign extension or zero extension of the four byte values
2408 from the source operand into packed double word values in destination operand,
2409 the source can be 32-bit memory or SSE register. "pmovsxbq" and "pmovzxbq"
2410 perform sign extension or zero extension of the two byte values from the
2411 source operand into packed quad word values in destination operand, the source
2412 can be 16-bit memory or SSE register. "pmovsxwd" and "pmovzxwd" perform sign
2413 extension or zero extension of the four word values from the source operand
2414 into packed double words in destination operand, the source can be 64-bit
2415 memory or SSE register. "pmovsxwq" and "pmovzxwq" perform sign extension or
2416 zero extension of the two word values from the source operand into packed quad
2417 words in destination operand, the source can be 32-bit memory or SSE register.
2418 "pmovsxdq" and "pmovzxdq" perform sign extension or zero extension of the two
2419 double word values from the source operand into packed quad words in
2420 destination operand, the source can be 64-bit memory or SSE register.
2421
2422 pmovzxbq xmm0,word [si] ; zero-extend bytes to quad words
2423 pmovsxwq xmm0,xmm1 ; sign-extend words to quad words
2424
2425 "movntdqa" loads double quad word from the source operand to the destination
2426 using a non-temporal hint. The destination operand should be SSE register,
2427 and the source operand should be 128-bit memory location.
2428 The SSE4.2, described below, adds not only some new operations on SSE
2429 registers, but also introduces some completely new instructions operating on
2430 general purpose registers only.
2431 "pcmpistri" compares two zero-ended (implicit length) strings provided in
2432 its source and destination operand and generates an index stored to ECX;
2433 "pcmpistrm" performs the same comparison and generates a mask stored to XMM0.
2434 "pcmpestri" compares two strings of explicit lengths, with length provided
2435 in EAX for the destination operand and in EDX for the source operand, and
2436 generates an index stored to ECX; "pcmpestrm" performs the same comparision
2437 and generates a mask stored to XMM0. The source and destination operand follow
2438 the same rules as for general SSE instructions, the third operand should be
2439 8-bit immediate value determining the details of performed operation - refer to
2440 Intel documentation for information on those details.
2441 "pcmpgtq" compares packed quad words, and fills the corresponding elements of
2442 destination operand with either ones or zeros, depending on whether the value
2443 in destination is greater than the one in source, or not. This instruction
2444 follows the same rules for operands as "pcmpeqq".
2445 "crc32" accumulates a CRC32 value for the source operand starting with
2446 initial value provided by destination operand, and stores the result in
2447 destination. Unless in long mode, the destination operand should be a 32-bit
2448 general purpose register, and the source operand can be a byte, word, or double
2449 word register or memory location. In long mode the destination operand can
2450 also be a 64-bit general purpose register, and the source operand in such case
2451 can be a byte or quad word register or memory location.
2452
2453 crc32 eax,dl ; accumulate CRC32 on byte value
2454 crc32 eax,word [ebx] ; accumulate CRC32 on word value
2455 crc32 rax,qword [rbx] ; accumulate CRC32 on quad word value
2456
2457 "popcnt" calculates the number of bits set in the source operand, which can
2458 be 16-bit, 32-bit, or 64-bit general purpose register or memory location,
2459 and stores this count in the destination operand, which has to be register of
2460 the same size as source operand. The 64-bit variant is available only in long
2461 mode.
2462
2463 popcnt ecx,eax ; count bits set to 1
2464
2465 The SSE4a extension, which also includes the "popcnt" instruction introduced
2466 by SSE4.2, at the same time adds the "lzcnt" instruction, which follows the
2467 same syntax, and calculates the count of leading zero bits in source operand
2468 (if the source operand is all zero bits, the total number of bits in source
2469 operand is stored in destination).
2470 "extrq" extract the sequence of bits from the low quad word of SSE register
2471 provided as first operand and stores them at the low end of this register,
2472 filling the remaining bits in the low quad word with zeros. The position of bit
2473 string and its length can either be provided with two 8-bit immediate values
2474 as second and third operand, or by SSE register as second operand (and there
2475 is no third operand in such case), which should contain position value in bits
2476 8-13 and length of bit string in bits 0-5.
2477
2478 extrq xmm0,8,7 ; extract 8 bits from position 7
2479 extrq xmm0,xmm5 ; extract bits defined by register
2480
2481 "insertq" writes the sequence of bits from the low quad word of the source
2482 operand into specified position in low quad word of the destination operand,
2483 leaving the other bits in low quad word of destination intact. The position
2484 where bits should be written and the length of bit string can either be
2485 provided with two 8-bit immediate values as third and fourth operand, or by
2486 the bit fields in source operand (and there are only two operands in such
2487 case), which should contain position value in bits 72-77 and length of bit
2488 string in bits 64-69.
2489
2490 insertq xmm1,xmm0,4,2 ; insert 4 bits at position 2
2491 insertq xmm1,xmm0 ; insert bits defined by register
2492
2493 "movntss" and "movntsd" store single or double precision floating point
2494 value from the source SSE register into 32-bit or 64-bit destination memory
2495 location respectively, using non-temporal hint.
2496
2497
2498 2.1.21 AVX instructions
2499
2500 The Advanced Vector Extensions introduce instructions that are new variants
2501 of SSE instructions, with new scheme of encoding that allows extended syntax
2502 having a destination operand separate from all the source operands. It also
2503 introduces 256-bit AVX registers, which extend up the old 128-bit SSE
2504 registers. Any AVX instruction that puts some result into SSE register, puts
2505 zero bits into high portion of the AVX register containing it.
2506 The AVX version of SSE instruction has the mnemonic obtained by prepending
2507 SSE instruction name with "v". For any SSE arithmetic instruction which had a
2508 destination operand also being used as one of the source values, the AVX
2509 variant has a new syntax with three operands - the destination and two sources.
2510 The destination and first source can be SSE registers, and second source can be
2511 SSE register or memory. If the operation is performed on single pair of values,
2512 the remaining bits of first source SSE register are copied into the the
2513 destination register.
2514
2515 vsubss xmm0,xmm2,xmm3 ; substract two 32-bit floats
2516 vmulsd xmm0,xmm7,qword [esi] ; multiply two 64-bit floats
2517
2518 In case of packed operations, each instruction can also operate on the 256-bit
2519 data size when the AVX registers are specified instead of SSE registers, and
2520 the size of memory operand is also doubled then.
2521
2522 vaddps ymm1,ymm5,yword [esi] ; eight sums of 32-bit float pairs
2523
2524 The instructions that operate on packed integer types (in particular the ones
2525 that earlier had been promoted from MMX to SSE) also acquired the new syntax
2526 with three operands, however they are only allowed to operate on 128-bit
2527 packed types and thus cannot use the whole AVX registers.
2528
2529 vpavgw xmm3,xmm0,xmm2 ; average of 16-bit integers
2530 vpslld xmm1,xmm0,1 ; shift double words left
2531
2532 If the SSE version of instruction had a syntax with three operands, the third
2533 one being an immediate value, the AVX version of such instruction takes four
2534 operands, with immediate remaining the last one.
2535
2536 vshufpd ymm0,ymm1,ymm2,10010011b ; shuffle 64-bit floats
2537 vpalignr xmm0,xmm4,xmm2,3 ; extract byte aligned value
2538
2539 The promotion to new syntax according to the rules described above has been
2540 applied to all the instructions from SSE extensions up to SSE4, with the
2541 exceptions described below.
2542 "vdppd" instruction has syntax extended to four operans, but it does not
2543 have a 256-bit version.
2544 The are a few instructions, namely "vsqrtpd", "vsqrtps", "vrcpps" and
2545 "vrsqrtps", which can operate on 256-bit data size, but retained the syntax
2546 with only two operands, because they use data from only one source:
2547
2548 vsqrtpd ymm1,ymm0 ; put square roots into other register
2549
2550 In a similar way "vroundpd" and "vroundps" retained the syntax with three
2551 operands, the last one being immediate value.
2552
2553 vroundps ymm0,ymm1,0011b ; round toward zero
2554
2555 Also some of the operations on packed integers kept their two-operand or
2556 three-operand syntax while being promoted to AVX version. In such case these
2557 instructions follow exactly the same rules for operands as their SSE
2558 counterparts (since operations on packed integers do not have 256-bit variants
2559 in AVX extension). These include "vpcmpestri", "vpcmpestrm", "vpcmpistri",
2560 "vpcmpistrm", "vphminposuw", "vpshufd", "vpshufhw", "vpshuflw". And there are
2561 more instructions that in AVX versions keep exactly the same syntax for
2562 operands as the one from SSE, without any additional options: "vcomiss",
2563 "vcomisd", "vcvtss2si", "vcvtsd2si", "vcvttss2si", "vcvttsd2si", "vextractps",
2564 "vpextrb", "vpextrw", "vpextrd", "vpextrq", "vmovd", "vmovq", "vmovntdqa",
2565 "vmaskmovdqu", "vpmovmskb", "vpmovsxbw", "vpmovsxbd", "vpmovsxbq", "vpmovsxwd",
2566 "vpmovsxwq", "vpmovsxdq", "vpmovzxbw", "vpmovzxbd", "vpmovzxbq", "vpmovzxwd",
2567 "vpmovzxwq" and "vpmovzxdq".
2568 The move and conversion instructions have mostly been promoted to allow
2569 256-bit size operands in addition to the 128-bit variant with syntax identical
2570 to that from SSE version of the same instruction. Each of the "vcvtdq2ps",
2571 "vcvtps2dq" and "vcvttps2dq", "vmovaps", "vmovapd", "vmovups", "vmovupd",
2572 "vmovdqa", "vmovdqu", "vlddqu", "vmovntps", "vmovntpd", "vmovntdq",
2573 "vmovsldup", "vmovshdup", "vmovmskps" and "vmovmskpd" inherits the 128-bit
2574 syntax from SSE without any changes, and also allows a new form with 256-bit
2575 operands in place of 128-bit ones.
2576
2577 vmovups [edi],ymm6 ; store unaligned 256-bit data
2578
2579 "vmovddup" has the identical 128-bit syntax as its SSE version, and it also
2580 has a 256-bit version, which stores the duplicates of the lowest quad word
2581 from the source operand in the lower half of destination operand, and in the
2582 upper half of destination the duplicates of the low quad word from the upper
2583 half of source. Both source and destination operands need then to be 256-bit
2584 values.
2585 "vmovlhps" and "vmovhlps" have only 128-bit versions, and each takes three
2586 operands, which all must be SSE registers. "vmovlhps" copies two single
2587 precision values from the low quad word of second source register to the high
2588 quad word of destination register, and copies the low quad word of first
2589 source register into the low quad word of destination register. "vmovhlps"
2590 copies two single precision values from the high quad word of second source
2591 register to the low quad word of destination register, and copies the high
2592 quad word of first source register into the high quad word of destination
2593 register.
2594 "vmovlps", "vmovhps", "vmovlpd" and "vmovhpd" have only 128-bit versions and
2595 their syntax varies depending on whether memory operand is a destination or
2596 source. When memory is destination, the syntax is identical to the one of
2597 equivalent SSE instruction, and when memory is source, the instruction requires
2598 three operands, first two being SSE registers and the third one 64-bit memory.
2599 The value put into destination is then the value copied from first source with
2600 either low or high quad word replaced with value from second source (the
2601 memory operand).
2602
2603 vmovhps [esi],xmm7 ; store upper half to memory
2604 vmovlps xmm0,xmm7,[ebx] ; low from memory, rest from register
2605
2606 "vmovss" and "vmovsd" have syntax identical to their SSE equivalents as long
2607 as one of the operands is memory, while the versions that operate purely on
2608 registers require three operands (each being SSE register). The value stored
2609 in destination is then the value copied from first source with lowest data
2610 element replaced with the lowest value from second source.
2611
2612 vmovss xmm3,[edi] ; low from memory, rest zeroed
2613 vmovss xmm0,xmm1,xmm2 ; one value from xmm2, three from xmm1
2614
2615 "vcvtss2sd", "vcvtsd2ss", "vcvtsi2ss" and "vcvtsi2d" use the three-operand
2616 syntax, where destination and first source are always SSE registers, and the
2617 second source follows the same rules and the source in syntax of equivalent
2618 SSE instruction. The value stored in destination is then the value copied from
2619 first source with lowest data element replaced with the result of conversion.
2620
2621 vcvtsi2sd xmm4,xmm4,ecx ; 32-bit integer to 64-bit float
2622 vcvtsi2ss xmm0,xmm0,rax ; 64-bit integer to 32-bit float
2623
2624 "vcvtdq2pd" and "vcvtps2pd" allow the same syntax as their SSE equivalents,
2625 plus the new variants with AVX register as destination and SSE register or
2626 128-bit memory as source. Analogously "vcvtpd2dq", "vcvttpd2dq" and
2627 "vcvtpd2ps", in addition to variant with syntax identical to SSE version,
2628 allow a variant with SSE register as destination and AVX register or 256-bit
2629 memory as source.
2630 "vinsertps", "vpinsrb", "vpinsrw", "vpinsrd", "vpinsrq" and "vpblendw" use
2631 a syntax with four operands, where destination and first source have to be SSE
2632 registers, and the third and fourth operand follow the same rules as second
2633 and third operand in the syntax of equivalent SSE instruction. Value stored in
2634 destination is the the value copied from first source with some data elements
2635 replaced with values extracted from the second source, analogously to the
2636 operation of corresponding SSE instruction.
2637
2638 vpinsrd xmm0,xmm0,eax,3 ; insert double word
2639
2640 "vblendvps", "vblendvpd" and "vpblendvb" use a new syntax with four register
2641 operands: destination, two sources and a mask, where second source can also be
2642 a memory operand. "vblendvps" and "vblendvpd" have 256-bit variant, where
2643 operands are AVX registers or 256-bit memory, as well as 128-bit variant,
2644 which has operands being SSE registers or 128-bit memory. "vpblendvb" has only
2645 a 128-bit variant. Value stored in destination is the value copied from the
2646 first source with some data elements replaced, according to mask, by values
2647 from the second source.
2648
2649 vblendvps ymm3,ymm1,ymm2,ymm7 ; blend according to mask
2650
2651 "vptest" allows the same syntax as its SSE version and also has a 256-bit
2652 version, with both operands doubled in size. There are also two new
2653 instructions, "vtestps" and "vtestpd", which perform analogous tests, but only
2654 of the sign bits of corresponding single precision or double precision values,
2655 and set the ZF and CF accordingly. They follow the same syntax rules as
2656 "vptest".
2657
2658 vptest ymm0,yword [ebx] ; test 256-bit values
2659 vtestpd xmm0,xmm1 ; test sign bits of 64-bit floats
2660
2661 "vbroadcastss", "vbroadcastsd" and "vbroadcastf128" are new instructions,
2662 which broadcast the data element defined by source operand into all elements
2663 of corresponing size in the destination register. "vbroadcastss" needs
2664 source to be 32-bit memory and destination to be either SSE or AVX register.
2665 "vbroadcastsd" requires 64-bit memory as source, and AVX register as
2666 destination. "vbroadcastf128" requires 128-bit memory as source, and AVX
2667 register as destination.
2668
2669 vbroadcastss ymm0,dword [eax] ; get eight copies of value
2670
2671 "vinsertf128" is the new instruction, which takes four operands. The
2672 destination and first source have to be AVX registers, second source can be
2673 SSE register or 128-bit memory location, and fourth operand should be an
2674 immediate value. It stores in destination the value obtained by taking
2675 contents of first source and replacing one of its 128-bit units with value of
2676 the second source. The lowest bit of fourth operand specifies at which
2677 position that replacement is done (either 0 or 1).
2678 "vextractf128" is the new instruction with three operands. The destination
2679 needs to be SSE register or 128-bit memory location, the source must be AVX
2680 register, and the third operand should be an immediate value. It extracts
2681 into destination one of the 128-bit units from source. The lowest bit of third
2682 operand specifies, which unit is extracted.
2683 "vmaskmovps" and "vmaskmovpd" are the new instructions with three operands
2684 that selectively store in destination the elements from second source
2685 depending on the sign bits of corresponding elements from first source. These
2686 instructions can operate on either 128-bit data (SSE registers) or 256-bit
2687 data (AVX registers). Either destination or second source has to be a memory
2688 location of appropriate size, the two other operands should be registers.
2689
2690 vmaskmovps [edi],xmm0,xmm5 ; conditionally store
2691 vmaskmovpd ymm5,ymm0,[esi] ; conditionally load
2692
2693 "vpermilpd" and "vpermilps" are the new instructions with three operands
2694 that permute the values from first source according to the control fields from
2695 second source and put the result into destination operand. It allows to use
2696 either three SSE registers or three AVX registers as its operands, the second
2697 source can be a memory of size equal to the registers used. In alternative
2698 form the second source can be immediate value and then the first source
2699 can be a memory location of the size equal to destination register.
2700 "vperm2f128" is the new instruction with four operands, which selects
2701 128-bit blocks of floating point data from first and second source according
2702 to the bit fields from fourth operand, and stores them in destination.
2703 Destination and first source need to be AVX registers, second source can be
2704 AVX register or 256-bit memory area, and fourth operand should be an immediate
2705 value.
2706
2707 vperm2f128 ymm0,ymm6,ymm7,12h ; permute 128-bit blocks
2708
2709 "vzeroall" instruction sets all the AVX registers to zero. "vzeroupper" sets
2710 the upper 128-bit portions of all AVX registers to zero, leaving the SSE
2711 registers intact. These new instructions take no operands.
2712 "vldmxcsr" and "vstmxcsr" are the AVX versions of "ldmxcsr" and "stmxcsr"
2713 instructions. The rules for their operands remain unchanged.
2714
2715
2716 2.1.22 AVX2 instructions
2717
2718 The AVX2 extension allows all the AVX instructions operating on packed integers
2719 to use 256-bit data types, and introduces some new instructions as well.
2720 The AVX instructions that operate on packed integers and had only a 128-bit
2721 variants, have been supplemented with 256-bit variants, and thus their syntax
2722 rules became analogous to AVX instructions operating on packed floating point
2723 types.
2724
2725 vpsubb ymm0,ymm0,[esi] ; substract 32 packed bytes
2726 vpavgw ymm3,ymm0,ymm2 ; average of 16-bit integers
2727
2728 However there are some instructions that have not been equipped with the
2729 256-bit variants. "vpcmpestri", "vpcmpestrm", "vpcmpistri", "vpcmpistrm",
2730 "vpextrb", "vpextrw", "vpextrd", "vpextrq", "vpinsrb", "vpinsrw", "vpinsrd",
2731 "vpinsrq" and "vphminposuw" are not affected by AVX2 and allow only the
2732 128-bit operands.
2733 The packed shift instructions, which allowed the third operand specifying
2734 amount to be SSE register or 128-bit memory location, use the same rules
2735 for the third operand in their 256-bit variant.
2736
2737 vpsllw ymm2,ymm2,xmm4 ; shift words left
2738 vpsrad ymm0,ymm3,xword [ebx] ; shift double words right
2739
2740 There are also new packed shift instructions with standard three-operand AVX
2741 syntax, which shift each element from first source by the amount specified in
2742 corresponding element of second source, and store the results in destination.
2743 "vpsllvd" shifts 32-bit elements left, "vpsllvq" shifts 64-bit elements left,
2744 "vpsrlvd" shifts 32-bit elements right logically, "vpsrlvq" shifts 64-bit
2745 elements right logically and "vpsravd" shifts 32-bit elements right
2746 arithmetically.
2747 The sign-extend and zero-extend instructions, which in AVX versions allowed
2748 source operand to be SSE register or a memory of specific size, in the new
2749 256-bit variant need memory of that size doubled or SSE register as source and
2750 AVX register as destination.
2751
2752 vpmovzxbq ymm0,dword [esi] ; bytes to quad words
2753
2754 Also "vmovntdqa" has been upgraded with 256-bit variant, so it allows to
2755 transfer 256-bit value from memory to AVX register, it needs memory address
2756 to be aligned to 32 bytes.
2757 "vpmaskmovd" and "vpmaskmovq" are the new instructions with syntax identical
2758 to "vmaskmovps" or "vmaskmovpd", and they performs analogous operation on
2759 packed 32-bit or 64-bit values.
2760 "vinserti128", "vextracti128", "vbroadcasti128" and "vperm2i128" are the new
2761 instructions with syntax identical to "vinsertf128", "vextractf128",
2762 "vbroadcastf128" and "vperm2f128" respectively, and they perform analogous
2763 operations on 128-bit blocks of integer data.
2764 "vbroadcastss" and "vbroadcastsd" instructions have been extended to allow
2765 SSE register as a source operand (which in AVX could only be a memory).
2766 "vpbroadcastb", "vpbroadcastw", "vpbroadcastd" and "vpbroadcastq" are the
2767 new instructions which broadcast the byte, word, double word or quad word from
2768 the source operand into all elements of corresponing size in the destination
2769 register. The destination operand can be either SSE or AVX register, and the
2770 source operand can be SSE register or memory of size equal to the size of data
2771 element.
2772
2773 vpbroadcastb ymm0,byte [ebx] ; get 32 identical bytes
2774
2775 "vpermd" and "vpermps" are new three-operand instructions, which use each
2776 32-bit element from first source as an index of element in second source which
2777 is copied into destination at position corresponding to element containing
2778 index. The destination and first source have to be AVX registers, and the
2779 second source can be AVX register or 256-bit memory.
2780 "vpermq" and "vpermpd" are new three-operand instructions, which use 2-bit
2781 indexes from the immediate value specified as third operand to determine which
2782 element from source store at given position in destination. The destination
2783 has to be AVX register, source can be AVX register or 256-bit memory, and the
2784 third operand must be 8-bit immediate value.
2785 The family of new instructions performing "gather" operation have special
2786 syntax, as in their memory operand they use addressing mode that is unique to
2787 them. The base of address can be a 32-bit or 64-bit general purpose register
2788 (the latter only in long mode), and the index (possibly multiplied by scale
2789 value, as in standard addressing) is specified by SSE or AVX register. It is
2790 possible to use only index without base and any numerical displacement can be
2791 added to the address. Each of those instructions takes three operands. First
2792 operand is the destination register, second operand is memory addressed with
2793 a vector index, and third operand is register containing a mask. The most
2794 significant bit of each element of mask determines whether a value will be
2795 loaded from memory into corresponding element in destination. The address of
2796 each element to load is determined by using the corresponding element from
2797 index register in memory operand to calculate final address with given base
2798 and displacement. When the index register contains less elements than the
2799 destination and mask registers, the higher elements of destination are zeroed.
2800 After the value is successfuly loaded, the corresponding element in mask
2801 register is set to zero. The destination, index and mask should all be
2802 distinct registers, it is not allowed to use the same register in two
2803 different roles.
2804 "vgatherdps" loads single precision floating point values addressed by
2805 32-bit indexes. The destination, index and mask should all be registers of the
2806 same type, either SSE or AVX. The data addressed by memory operand is 32-bit
2807 in size.
2808
2809 vgatherdps xmm0,[eax+xmm1],xmm3 ; gather four floats
2810 vgatherdps ymm0,[ebx+ymm7*4],ymm3 ; gather eight floats
2811
2812 "vgatherqps" loads single precision floating point values addressed by
2813 64-bit indexes. The destination and mask should always be SSE registers, while
2814 index register can be either SSE or AVX register. The data addressed by memory
2815 operand is 32-bit in size.
2816
2817 vgatherqps xmm0,[xmm2],xmm3 ; gather two floats
2818 vgatherqps xmm0,[ymm2+64],xmm3 ; gather four floats
2819
2820 "vgatherdpd" loads double precision floating point values addressed by
2821 32-bit indexes. The index register should always be SSE register, the
2822 destination and mask should be two registers of the same type, either SSE or
2823 AVX. The data addressed by memory operand is 64-bit in size.
2824
2825 vgatherdpd xmm0,[ebp+xmm1],xmm3 ; gather two doubles
2826 vgatherdpd ymm0,[xmm3*8],ymm5 ; gather four doubles
2827
2828 "vgatherqpd" loads double precision floating point values addressed by
2829 64-bit indexes. The destination, index and mask should all be registers of the
2830 same type, either SSE or AVX. The data addressed by memory operand is 64-bit
2831 in size.
2832 "vpgatherdd" and "vpgatherqd" load 32-bit values addressed by either 32-bit
2833 or 64-bit indexes. They follow the same rules as "vgatherdps" and "vgatherqps"
2834 respectively.
2835 "vpgatherdq" and "vpgatherqq" load 64-bit values addressed by either 32-bit
2836 or 64-bit indexes. They follow the same rules as "vgatherdpd" and "vgatherqpd"
2837 respectively.
2838
2839
2840 2.1.23 Auxiliary sets of computational instructions
2841
2842 There is a number of additional instruction set extensions related to
2843 AVX. They introduce new vector instructions (and sometimes also their SSE
2844 equivalents that use classic instruction encoding), and even some new
2845 instructions operating on general registers that use the AVX-like encoding
2846 allowing the extended syntax with separate destination and source operands.
2847 The CPU support for each of these instructions sets needs to be determined
2848 separately.
2849 The AES extension provides a specialized set of instructions for the
2850 purpose of cryptographic computations defined by Advanced Encryption Standard.
2851 Each of these instructions has two versions: the AVX one and the one with
2852 SSE-like syntax that uses classic encoding. Refer to the Intel manuals for the
2853 details of operation of these instructions.
2854 "aesenc" and "aesenclast" perform a single round of AES encryption on data
2855 from first source with a round key from second source, and store result in
2856 destination. The destination and first source are SSE registers, and the
2857 second source can be SSE register or 128-bit memory. The AVX versions of these
2858 instructions, "vaesenc" and "vaesenclast", use the syntax with three operands,
2859 while the SSE-like version has only two operands, with first operand being
2860 both the destination and first source.
2861 "aesdec" and "aesdeclast" perform a single round of AES decryption on data
2862 from first source with a round key from second source. The syntax rules for
2863 them and their AVX versions are the same as for "aesenc".
2864 "aesimc" performs the InvMixColumns transformation of source operand and
2865 store the result in destination. Both "aesimc" and "vaesimc" use only two
2866 operands, destination being SSE register, and source being SSE register or
2867 128-bit memory location.
2868 "aeskeygenassist" is a helper instruction for generating the round key.
2869 It needs three operands: destination being SSE register, source being SSE
2870 register or 128-bit memory, and third operand being 8-bit immediate value.
2871 The AVX version of this instruction uses the same syntax.
2872 The CLMUL extension introduces just one instruction, "pclmulqdq", and its
2873 AVX version as well. This instruction performs a carryless multiplication of
2874 two 64-bit values selected from first and second source according to the bit
2875 fields in immediate value. The destination and first source are SSE registers,
2876 second source is SSE register or 128-bit memory, and immediate value is
2877 provided as last operand. "vpclmulqdq" takes four operands, while "pclmulqdq"
2878 takes only three operands, with the first one serving both the role of
2879 destination and first source.
2880 The FMA (Fused Multiply-Add) extension introduces additional AVX
2881 instructions which perform multiplication and summation as single operation.
2882 Each one takes three operands, first one serving both the role of destination
2883 and first source, and the following ones being the second and third source.
2884 The mnemonic of FMA instruction is obtained by appending to "vf" prefix: first
2885 either "m" or "nm" to select whether result of multiplication should be taken
2886 as-is or negated, then either "add" or "sub" to select whether third value
2887 will be added to the product or substracted from the product, then either
2888 "132", "213" or "231" to select which source operands are multiplied and which
2889 one is added or substracted, and finally the type of data on which the
2890 instruction operates, either "ps", "pd", "ss" or "sd". As it was with SSE
2891 instructions promoted to AVX, instructions operating on packed floating point
2892 values allow 128-bit or 256-bit syntax, in former all the operands are SSE
2893 registers, but the third one can also be a 128-bit memory, in latter the
2894 operands are AVX registers and the third one can also be a 256-bit memory.
2895 Instructions that compute just one floating point result need operands to be
2896 SSE registers, and the third operand can also be a memory, either 32-bit for
2897 single precision or 64-bit for double precision.
2898
2899 vfmsub231ps ymm1,ymm2,ymm3 ; multiply and substract
2900 vfnmadd132sd xmm0,xmm5,[ebx] ; multiply, negate and add
2901
2902 In addition to the instructions created by the rule described above, there are
2903 families of instructions with mnemonics starting with either "vfmaddsub" or
2904 "vfmsubadd", followed by either "132", "213" or "231" and then either "ps" or
2905 "pd" (the operation must always be on packed values in this case). They add
2906 to the result of multiplication or substract from it depending on the position
2907 of value in packed data - instructions from the "vfmaddsub" group add when the
2908 position is odd and substract when the position is even, instructions from the
2909 "vfmsubadd" group add when the position is even and subtstract when the
2910 position is odd. The rules for operands are the same as for other FMA
2911 instructions.
2912 The FMA4 instructions are similar to FMA, but use syntax with four operands
2913 and thus allow destination to be different than all the sources. Their
2914 mnemonics are identical to FMA instructions with the "132", "213" or "231" cut
2915 out, as having separate destination operand makes such selection of operands
2916 superfluous. The multiplication is always performed on values from the first
2917 and second source, and then the value from third source is added or
2918 substracted. Either second or third source can be a memory operand, and the
2919 rules for the sizes of operands are the same as for FMA instructions.
2920
2921 vfmaddpd ymm0,ymm1,[esi],ymm2 ; multiply and add
2922 vfmsubss xmm0,xmm1,xmm2,[ebx] ; multiply and substract
2923
2924 The F16C extension consists of two instructions, "vcvtps2ph" and
2925 "vcvtph2ps", which convert floating point values between single precision and
2926 half precision (the 16-bit floating point format). "vcvtps2ph" takes three
2927 operands: destination, source, and rounding controls. The third operand is
2928 always an immediate, the source is either SSE or AVX register containing
2929 single precision values, and the destination is SSE register or memory, the
2930 size of memory is 64 bits when the source is SSE register and 128 bits when
2931 the source is AVX register. "vcvtph2ps" takes two operands, the destination
2932 that can be SSE or AVX register, and the source that is SSE register or memory
2933 with size of the half of destination operand's size.
2934 The AMD XOP extension introduces a number of new vector instructions with
2935 encoding and syntax analogous to AVX instructions. "vfrczps", "vfrczss",
2936 "vfrczpd" and "vfrczsd" extract fractional portions of single or double
2937 precision values, they all take two operands. The packed operations allow
2938 either SSE or AVX register as destination, for the other two it has to be SSE
2939 register. Source can be register of the same type as destination, or memory
2940 of appropriate size (256-bit for destination being AVX register, 128-bit for
2941 packed operation with destination being SSE register, 64-bit for operation
2942 on a solitary double precision value and 32-bit for operation on a solitary
2943 single precision value).
2944
2945 vfrczps ymm0,[esi] ; load fractional parts
2946
2947 "vpcmov" copies bits from either first or second source into destination
2948 depending on the values of corresponding bits in the fourth operand (the
2949 selector). If the bit in selector is set, the corresponding bit from first
2950 source is copied into the same position in destination, otherwise the bit from
2951 second source is copied. Either second source or selector can be memory
2952 location, 128-bit or 256-bit depending on whether SSE registers or AVX
2953 registers are specified as the other operands.
2954
2955 vpcmov xmm0,xmm1,xmm2,[ebx] ; selector in memory
2956 vpcmov ymm0,ymm5,[esi],ymm2 ; source in memory
2957
2958 The family of packed comparison instructions take four operands, the
2959 destination and first source being SSE register, second source being SSE
2960 register or 128-bit memory and the fourth operand being immediate value
2961 defining the type of comparison. The mnemonic or instruction is created
2962 by appending to "vpcom" prefix either "b" or "ub" to compare signed or
2963 unsigned bytes, "w" or "uw" to compare signed or unsigned words, "d" or "ud"
2964 to compare signed or unsigned double words, "q" or "uq" to compare signed or
2965 unsigned quad words. The respective values from the first and second source
2966 are compared and the corresponding data element in destination is set to
2967 either all ones or all zeros depending on the result of comparison. The fourth
2968 operand has to specify one of the eight comparison types (table 2.5). All
2969 these instructions have also variants with only three operands and the type
2970 of comparison encoded within the instruction name by inserting the comparison
2971 mnemonic after "vpcom".
2972
2973 vpcomb xmm0,xmm1,xmm2,4 ; test for equal bytes
2974 vpcomgew xmm0,xmm1,[ebx] ; compare signed words
2975
2976 Table 2.5 XOP comparisons
2977 /-------------------------------------------\
2978 | Code | Mnemonic | Description |
2979 |======|==========|=========================|
2980 | 0 | lt | less than |
2981 | 1 | le | less than or equal |
2982 | 2 | gt | greater than |
2983 | 3 | ge | greater than or equal |
2984 | 4 | eq | equal |
2985 | 5 | neq | not equal |
2986 | 6 | false | false |
2987 | 7 | true | true |
2988 \-------------------------------------------/
2989
2990 "vpermil2ps" and "vpermil2pd" set the elements in destination register to
2991 zero or to a value selected from first or second source depending on the
2992 corresponding bit fields from the fourth operand (the selector) and the
2993 immediate value provided in fifth operand. Refer to the AMD manuals for the
2994 detailed explanation of the operation performed by these instructions. Each
2995 of the first four operands can be a register, and either second source or
2996 selector can be memory location, 128-bit or 256-bit depending on whether SSE
2997 registers or AVX registers are used for the other operands.
2998
2999 vpermil2ps ymm0,ymm3,ymm7,ymm2,0 ; permute from two sources
3000
3001 "vphaddbw" adds pairs of adjacent signed bytes to form 16-bit values and
3002 stores them at the same positions in destination. "vphaddubw" does the same
3003 but treats the bytes as unsigned. "vphaddbd" and "vphaddubd" sum all bytes
3004 (either signed or unsigned) in each four-byte block to 32-bit results,
3005 "vphaddbq" and "vphaddubq" sum all bytes in each eight-byte block to
3006 64-bit results, "vphaddwd" and "vphadduwd" add pairs of words to 32-bit
3007 results, "vphaddwq" and "vphadduwq" sum all words in each four-word block to
3008 64-bit results, "vphadddq" and "vphaddudq" add pairs of double words to 64-bit
3009 results. "vphsubbw" substracts in each two-byte block the byte at higher
3010 position from the one at lower position, and stores the result as a signed
3011 16-bit value at the corresponding position in destination, "vphsubwd"
3012 substracts in each two-word block the word at higher position from the one at
3013 lower position and makes signed 32-bit results, "vphsubdq" substract in each
3014 block of two double word the one at higher position from the one at lower
3015 position and makes signed 64-bit results. Each of these instructions takes
3016 two operands, the destination being SSE register, and the source being SSE
3017 register or 128-bit memory.
3018
3019 vphadduwq xmm0,xmm1 ; sum quadruplets of words
3020
3021 "vpmacsww" and "vpmacssww" multiply the corresponding signed 16-bit values
3022 from the first and second source and then add the products to the parallel
3023 values from the third source, then "vpmacsww" takes the lowest 16 bits of the
3024 result and "vpmacssww" saturates the result down to 16-bit value, and they
3025 store the final 16-bit results in the destination. "vpmacsdd" and "vpmacssdd"
3026 perform the analogous operation on 32-bit values. "vpmacswd" and "vpmacsswd" do
3027 the same calculation only on the low 16-bit values from each 32-bit block and
3028 form the 32-bit results. "vpmacsdql" and "vpmacssdql" perform such operation
3029 on the low 32-bit values from each 64-bit block and form the 64-bit results,
3030 while "vpmacsdqh" and "vpmacssdqh" do the same on the high 32-bit values from
3031 each 64-bit block, also forming the 64-bit results. "vpmadcswd" and
3032 "vpmadcsswd" multiply the corresponding signed 16-bit value from the first
3033 and second source, then sum all the four products and add this sum to each
3034 16-bit element from third source, storing the truncated or saturated result
3035 in destination. All these instructions take four operands, the second source
3036 can be 128-bit memory or SSE register, all the other operands have to be
3037 SSE registers.
3038
3039 vpmacsdd xmm6,xmm1,[ebx],xmm6 ; accumulate product
3040
3041 "vpperm" selects bytes from first and second source, optionally applies a
3042 separate transformation to each of them, and stores them in the destination.
3043 The bit fields in fourth operand (the selector) specify for each position in
3044 destination what byte from which source is taken and what operation is applied
3045 to it before it is stored there. Refer to the AMD manuals for the detailed
3046 information about these bit fields. This instruction takes four operands,
3047 either second source or selector can be a 128-bit memory (or they can be SSE
3048 registers both), all the other operands have to be SSE registers.
3049 "vpshlb", "vpshlw", "vpshld" and "vpshlq" shift logically bytes, words, double
3050 words or quad words respectively. The amount of bits to shift by is specified
3051 for each element separately by the signed byte placed at the corresponding
3052 position in the third operand. The source containing elements to shift is
3053 provided as second operand. Either second or third operand can be 128-bit
3054 memory (or they can be SSE registers both) and the other operands have to be
3055 SSE registers.
3056
3057 vpshld xmm3,xmm1,[ebx] ; shift bytes from xmm1
3058
3059 "vpshab", "vpshaw", "vpshad" and "vpshaq" arithmetically shift bytes, words,
3060 double words or quad words. These instructions follow the same rules as the
3061 logical shifts described above. "vprotb", "vprotw", "vprotd" and "vprotq"
3062 rotate bytes, word, double words or quad words. They follow the same rules as
3063 shifts, but additionally allow third operand to be immediate value, in which
3064 case the same amount of rotation is specified for all the elements in source.
3065
3066 vprotb xmm0,[esi],3 ; rotate bytes to the left
3067
3068 The MOVBE extension introduces just one new instruction, "movbe", which
3069 swaps bytes in value from source before storing it in destination, so can
3070 be used to load and store big endian values. It takes two operands, either
3071 the destination or source should be a 16-bit, 32-bit or 64-bit memory (the
3072 last one being only allowed in long mode), and the other operand should be
3073 a general register of the same size.
3074 The BMI extension, consisting of two subsets - BMI1 and BMI2, introduces
3075 new instructions operating on general registers, which use the same encoding
3076 as AVX instructions and so allow the extended syntax. All these instructions
3077 use 32-bit operands, and in long mode they also allow the forms with 64-bit
3078 operands.
3079 "andn" calculates the bitwise AND of second source with the inverted bits
3080 of first source and stores the result in destination. The destination and
3081 the first source have to be general registers, the second source can be
3082 general register or memory.
3083
3084 andn edx,eax,[ebx] ; bit-multiply inverted eax with memory
3085
3086 "bextr" extracts from the first source the sequence of bits using an index
3087 and length specified by bit fields in the second source operand and stores
3088 it into destination. The lowest 8 bits of second source specify the position
3089 of bit sequence to extract and the next 8 bits of second source specify the
3090 length of sequence. The first source can be a general register or memory,
3091 the other two operands have to be general registers.
3092
3093 bextr eax,[esi],ecx ; extract bit field from memory
3094
3095 "blsi" extracts the lowest set bit from the source, setting all the other
3096 bits in destination to zero. The destination must be a general register,
3097 the source can be general register or memory.
3098
3099 blsi rax,r11 ; isolate the lowest set bit
3100
3101 "blsmsk" sets all the bits in the destination up to the lowest set bit in
3102 the source, including this bit. "blsr" copies all the bits from the source to
3103 destination except for the lowest set bit, which is replaced by zero. These
3104 instructions follow the same rules for operands as "blsi".
3105 "tzcnt" counts the number of trailing zero bits, that is the zero bits up to
3106 the lowest set bit of source value. This instruction is analogous to "lzcnt"
3107 and follows the same rules for operands, so it also has a 16-bit version,
3108 unlike the other BMI instructions.
3109 "bzhi" is BMI2 instruction, which copies the bits from first source to
3110 destination, zeroing all the bits up from the position specified by second
3111 source. It follows the same rules for operands as "bextr".
3112 "pext" uses a mask in second source operand to select bits from first
3113 operands and puts the selected bits as a continuous sequence into destination.
3114 "pdep" performs the reverse operation - it takes sequence of bits from the
3115 first source and puts them consecutively at the positions where the bits in
3116 second source are set, setting all the other bits in destination to zero.
3117 These BMI2 instructions follow the same rules for operands as "andn".
3118 "mulx" is a BMI2 instruction which performs an unsigned multiplication of
3119 value from EDX or RDX register (depending on the size of specified operands)
3120 by the value from third operand, and stores the low half of result in the
3121 second operand, and the high half of result in the first operand, and it does
3122 it without affecting the flags. The third operand can be general register or
3123 memory, and both the destination operands have to be general registers.
3124
3125 mulx edx,eax,ecx ; multiply edx by ecx into edx:eax
3126
3127 "shlx", "shrx" and "sarx" are BMI2 instructions, which perform logical or
3128 arithmetical shifts of value from first source by the amount specified by
3129 second source, and store the result in destination without affecting the
3130 flags. The have the same rules for operands as "bzhi" instruction.
3131 "rorx" is a BMI2 instruction which rotates right the value from source
3132 operand by the constant amount specified in third operand and stores the
3133 result in destination without affecting the flags. The destination operand
3134 has to be general register, the source operand can be general register or
3135 memory, and the third operand has to be an immediate value.
3136
3137 rorx eax,edx,7 ; rotate without affecting flags
3138
3139 The TBM is an extension designed by AMD to supplement the BMI set. The
3140 "bextr" instruction is extended with a new form, in which second source is
3141 a 32-bit immediate value. "blsic" is a new instruction which performs the
3142 same operation as "blsi", but with the bits of result reversed. It uses the
3143 same rules for operands as "blsi". "blsfill" is a new instruction, which takes
3144 the value from source, sets all the bits below the lowest set bit and store
3145 the result in destination, it also uses the same rules for operands as "blsi".
3146 "blci", "blcic", "blcs", "blcmsk" and "blcfill" are instructions analogous
3147 to "blsi", "blsic", "blsr", "blsmsk" and "blsfill" respectively, but they
3148 perform the bit-inverted versions of the same operations. They follow the
3149 same rules for operands as the instructions they reflect.
3150 "tzmsk" finds the lowest set bit in value from source operand, sets all bits
3151 below it to 1 and all the rest of bits to zero, then writes the result to
3152 destination. "t1mskc" finds the least significant zero bit in the value from
3153 source operand, sets the bits below it to zero and all the other bits to 1,
3154 and writes the result to destination. These instructions have the same rules
3155 for operands as "blsi".
3156
3157
3158 2.1.24 Other extensions of instruction set
3159
3160 There is a number of additional instruction set extensions recognized by flat
3161 assembler, and the general syntax of the instructions introduced by those
3162 extensions is provided here. For a detailed information on the operations
3163 performed by them, check out the manuals from Intel (for the VMX, SMX, XSAVE,
3164 RDRAND, FSGSBASE, INVPCID, HLE and RTM extensions) or AMD (for the SVM
3165 extension).
3166 The Virtual-Machine Extensions (VMX) provide a set of instructions for the
3167 management of virtual machines. The "vmxon" instruction, which enters the VMX
3168 operation, requires a single 64-bit memory operand, which should be a physical
3169 address of memory region, which the logical processor may use to support VMX
3170 operation. The "vmxoff" instruction, which leaves the VMX operation, has no
3171 operands. The "vmlaunch" and "vmresume", which launch or resume the virtual
3172 machines, and "vmcall", which allows guest software to call the VM monitor,
3173 use no operands either.
3174 The "vmptrld" loads the physical address of current Virtual Machine Control
3175 Structure (VMCS) from its memory operand, "vmptrst" stores the pointer to
3176 current VMCS into address specified by its memory operand, and "vmclear" sets
3177 the launch state of the VMCS referenced by its memory operand to clear. These
3178 three instruction all require single 64-bit memory operand.
3179 The "vmread" reads from VCMS a field specified by the source operand and
3180 stores it into the destination operand. The source operand should be a
3181 general purpose register, and the destination operand can be a register of
3182 memory. The "vmwrite" writes into a VMCS field specified by the destination
3183 operand the value provided by source operand. The source operand can be a
3184 general purpose register or memory, and the destination operand must be a
3185 register. The size of operands for those instructions should be 64-bit when
3186 in long mode, and 32-bit otherwise.
3187 The "invept" and "invvpid" invalidate the translation lookaside buffers
3188 (TLBs) and paging-structure caches, either derived from extended page tables
3189 (EPT), or based on the virtual processor identifier (VPID). These instructions
3190 require two operands, the first one being the general purpose register
3191 specifying the type of invalidation, and the second one being a 128-bit
3192 memory operand providing the invalidation descriptor. The first operand
3193 should be a 64-bit register when in long mode, and 32-bit register otherwise.
3194 The Safer Mode Extensions (SMX) provide the functionalities available
3195 throught the "getsec" instruction. This instruction takes no operands, and
3196 the function that is executed is determined by the contents of EAX register
3197 upon executing this instruction.
3198 The Secure Virtual Machine (SVM) is a variant of virtual machine extension
3199 used by AMD. The "skinit" instruction securely reinitializes the processor
3200 allowing the startup of trusted software, such as the virtual machine monitor
3201 (VMM). This instruction takes a single operand, which must be EAX, and
3202 provides a physical address of the secure loader block (SLB).
3203 The "vmrun" instruction is used to start a guest virtual machine,
3204 its only operand should be an accumulator register (AX, EAX or RAX, the
3205 last one available only in long mode) providing the physical address of the
3206 virtual machine control block (VMCB). The "vmsave" stores a subset of
3207 processor state into VMCB specified by its operand, and "vmload" loads the
3208 same subset of processor state from a specified VMCB. The same operand rules
3209 as for the "vmrun" apply to those two instructions.
3210 "vmmcall" allows the guest software to call the VMM. This instruction takes
3211 no operands.
3212 "stgi" set the global interrupt flag to 1, and "clgi" zeroes it. These
3213 instructions take no operands.
3214 "invlpga" invalidates the TLB mapping for a virtual page specified by the
3215 first operand (which has to be accumulator register) and address space
3216 identifier specified by the second operand (which must be ECX register).
3217 The XSAVE set of instructions allows to save and restore processor state
3218 components. "xsave" and "xsaveopt" store the components of processor state
3219 defined by bit mask in EDX and EAX registers into area defined by memory
3220 operand. "xrstor" restores from the area specified by memory operand the
3221 components of processor state defined by mask in EDX and EAX. The "xsave64",
3222 "xsaveopt64" and "xrstor64" are 64-bit versions of these instructions, allowed
3223 only in long mode.
3224 "xgetbv" read the contents of 64-bit XCR (extended control register)
3225 specified in ECX register into EDX and EAX registers. "xsetbv" writes the
3226 contents of EDX and EAX into the 64-bit XCR specified by ECX register. These
3227 instructions have no operands.
3228 The RDRAND extension introduces one new instruction, "rdrand", which loads
3229 the hardware-generated random value into general register. It takes one
3230 operand, which can be 16-bit, 32-bit or 64-bit register (with the last one
3231 being allowed only in long mode).
3232 The FSGSBASE extension adds long mode instructions that allow to read and
3233 write the segment base registers for FS and GS segments. "rdfsbase" and
3234 "rdgsbase" read the corresponding segment base registers into operand, while
3235 "wrfsbase" and "wrgsbase" write the value of operand into those register.
3236 All these instructions take one operand, which can be 32-bit or 64-bit general
3237 register.
3238 The INVPCID extension adds "invpcid" instruction, which invalidates mapping
3239 in the TLBs and paging caches based on the invalidation type specified in
3240 first operand and PCID invalidate descriptor specified in second operand.
3241 The first operands should be 32-bit general register when not in long mode,
3242 or 64-bit general register when in long mode. The second operand should be
3243 128-bit memory location.
3244 The HLE and RTM extensions provide set of instructions for the transactional
3245 management. The "xacquire" and "xrelease" are new prefixes that can be used
3246 with some of the instructions to start or end lock elision on the memory
3247 address specified by prefixed instruction. The "xbegin" instruction starts
3248 the transactional execution, its operand is the address a fallback routine
3249 that gets executes in case of transaction abort, specified like the operand
3250 for near jump instruction. "xend" marks the end of transcational execution
3251 region, it takes no operands. "xabort" forces the transaction abort, it takes
3252 an 8-bit immediate value as its only operand, this value is passed in the
3253 highest bits of EAX to the fallback routine. "xtest" checks whether there is
3254 transactional execution in progress, this instruction takes no operands.
3255
3256
3257 2.2 Control directives
3258
3259 This section describes the directives that control the assembly process, they
3260 are processed during the assembly and may cause some blocks of instructions
3261 to be assembled differently or not assembled at all.
3262
3263
3264 2.2.1 Numerical constants
3265
3266 The "=" directive allows to define the numerical constant. It should be
3267 preceded by the name for the constant and followed by the numerical expression
3268 providing the value. The value of such constants can be a number or an address,
3269 but - unlike labels - the numerical constants are not allowed to hold the
3270 register-based addresses. Besides this difference, in their basic variant
3271 numerical constants behave very much like labels and you can even
3272 forward-reference them (access their values before they actually get defined).
3273 There is, however, a second variant of numerical constants, which is
3274 recognized by assembler when you try to define the constant of name, under
3275 which there already was a numerical constant defined. In such case assembler
3276 treats that constant as an assembly-time variable and allows it to be assigned
3277 with new value, but forbids forward-referencing it (for obvious reasons). Let's
3278 see both the variant of numerical constants in one example:
3279
3280 dd sum
3281 x = 1
3282 x = x+2
3283 sum = x
3284
3285 Here the "x" is an assembly-time variable, and every time it is accessed, the
3286 value that was assigned to it the most recently is used. Thus if we tried to
3287 access the "x" before it gets defined the first time, like if we wrote "dd x"
3288 in place of the "dd sum" instruction, it would cause an error. And when it is
3289 re-defined with the "x = x+2" directive, the previous value of "x" is used to
3290 calculate the new one. So when the "sum" constant gets defined, the "x" has
3291 value of 3, and this value is assigned to the "sum". Since this one is defined
3292 only once in source, it is the standard numerical constant, and can be
3293 forward-referenced. So the "dd sum" is assembled as "dd 3". To read more about
3294 how the assembler is able to resolve this, see section 2.2.6.
3295 The value of numerical constant can be preceded by size operator, which can
3296 ensure that the value will fit in the range for the specified size, and can
3297 affect also how some of the calculations inside the numerical expression are
3298 performed. This example:
3299
3300 c8 = byte -1
3301 c32 = dword -1
3302
3303 defines two different constants, the first one fits in 8 bits, the second one
3304 fits in 32 bits.
3305 When you need to define constant with the value of address, which may be
3306 register-based (and thus you cannot employ numerical constant for this
3307 purpose), you can use the extended syntax of "label" directive (already
3308 described in section 1.2.3), like:
3309
3310 label myaddr at ebp+4
3311
3312 which declares label placed at "ebp+4" address. However remember that labels,
3313 unlike numerical constants, cannot become assembly-time variables.
3314
3315
3316 2.2.2 Conditional assembly
3317
3318 "if" directive causes some block of instructions to be assembled only under
3319 certain condition. It should be followed by logical expression specifying the
3320 condition, instructions in next lines will be assembled only when this
3321 condition is met, otherwise they will be skipped. The optional "else if"
3322 directive followed with logical expression specifying additional condition
3323 begins the next block of instructions that will be assembled if previous
3324 conditions were not met, and the additional condition is met. The optional
3325 "else" directive begins the block of instructions that will be assembled if
3326 all the conditions were not met. The "end if" directive ends the last block of
3327 instructions.
3328 You should note that "if" directive is processed at assembly stage and
3329 therefore it doesn't affect any preprocessor directives, like the definitions
3330 of symbolic constants and macroinstructions - when the assembler recognizes the
3331 "if" directive, all the preprocessing has been already finished.
3332 The logical expression consist of logical values and logical operators. The
3333 logical operators are "~" for logical negation, "&" for logical and, "|" for
3334 logical or. The negation has the highest priority. Logical value can be a
3335 numerical expression, it will be false if it is equal to zero, otherwise it
3336 will be true. Two numerical expression can be compared using one of the
3337 following operators to make the logical value: "=" (equal), "<" (less),
3338 ">" (greater), "<=" (less or equal), ">=" (greater or equal),
3339 "<>" (not equal).
3340 The "used" operator followed by a symbol name, is the logical value that
3341 checks whether the given symbol is used somewhere (it returns correct result
3342 even if symbol is used only after this check). The "defined" operator can be
3343 followed by any expression, usually just by a single symbol name; it checks
3344 whether the given expression contains only symbols that are defined in the
3345 source and accessible from the current position.
3346 With "relativeto" operator it is possible to check whether values of two
3347 expressions differ only by constant amount. The valid syntax is a numerical
3348 expression followed by "relativeto" and then another expression (possibly
3349 register-based). Labels that have no simple numerical value can be tested
3350 this way to determine what kind of operations may be possible with them.
3351 The following simple example uses the "count" constant that should be
3352 defined somewhere in source:
3353
3354 if count>0
3355 mov cx,count
3356 rep movsb
3357 end if
3358
3359 These two assembly instructions will be assembled only if the "count" constant
3360 is greater than 0. The next sample shows more complex conditional structure:
3361
3362 if count & ~ count mod 4
3363 mov cx,count/4
3364 rep movsd
3365 else if count>4
3366 mov cx,count/4
3367 rep movsd
3368 mov cx,count mod 4
3369 rep movsb
3370 else
3371 mov cx,count
3372 rep movsb
3373 end if
3374
3375 The first block of instructions gets assembled when the "count" is non zero and
3376 divisible by four, if this condition is not met, the second logical expression,
3377 which follows the "else if", is evaluated and if it's true, the second block
3378 of instructions get assembled, otherwise the last block of instructions, which
3379 follows the line containing only "else", is assembled.
3380 There are also operators that allow comparison of values being any chains of
3381 symbols. The "eq" compares whether two such values are exactly the same.
3382 The "in" operator checks whether given value is a member of the list of values
3383 following this operator, the list should be enclosed between "<" and ">"
3384 characters, its members should be separated with commas. The symbols are
3385 considered the same when they have the same meaning for the assembler - for
3386 example "pword" and "fword" for assembler are the same and thus are not
3387 distinguished by the above operators. In the same way "16 eq 10h" is the true
3388 condition, however "16 eq 10+4" is not.
3389 The "eqtype" operator checks whether the two compared values have the same
3390 structure, and whether the structural elements are of the same type. The
3391 distinguished types include numerical expressions, individual quoted strings,
3392 floating point numbers, address expressions (the expressions enclosed in square
3393 brackets or preceded by "ptr" operator), instruction mnemonics, registers, size
3394 operators, jump type and code type operators. And each of the special
3395 characters that act as a separators, like comma or colon, is the separate type
3396 itself. For example, two values, each one consisting of register name followed
3397 by comma and numerical expression, will be regarded as of the same type, no
3398 matter what kind of register and how complicated numerical expression is used;
3399 with exception for the quoted strings and floating point values, which are the
3400 special kinds of numerical expressions and are treated as different types. Thus
3401 "eax,16 eqtype fs,3+7" condition is true, but "eax,16 eqtype eax,1.6" is false.
3402
3403
3404 2.2.3 Repeating blocks of instructions
3405
3406 "times" directive repeats one instruction specified number of times. It
3407 should be followed by numerical expression specifying number of repeats and
3408 the instruction to repeat (optionally colon can be used to separate number and
3409 instruction). When special symbol "%" is used inside the instruction, it is
3410 equal to the number of current repeat. For example "times 5 db %" will define
3411 five bytes with values 1, 2, 3, 4, 5. Recursive use of "times" directive is
3412 also allowed, so "times 3 times % db %" will define six bytes with values
3413 1, 1, 2, 1, 2, 3.
3414 "repeat" directive repeats the whole block of instructions. It should be
3415 followed by numerical expression specifying number of repeats. Instructions
3416 to repeat are expected in next lines, ended with the "end repeat" directive,
3417 for example:
3418
3419 repeat 8
3420 mov byte [bx],%
3421 inc bx
3422 end repeat
3423
3424 The generated code will store byte values from one to eight in the memory
3425 addressed by BX register.
3426 Number of repeats can be zero, in that case the instructions are not
3427 assembled at all.
3428 The "break" directive allows to stop repeating earlier and continue assembly
3429 from the first line after the "end repeat". Combined with the "if" directive it
3430 allows to stop repeating under some special condition, like:
3431
3432 s = x/2
3433 repeat 100
3434 if x/s = s
3435 break
3436 end if
3437 s = (s+x/s)/2
3438 end repeat
3439
3440 The "while" directive repeats the block of instructions as long as the
3441 condition specified by the logical expression following it is true. The block
3442 of instructions to be repeated should end with the "end while" directive.
3443 Before each repetition the logical expression is evaluated and when its value
3444 is false, the assembly is continued starting from the first line after the
3445 "end while". Also in this case the "%" symbol holds the number of current
3446 repeat. The "break" directive can be used to stop this kind of loop in the same
3447 way as with "repeat" directive. The previous sample can be rewritten to use the
3448 "while" instead of "repeat" this way:
3449
3450 s = x/2
3451 while x/s <> s
3452 s = (s+x/s)/2
3453 if % = 100
3454 break
3455 end if
3456 end while
3457
3458 The blocks defined with "if", "repeat" and "while" can be nested in any
3459 order, however they should be closed in the same order in which they were
3460 started. The "break" directive always stops processing the block that was
3461 started last with either the "repeat" or "while" directive.
3462
3463
3464 2.2.4 Addressing spaces
3465
3466 "org" directive sets address at which the following code is expected to
3467 appear in memory. It should be followed by numerical expression specifying
3468 the address. This directive begins the new addressing space, the following
3469 code itself is not moved in any way, but all the labels defined within it
3470 and the value of "$" symbol are affected as if it was put at the given
3471 address. However it's the responsibility of programmer to put the code at
3472 correct address at run-time.
3473 The "load" directive allows to define constant with a binary value loaded
3474 from the already assembled code. This directive should be followed by the name
3475 of the constant, then optionally size operator, then "from" operator and a
3476 numerical expression specifying a valid address in current addressing space.
3477 The size operator has unusual meaning in this case - it states how many bytes
3478 (up to 8) have to be loaded to form the binary value of constant. If no size
3479 operator is specified, one byte is loaded (thus value is in range from 0 to
3480 255). The loaded data cannot exceed current offset.
3481 The "store" directive can modify the already generated code by replacing
3482 some of the previously generated data with the value defined by given
3483 numerical expression, which follows. The expression can be preceded by the
3484 optional size operator to specify how large value the expression defines, and
3485 therefore how much bytes will be stored, if there is no size operator, the
3486 size of one byte is assumed. Then the "at" operator and the numerical
3487 expression defining the valid address in current addressing code space, at
3488 which the given value have to be stored should follow. This is a directive for
3489 advanced appliances and should be used carefully.
3490 Both "load" and "store" directives in their basic variant (defined above)
3491 are limited to operate on places in current addressing space. The "$$" symbol
3492 is always equal to the base address of current addressing space, and the "$"
3493 symbol is the address of current position in that addressing space, therefore
3494 these two values define limits of the area, where "load" and "store" can
3495 operate.
3496 Combining the "load" and "store" directives allows to do things like encoding
3497 some of the already generated code. For example to encode the whole code
3498 generated in current addressing space you can use such block of directives:
3499
3500 repeat $-$$
3501 load a byte from $$+%-1
3502 store byte a xor c at $$+%-1
3503 end repeat
3504
3505 and each byte of code will be xored with the value defined by "c" constant.
3506 "virtual" defines virtual data at specified address. This data will not be
3507 included in the output file, but labels defined there can be used in other
3508 parts of source. This directive can be followed by "at" operator and the
3509 numerical expression specifying the address for virtual data, otherwise is
3510 uses current address, the same as "virtual at $". Instructions defining data
3511 are expected in next lines, ended with "end virtual" directive. The block of
3512 virtual instructions itself is an independent addressing space, after it's
3513 ended, the context of previous addressing space is restored.
3514 The "virtual" directive can be used to create union of some variables, for
3515 example:
3516
3517 GDTR dp ?
3518 virtual at GDTR
3519 GDT_limit dw ?
3520 GDT_address dd ?
3521 end virtual
3522
3523 It defines two labels for parts of the 48-bit variable at "GDTR" address.
3524 It can be also used to define labels for some structures addressed by a
3525 register, for example:
3526
3527 virtual at bx
3528 LDT_limit dw ?
3529 LDT_address dd ?
3530 end virtual
3531
3532 With such definition instruction "mov ax,[LDT_limit]" will be assembled
3533 to the same instruction as "mov ax,[bx]".
3534 Declaring defined data values or instructions inside the virtual block could
3535 also be useful, because the "load" directive may be used to load the values
3536 from the virtually generated code into a constants. This directive in its basic
3537 version should be used after the code it loads but before the virtual block
3538 ends, because it can only load the values from the same addressing space. For
3539 example:
3540
3541 virtual at 0
3542 xor eax,eax
3543 and edx,eax
3544 load zeroq dword from 0
3545 end virtual
3546
3547 The above piece of code will define the "zeroq" constant containing four bytes
3548 of the machine code of the instructions defined inside the virtual block.
3549 This method can be also used to load some binary value from external file.
3550 For example this code:
3551
3552 virtual at 0
3553 file 'a.txt':10h,1
3554 load char from 0
3555 end virtual
3556
3557 loads the single byte from offset 10h in file "a.txt" into the "char"
3558 constant.
3559 Any of the "section" directives described in 2.4 also begins a new
3560 addressing space.
3561 It is possible to declare a special kind of label that marks the current
3562 addressing space, by appending a double colon instead of a single one after a
3563 label name. This symbol cannot then be used in numerical expressions, the only
3564 place where it is allowed to use it is the extended syntax of "load" and
3565 "store" directives. It is possible to make these directives operate on a
3566 different addressing space than the current one, by specifying address with
3567 the two components: first the name of a special label that marks the
3568 addressing space, followed by the colon character and a numerical expression
3569 defining a valid address inside that addressing space. In the following
3570 example this extended syntax is used to load the value from a block after it
3571 has been closed:
3572
3573 virtual at 0
3574 hex_digits::
3575 db '0123456789ABCDEF'
3576 end virtual
3577 load a byte from hex_digits:10
3578
3579 This way it is possible to operate on values inside any code block,
3580 including all the ones defined with "virtual". However it is not allowed to
3581 specify addressing space that has not been assembled yet, just as it is not
3582 allowed to specify an address in the current addressing space that exceeds
3583 the current offset. The addresses in any other addressing space are also
3584 limited by the boundaries of the block.
3585
3586
3587 2.2.5 Other directives
3588
3589 "align" directive aligns code or data to the specified boundary. It should
3590 be followed by a numerical expression specifying the number of bytes, to the
3591 multiply of which the current address has to be aligned. The boundary value
3592 has to be the power of two.
3593 The "align" directive fills the bytes that had to be skipped to perform the
3594 alignment with the "nop" instructions and at the same time marks this area as
3595 uninitialized data, so if it is placed among other uninitialized data that
3596 wouldn't take space in the output file, the alignment bytes will act the same
3597 way. If you need to fill the alignment area with some other values, you can
3598 combine "align" with "virtual" to get the size of alignment needed and then
3599 create the alignment yourself, like:
3600
3601 virtual
3602 align 16
3603 a = $ - $$
3604 end virtual
3605 db a dup 0
3606
3607 The "a" constant is defined to be the difference between address after
3608 alignment and address of the "virtual" block (see previous section), so it is
3609 equal to the size of needed alignment space.
3610 "display" directive displays the message at the assembly time. It should
3611 be followed by the quoted strings or byte values, separated with commas. It
3612 can be used to display values of some constants, for example:
3613
3614 bits = 16
3615 display 'Current offset is 0x'
3616 repeat bits/4
3617 d = '0' + $ shr (bits-%*4) and 0Fh
3618 if d > '9'
3619 d = d + 'A'-'9'-1
3620 end if
3621 display d
3622 end repeat
3623 display 13,10
3624
3625 This block of directives calculates the four hexadecimal digits of 16-bit
3626 value and converts them into characters for displaying. Note that this will
3627 not work if the adresses in current addressing space are relocatable (as it
3628 might happen with PE or object output formats), since only absolute values can
3629 be used this way. The absolute value may be obtained by calculating the
3630 relative address, like "$-$$", or "rva $" in case of PE format.
3631 The "err" directive immediately terminates the assembly process when it is
3632 encountered by assembler.
3633 The "assert" directive tests whether the logical expression that follows it
3634 is true, and if not, it signalizes the error.
3635
3636
3637 2.2.6 Multiple passes
3638
3639 Because the assembler allows to reference some of the labels or constants
3640 before they get actually defined, it has to predict the values of such labels
3641 and if there is even a suspicion that prediction failed in at least one case,
3642 it does one more pass, assembling the whole source, this time doing better
3643 prediction based on the values the labels got in the previous pass.
3644 The changing values of labels can cause some instructions to have encodings
3645 of different length, and this can cause the change in values of labels again.
3646 And since the labels and constants can also be used inside the expressions that
3647 affect the behavior of control directives, the whole block of source can be
3648 processed completely differently during the new pass. Thus the assembler does
3649 more and more passes, each time trying to do better predictions to approach
3650 the final solution, when all the values get predicted correctly. It uses
3651 various method for predicting the values, which has been chosen to allow
3652 finding in a few passes the solution of possibly smallest length for the most
3653 of the programs.
3654 Some of the errors, like the values not fitting in required boundaries, are
3655 not signaled during those intermediate passes, since it may happen that when
3656 some of the values are predicted better, these errors will disappear. However
3657 if assembler meets some illegal syntax construction or unknown instruction, it
3658 always stops immediately. Also defining some label more than once causes such
3659 error, because it makes the predictions groundless.
3660 Only the messages created with the "display" directive during the last
3661 performed pass get actually displayed. In case when the assembly has been
3662 stopped due to an error, these messages may reflect the predicted values that
3663 are not yet resolved correctly.
3664 The solution may sometimes not exist and in such cases the assembler will
3665 never manage to make correct predictions - for this reason there is a limit for
3666 a number of passes, and when assembler reaches this limit, it stops and
3667 displays the message that it is not able to generate the correct output.
3668 Consider the following example:
3669
3670 if ~ defined alpha
3671 alpha:
3672 end if
3673
3674 The "defined" operator gives the true value when the expression following it
3675 could be calculated in this place, what in this case means that the "alpha"
3676 label is defined somewhere. But the above block causes this label to be defined
3677 only when the value given by "defined" operator is false, what leads to an
3678 antynomy and makes it impossible to resolve such code. When processing the "if"
3679 directive assembler has to predict whether the "alpha" label will be defined
3680 somewhere (it wouldn't have to predict only if the label was already defined
3681 earlier in this pass), and whatever the prediction is, the opposite always
3682 happens. Thus the assembly will fail, unless the "alpha" label is defined
3683 somewhere in source preceding the above block of instructions - in such case,
3684 as it was already noted, the prediction is not needed and the block will just
3685 get skipped.
3686 The above sample might have been written as a try to define the label only
3687 when it was not yet defined. It fails, because the "defined" operator does
3688 check whether the label is defined anywhere, and this includes the definition
3689 inside this conditionally processed block. However adding some additional
3690 condition may make it possible to get it resolved:
3691
3692 if ~ defined alpha | defined @f
3693 alpha:
3694 @@:
3695 end if
3696
3697 The "@f" is always the same label as the nearest "@@" symbol in the source
3698 following it, so the above sample would mean the same if any unique name was
3699 used instead of the anonymous label. When "alpha" is not defined in any other
3700 place in source, the only possible solution is when this block gets defined,
3701 and this time this doesn't lead to the antynomy, because of the anonymous
3702 label which makes this block self-establishing. To better understand this,
3703 look at the blocks that has nothing more than this self-establishing:
3704
3705 if defined @f
3706 @@:
3707 end if
3708
3709 This is an example of source that may have more than one solution, as both
3710 cases when this block gets processed or not are equally correct. Which one of
3711 those two solutions we get depends on the algorithm on the assembler, in case
3712 of flat assembler - on the algorithm of predictions. Back to the previous
3713 sample, when "alpha" is not defined anywhere else, the condition for "if" block
3714 cannot be false, so we are left with only one possible solution, and we can
3715 hope the assembler will arrive at it. On the other hand, when "alpha" is
3716 defined in some other place, we've got two possible solutions again, but one of
3717 them causes "alpha" to be defined twice, and such an error causes assembler to
3718 abort the assembly immediately, as this is the kind of error that deeply
3719 disturbs the process of resolving. So we can get such source either correctly
3720 resolved or causing an error, and what we get may depend on the internal
3721 choices made by the assembler.
3722 However there are some facts about such choices that are certain. When
3723 assembler has to check whether the given symbol is defined and it was already
3724 defined in the current pass, no prediction is needed - it was already noted
3725 above. And when the given symbol has been defined never before, including all
3726 the already finished passes, the assembler predicts it to be not defined.
3727 Knowing this, we can expect that the simple self-establishing block shown
3728 above will not be assembled at all and that the previous sample will resolve
3729 correctly when "alpha" is defined somewhere before our conditional block,
3730 while it will itself define "alpha" when it's not already defined earlier, thus
3731 potentially causing the error because of double definition if the "alpha" is
3732 also defined somewhere later.
3733 The "used" operator may be expected to behave in a similar manner in
3734 analogous cases, however any other kinds of predictions may not be so simple and
3735 you should never rely on them this way.
3736 The "err" directive, usually used to stop the assembly when some condition is
3737 met, stops the assembly immediately, regardless of whether the current pass
3738 is final or intermediate. So even when the condition that caused this directive
3739 to be interpreted is mispredicted and temporary, and would eventually disappear
3740 in the later passes, the assembly is stopped anyway.
3741 The "assert" directive signalizes the error only if its expression is false
3742 after all the symbols have been resolved. You can use "assert 0" in place of
3743 "err" when you do not want to have assembly stopped during the intermediate
3744 passes.
3745
3746
3747 2.3 Preprocessor directives
3748
3749 All preprocessor directives are processed before the main assembly process,
3750 and therefore are not affected by the control directives. At this time also
3751 all comments are stripped out.
3752
3753
3754 2.3.1 Including source files
3755
3756 "include" directive includes the specified source file at the position where
3757 it is used. It should be followed by the quoted name of file that should be
3758 included, for example:
3759
3760 include 'macros.inc'
3761
3762 The whole included file is preprocessed before preprocessing the lines next
3763 to the line containing the "include" directive. There are no limits to the
3764 number of included files as long as they fit in memory.
3765 The quoted path can contain environment variables enclosed within "%"
3766 characters, they will be replaced with their values inside the path, both the
3767 "\" and "/" characters are allowed as a path separators. The file is first
3768 searched for in the directory containing file which included it and when it is
3769 not found there, the search is continued in the directories specified in the
3770 environment variable called INCLUDE (the multiple paths separated with
3771 semicolons can be defined there, they will be searched in the same order as
3772 specified). If file was not found in any of these places, preprocessor looks
3773 for it in the directory containing the main source file (the one specified in
3774 command line). These rules concern also paths given with the "file" directive.
3775
3776
3777 2.3.2 Symbolic constants
3778
3779 The symbolic constants are different from the numerical constants, before the
3780 assembly process they are replaced with their values everywhere in source
3781 lines after their definitions, and anything can become their values.
3782 The definition of symbolic constant consists of name of the constant
3783 followed by the "equ" directive. Everything that follows this directive will
3784 become the value of constant. If the value of symbolic constant contains
3785 other symbolic constants, they are replaced with their values before assigning
3786 this value to the new constant. For example:
3787
3788 d equ dword
3789 NULL equ d 0
3790 d equ edx
3791
3792 After these three definitions the value of "NULL" constant is "dword 0" and
3793 the value of "d" is "edx". So, for example, "push NULL" will be assembled as
3794 "push dword 0" and "push d" will be assembled as "push edx". And if then the
3795 following line was put:
3796
3797 d equ d,eax
3798
3799 the "d" constant would get the new value of "edx,eax". This way the growing
3800 lists of symbols can be defined.
3801 "restore" directive allows to get back previous value of redefined symbolic
3802 constant. It should be followed by one more names of symbolic constants,
3803 separated with commas. So "restore d" after the above definitions will give
3804 "d" constant back the value "edx", the second one will restore it to value
3805 "dword", and one more will revert "d" to original meaning as if no such
3806 constant was defined. If there was no constant defined of given name,
3807 "restore" will not cause an error, it will be just ignored.
3808 Symbolic constant can be used to adjust the syntax of assembler to personal
3809 preferences. For example the following set of definitions provides the handy
3810 shortcuts for all the size operators:
3811
3812 b equ byte
3813 w equ word
3814 d equ dword
3815 p equ pword
3816 f equ fword
3817 q equ qword
3818 t equ tword
3819 x equ dqword
3820 y equ qqword
3821
3822 Because symbolic constant may also have an empty value, it can be used to
3823 allow the syntax with "offset" word before any address value:
3824
3825 offset equ
3826
3827 After this definition "mov ax,offset char" will be valid construction for
3828 copying the offset of "char" variable into "ax" register, because "offset" is
3829 replaced with an empty value, and therefore ignored.
3830 The "define" directive followed by the name of constant and then the value,
3831 is the alternative way of defining symbolic constant. The only difference
3832 between "define" and "equ" is that "define" assigns the value as it is, it does
3833 not replace the symbolic constants with their values inside it.
3834 Symbolic constants can also be defined with the "fix" directive, which has
3835 the same syntax as "equ", but defines constants of high priority - they are
3836 replaced with their symbolic values even before processing the preprocessor
3837 directives and macroinstructions, the only exception is "fix" directive
3838 itself, which has the highest possible priority, so it allows redefinition of
3839 constants defined this way.
3840 The "fix" directive can be used for syntax adjustments related to directives
3841 of preprocessor, what cannot be done with "equ" directive. For example:
3842
3843 incl fix include
3844
3845 defines a short name for "include" directive, while the similar definition done
3846 with "equ" directive wouldn't give such result, as standard symbolic constants
3847 are replaced with their values after searching the line for preprocessor
3848 directives.
3849
3850
3851 2.3.3 Macroinstructions
3852
3853 "macro" directive allows you to define your own complex instructions, called
3854 macroinstructions, using which can greatly simplify the process of
3855 programming. In its simplest form it's similar to symbolic constant
3856 definition. For example the following definition defines a shortcut for the
3857 "test al,0xFF" instruction:
3858
3859 macro tst {test al,0xFF}
3860
3861 After the "macro" directive there is a name of macroinstruction and then its
3862 contents enclosed between the "{" and "}" characters. You can use "tst"
3863 instruction anywhere after this definition and it will be assembled as
3864 "test al,0xFF". Defining symbolic constant "tst" of that value would give the
3865 similar result, but the difference is that the name of macroinstruction is
3866 recognized only as an instruction mnemonic. Also, macroinstructions are
3867 replaced with corresponding code even before the symbolic constants are
3868 replaced with their values. So if you define macroinstruction and symbolic
3869 constant of the same name, and use this name as an instruction mnemonic, it
3870 will be replaced with the contents of macroinstruction, but it will be
3871 replaced with value if symbolic constant if used somewhere inside the
3872 operands.
3873 The definition of macroinstruction can consist of many lines, because
3874 "{" and "}" characters don't have to be in the same line as "macro" directive.
3875 For example:
3876
3877 macro stos0
3878 {
3879 xor al,al
3880 stosb
3881 }
3882
3883 The macroinstruction "stos0" will be replaced with these two assembly
3884 instructions anywhere it's used.
3885 Like instructions which needs some number of operands, the macroinstruction
3886 can be defined to need some number of arguments separated with commas. The
3887 names of needed argument should follow the name of macroinstruction in the
3888 line of "macro" directive and should be separated with commas if there is more
3889 than one. Anywhere one of these names occurs in the contents of
3890 macroinstruction, it will be replaced with corresponding value, provided when
3891 the macroinstruction is used. Here is an example of a macroinstruction that
3892 will do data alignment for binary output format:
3893
3894 macro align value { rb (value-1)-($+value-1) mod value }
3895
3896 When the "align 4" instruction is found after this macroinstruction is
3897 defined, it will be replaced with contents of this macroinstruction, and the
3898 "value" will there become 4, so the result will be "rb (4-1)-($+4-1) mod 4".
3899 If a macroinstruction is defined that uses an instruction with the same name
3900 inside its definition, the previous meaning of this name is used. Useful
3901 redefinition of macroinstructions can be done in that way, for example:
3902
3903 macro mov op1,op2
3904 {
3905 if op1 in <ds,es,fs,gs,ss> & op2 in <cs,ds,es,fs,gs,ss>
3906 push op2
3907 pop op1
3908 else
3909 mov op1,op2
3910 end if
3911 }
3912
3913 This macroinstruction extends the syntax of "mov" instruction, allowing both
3914 operands to be segment registers. For example "mov ds,es" will be assembled as
3915 "push es" and "pop ds". In all other cases the standard "mov" instruction will
3916 be used. The syntax of this "mov" can be extended further by defining next
3917 macroinstruction of that name, which will use the previous macroinstruction:
3918
3919 macro mov op1,op2,op3
3920 {
3921 if op3 eq
3922 mov op1,op2
3923 else
3924 mov op1,op2
3925 mov op2,op3
3926 end if
3927 }
3928
3929 It allows "mov" instruction to have three operands, but it can still have two
3930 operands only, because when macroinstruction is given less arguments than it
3931 needs, the rest of arguments will have empty values. When three operands are
3932 given, this macroinstruction will become two macroinstructions of the previous
3933 definition, so "mov es,ds,dx" will be assembled as "push ds", "pop es" and
3934 "mov ds,dx".
3935 By placing the "*" after the name of argument you can mark the argument as
3936 required - preprocessor will not allow it to have an empty value. For example
3937 the above macroinstruction could be declared as "macro mov op1*,op2*,op3" to
3938 make sure that first two arguments will always have to be given some non empty
3939 values.
3940 Alternatively, you can provide the default value for argument, by placing
3941 the "=" followed by value after the name of argument. Then if the argument
3942 has an empty value provided, the default value will be used instead.
3943 When it's needed to provide macroinstruction with argument that contains
3944 some commas, such argument should be enclosed between "<" and ">" characters.
3945 If it contains more than one "<" character, the same number of ">" should be
3946 used to tell that the value of argument ends.
3947 "purge" directive allows removing the last definition of specified
3948 macroinstruction. It should be followed by one or more names of
3949 macroinstructions, separated with commas. If such macroinstruction has not
3950 been defined, you will not get any error. For example after having the syntax
3951 of "mov" extended with the macroinstructions defined above, you can disable
3952 syntax with three operands back by using "purge mov" directive. Next
3953 "purge mov" will disable also syntax for two operands being segment registers,
3954 and all the next such directives will do nothing.
3955 If after the "macro" directive you enclose some group of arguments' names in
3956 square brackets, it will allow giving more values for this group of arguments
3957 when using that macroinstruction. Any more argument given after the last
3958 argument of such group will begin the new group and will become the first
3959 argument of it. That's why after closing the square bracket no more argument
3960 names can follow. The contents of macroinstruction will be processed for each
3961 such group of arguments separately. The simplest example is to enclose one
3962 argument name in square brackets:
3963
3964 macro stoschar [char]
3965 {
3966 mov al,char
3967 stosb
3968 }
3969
3970 This macroinstruction accepts unlimited number of arguments, and each one
3971 will be processed into these two instructions separately. For example
3972 "stoschar 1,2,3" will be assembled as the following instructions:
3973
3974 mov al,1
3975 stosb
3976 mov al,2
3977 stosb
3978 mov al,3
3979 stosb
3980
3981 There are some special directives available only inside the definitions of
3982 macroinstructions. "local" directive defines local names, which will be
3983 replaced with unique values each time the macroinstruction is used. It should
3984 be followed by names separated with commas. If the name given as parameter to
3985 "local" directive begins with a dot or two dots, the unique labels generated
3986 by each evaluation of macroinstruction will have the same properties.
3987 This directive is usually needed for the constants or labels that
3988 macroinstruction defines and uses internally. For example:
3989
3990 macro movstr
3991 {
3992 local move
3993 move:
3994 lodsb
3995 stosb
3996 test al,al
3997 jnz move
3998 }
3999
4000 Each time this macroinstruction is used, "move" will become other unique name
4001 in its instructions, so you will not get an error you normally get when some
4002 label is defined more than once.
4003 "forward", "reverse" and "common" directives divide macroinstruction into
4004 blocks, each one processed after the processing of previous is finished. They
4005 differ in behavior only if macroinstruction allows multiple groups of
4006 arguments. Block of instructions that follows "forward" directive is processed
4007 for each group of arguments, from first to last - exactly like the default
4008 block (not preceded by any of these directives). Block that follows "reverse"
4009 directive is processed for each group of argument in reverse order - from last
4010 to first. Block that follows "common" directive is processed only once,
4011 commonly for all groups of arguments. Local name defined in one of the blocks
4012 is available in all the following blocks when processing the same group of
4013 arguments as when it was defined, and when it is defined in common block it is
4014 available in all the following blocks not depending on which group of
4015 arguments is processed.
4016 Here is an example of macroinstruction that will create the table of
4017 addresses to strings followed by these strings:
4018
4019 macro strtbl name,[string]
4020 {
4021 common
4022 label name dword
4023 forward
4024 local label
4025 dd label
4026 forward
4027 label db string,0
4028 }
4029
4030 First argument given to this macroinstruction will become the label for table
4031 of addresses, next arguments should be the strings. First block is processed
4032 only once and defines the label, second block for each string declares its
4033 local name and defines the table entry holding the address to that string.
4034 Third block defines the data of each string with the corresponding label.
4035 The directive starting the block in macroinstruction can be followed by the
4036 first instruction of this block in the same line, like in the following
4037 example:
4038
4039 macro stdcall proc,[arg]
4040 {
4041 reverse push arg
4042 common call proc
4043 }
4044
4045 This macroinstruction can be used for calling the procedures using STDCALL
4046 convention, which has all the arguments pushed on stack in the reverse order.
4047 For example "stdcall foo,1,2,3" will be assembled as:
4048
4049 push 3
4050 push 2
4051 push 1
4052 call foo
4053
4054 If some name inside macroinstruction has multiple values (it is either one
4055 of the arguments enclosed in square brackets or local name defined in the
4056 block following "forward" or "reverse" directive) and is used in block
4057 following the "common" directive, it will be replaced with all of its values,
4058 separated with commas. For example the following macroinstruction will pass
4059 all of the additional arguments to the previously defined "stdcall"
4060 macroinstruction:
4061
4062 macro invoke proc,[arg]
4063 { common stdcall [proc],arg }
4064
4065 It can be used to call indirectly (by the pointer stored in memory) the
4066 procedure using STDCALL convention.
4067 Inside macroinstruction also special operator "#" can be used. This
4068 operator causes two names to be concatenated into one name. It can be useful,
4069 because it's done after the arguments and local names are replaced with their
4070 values. The following macroinstruction will generate the conditional jump
4071 according to the "cond" argument:
4072
4073 macro jif op1,cond,op2,label
4074 {
4075 cmp op1,op2
4076 j#cond label
4077 }
4078
4079 For example "jif ax,ae,10h,exit" will be assembled as "cmp ax,10h" and
4080 "jae exit" instructions.
4081 The "#" operator can be also used to concatenate two quoted strings into one.
4082 Also conversion of name into a quoted string is possible, with the "`" operator,
4083 which likewise can be used inside the macroinstruction. It converts the name
4084 that follows it into a quoted string - but note, that when it is followed by
4085 a macro argument which is being replaced with value containing more than one
4086 symbol, only the first of them will be converted, as the "`" operator converts
4087 only one symbol that immediately follows it. Here's an example of utilizing
4088 those two features:
4089
4090 macro label name
4091 {
4092 label name
4093 if ~ used name
4094 display `name # " is defined but not used.",13,10
4095 end if
4096 }
4097
4098 When label defined with such macro is not used in the source, macro will warn
4099 you with the message, informing to which label it applies.
4100 To make macroinstruction behaving differently when some of the arguments are
4101 of some special type, for example a quoted strings, you can use "eqtype"
4102 comparison operator. Here's an example of utilizing it to distinguish a
4103 quoted string from an other argument:
4104
4105 macro message arg
4106 {
4107 if arg eqtype ""
4108 local str
4109 jmp @f
4110 str db arg,0Dh,0Ah,24h
4111 @@:
4112 mov dx,str
4113 else
4114 mov dx,arg
4115 end if
4116 mov ah,9
4117 int 21h
4118 }
4119
4120 The above macro is designed for displaying messages in DOS programs. When the
4121 argument of this macro is some number, label, or variable, the string from
4122 that address is displayed, but when the argument is a quoted string, the
4123 created code will display that string followed by the carriage return and
4124 line feed.
4125 It is also possible to put a declaration of macroinstruction inside another
4126 macroinstruction, so one macro can define another, but there is a problem
4127 with such definitions caused by the fact, that "}" character cannot occur
4128 inside the macroinstruction, as it always means the end of definition. To
4129 overcome this problem, the escaping of symbols inside macroinstruction can be
4130 used. This is done by placing one or more backslashes in front of any other
4131 symbol (even the special character). Preprocessor sees such sequence as a
4132 single symbol, but each time it meets such symbol during the macroinstruction
4133 processing, it cuts the backslash character from the front of it. For example
4134 "\{" is treated as single symbol, but during processing of the macroinstruction
4135 it becomes the "{" symbol. This allows to put one definition of
4136 macroinstruction inside another:
4137
4138 macro ext instr
4139 {
4140 macro instr op1,op2,op3
4141 \{
4142 if op3 eq
4143 instr op1,op2
4144 else
4145 instr op1,op2
4146 instr op2,op3
4147 end if
4148 \}
4149 }
4150
4151 ext add
4152 ext sub
4153
4154 The macro "ext" is defined correctly, but when it is used, the "\{" and "\}"
4155 become the "{" and "}" symbols. So when the "ext add" is processed, the
4156 contents of macro becomes valid definition of a macroinstruction and this way
4157 the "add" macro becomes defined. In the same way "ext sub" defines the "sub"
4158 macro. The use of "\{" symbol wasn't really necessary here, but is done this
4159 way to make the definition more clear.
4160 If some directives specific to macroinstructions, like "local" or "common"
4161 are needed inside some macro embedded this way, they can be escaped in the same
4162 way. Escaping the symbol with more than one backslash is also allowed, which
4163 allows multiple levels of nesting the macroinstruction definitions.
4164 The another technique for defining one macroinstruction by another is to
4165 use the "fix" directive, which becomes useful when some macroinstruction only
4166 begins the definition of another one, without closing it. For example:
4167
4168 macro tmacro [params]
4169 {
4170 common macro params {
4171 }
4172
4173 MACRO fix tmacro
4174 ENDM fix }
4175
4176 defines an alternative syntax for defining macroinstructions, which looks like:
4177
4178 MACRO stoschar char
4179 mov al,char
4180 stosb
4181 ENDM
4182
4183 Note that symbol that has such customized definition must be defined with "fix"
4184 directive, because only the prioritized symbolic constants are processed before
4185 the preprocessor looks for the "}" character while defining the macro. This
4186 might be a problem if one needed to perform some additional tasks one the end
4187 of such definition, but there is one more feature which helps in such cases.
4188 Namely it is possible to put any directive, instruction or macroinstruction
4189 just after the "}" character that ends the macroinstruction and it will be
4190 processed in the same way as if it was put in the next line.
4191 The "postpone" directive can be used to define a special type of
4192 macroinstruction that has no name or arguments and will get automatically
4193 called when the preprocessor reaches the end of source:
4194
4195 postpone
4196 {
4197 code_size = $
4198 }
4199
4200 It is a very simplified kind of macroinstruction and it simply delegates a
4201 block of instructions to be put at the end.
4202
4203
4204 2.3.4 Structures
4205
4206 "struc" directive is a special variant of "macro" directive that is used to
4207 define data structures. Macroinstruction defined using the "struc" directive
4208 must be preceded by a label (like the data definition directive) when it's
4209 used. This label will be also attached at the beginning of every name starting
4210 with dot in the contents of macroinstruction. The macroinstruction defined
4211 using the "struc" directive can have the same name as some other
4212 macroinstruction defined using the "macro" directive, structure
4213 macroinstruction will not prevent the standard macroinstruction from being
4214 processed when there is no label before it and vice versa. All the rules and
4215 features concerning standard macroinstructions apply to structure
4216 macroinstructions.
4217 Here is the sample of structure macroinstruction:
4218
4219 struc point x,y
4220 {
4221 .x dw x
4222 .y dw y
4223 }
4224
4225 For example "my point 7,11" will define structure labeled "my", consisting of
4226 two variables: "my.x" with value 7 and "my.y" with value 11.
4227 If somewhere inside the definition of structure the name consisting of a
4228 single dot it found, it is replaced by the name of the label for the given
4229 instance of structure and this label will not be defined automatically in
4230 such case, allowing to completely customize the definition. The following
4231 example utilizes this feature to extend the data definition directive "db"
4232 with ability to calculate the size of defined data:
4233
4234 struc db [data]
4235 {
4236 common
4237 . db data
4238 .size = $ - .
4239 }
4240
4241 With such definition "msg db 'Hello!',13,10" will define also "msg.size"
4242 constant, equal to the size of defined data in bytes.
4243 Defining data structures addressed by registers or absolute values should be
4244 done using the "virtual" directive with structure macroinstruction
4245 (see 2.2.4).
4246 "restruc" directive removes the last definition of the structure, just like
4247 "purge" does with macroinstructions and "restore" with symbolic constants.
4248 It also has the same syntax - should be followed by one or more names of
4249 structure macroinstructions, separated with commas.
4250
4251
4252 2.3.5 Repeating macroinstructions
4253
4254 The "rept" directive is a special kind of macroinstruction, which makes given
4255 amount of duplicates of the block enclosed with braces. The basic syntax is
4256 "rept" directive followed by number and then block of source enclosed between
4257 the "{" and "}" characters. The simplest example:
4258
4259 rept 5 { in al,dx }
4260
4261 will make five duplicates of the "in al,dx" line. The block of instructions
4262 is defined in the same way as for the standard macroinstruction and any
4263 special operators and directives which can be used only inside
4264 macroinstructions are also allowed here. When the given count is zero, the
4265 block is simply skipped, as if you defined macroinstruction but never used
4266 it. The number of repetitions can be followed by the name of counter symbol,
4267 which will get replaced symbolically with the number of duplicate currently
4268 generated. So this:
4269
4270 rept 3 counter
4271 {
4272 byte#counter db counter
4273 }
4274
4275 will generate lines:
4276
4277 byte1 db 1
4278 byte2 db 2
4279 byte3 db 3
4280
4281 The repetition mechanism applied to "rept" blocks is the same as the one used
4282 to process multiple groups of arguments for macroinstructions, so directives
4283 like "forward", "common" and "reverse" can be used in their usual meaning.
4284 Thus such macroinstruction:
4285
4286 rept 7 num { reverse display `num }
4287
4288 will display digits from 7 to 1 as text. The "local" directive behaves in the
4289 same way as inside macroinstruction with multiple groups of arguments, so:
4290
4291 rept 21
4292 {
4293 local label
4294 label: loop label
4295 }
4296
4297 will generate unique label for each duplicate.
4298 The counter symbol by default counts from 1, but you can declare different
4299 base value by placing the number preceded by colon immediately after the name
4300 of counter. For example:
4301
4302 rept 8 n:0 { pxor xmm#n,xmm#n }
4303
4304 will generate code which will clear the contents of eight SSE registers.
4305 You can define multiple counters separated with commas, and each one can have
4306 different base.
4307 The number of repetitions and the base values for counters can be specified
4308 using the numerical expressions with operator rules identical as in the case
4309 of assembler. However each value used in such expression must either be a
4310 directly specified number, or a symbolic constant with value also being an
4311 expression that can be calculated by preprocessor (in such case the value
4312 of expression associated with symbolic constant is calculated first, and then
4313 substituted into the outer expression in place of that constant). If you need
4314 repetitions based on values that can only be calculated at assembly time, use
4315 one of the code repeating directives that are processed by assembler, see
4316 section 2.2.3.
4317 The "irp" directive iterates the single argument through the given list of
4318 parameters. The syntax is "irp" followed by the argument name, then the comma
4319 and then the list of parameters. The parameters are specified in the same
4320 way like in the invocation of standard macroinstruction, so they have to be
4321 separated with commas and each one can be enclosed with the "<" and ">"
4322 characters. Also the name of argument may be followed by "*" to mark that it
4323 cannot get an empty value. Such block:
4324
4325 irp value, 2,3,5
4326 { db value }
4327
4328 will generate lines:
4329
4330 db 2
4331 db 3
4332 db 5
4333
4334 The "irps" directive iterates through the given list of symbols, it should
4335 be followed by the argument name, then the comma and then the sequence of any
4336 symbols. Each symbol in this sequence, no matter whether it is the name
4337 symbol, symbol character or quoted string, becomes an argument value for one
4338 iteration. If there are no symbols following the comma, no iteration is done
4339 at all. This example:
4340
4341 irps reg, al bx ecx
4342 { xor reg,reg }
4343
4344 will generate lines:
4345
4346 xor al,al
4347 xor bx,bx
4348 xor ecx,ecx
4349
4350 The "irpv" directive iterates through all of the values that were assigned to
4351 the given symbolic variable. It should be followed by the argument name and
4352 the name of symbolic variable, separated with comma. When the symbolic
4353 variable is treated with "restore" directive to remove its latest value, that
4354 value is removed from the list of values accessed by "irpv". But any
4355 modifications made to that list during the iterations performed by "irpv" (by
4356 either defining a new value for symbolic variable, or destroying the value
4357 with "restore" directive) do not affect the operation performed by this
4358 directive - the list that gets iterated reflects the state of symbolic
4359 variable at the time when "irpv" directive was encountered. For example this
4360 snippet restores a symbolic variable called "d" to its initial state, before
4361 any values were assigned to it:
4362
4363 irpv value, d
4364 { restore d }
4365
4366 It simply generates as many copies of "restore" directive, as many values
4367 there are to remove.
4368 The blocks defined by the "irp", "irps" and "irpv" directives are also
4369 processed in the same way as any macroinstructions, so operators and
4370 directives specific to macroinstructions may be freely used also in this case.
4371
4372
4373 2.3.6 Conditional preprocessing
4374
4375 "match" directive causes some block of source to be preprocessed and passed
4376 to assembler only when the given sequence of symbols matches the specified
4377 pattern. The pattern comes first, ended with comma, then the symbols that have
4378 to be matched with the pattern, and finally the block of source, enclosed
4379 within braces as macroinstruction.
4380 There are the few rules for building the expression for matching, first is
4381 that any of symbol characters and any quoted string should be matched exactly
4382 as is. In this example:
4383
4384 match +,+ { include 'first.inc' }
4385 match +,- { include 'second.inc' }
4386
4387 the first file will get included, since "+" after comma matches the "+" in
4388 pattern, and the second file will not be included, since there is no match.
4389 To match any other symbol literally, it has to be preceded by "=" character
4390 in the pattern. Also to match the "=" character itself, or the comma, the
4391 "==" and "=," constructions have to be used. For example the "=a==" pattern
4392 will match the "a=" sequence.
4393 If some name symbol is placed in the pattern, it matches any sequence
4394 consisting of at least one symbol and then this name is replaced with the
4395 matched sequence everywhere inside the following block, analogously to the
4396 parameters of macroinstruction. For instance:
4397
4398 match a-b, 0-7
4399 { dw a,b-a }
4400
4401 will generate the "dw 0,7-0" instruction. Each name is always matched with
4402 as few symbols as possible, leaving the rest for the following ones, so in
4403 this case:
4404
4405 match a b, 1+2+3 { db a }
4406
4407 the "a" name will match the "1" symbol, leaving the "+2+3" sequence to be
4408 matched with "b". But in this case:
4409
4410 match a b, 1 { db a }
4411
4412 there will be nothing left for "b" to match, so the block will not get
4413 processed at all.
4414 The block of source defined by match is processed in the same way as any
4415 macroinstruction, so any operators specific to macroinstructions can be used
4416 also in this case.
4417 What makes "match" directive more useful is the fact, that it replaces the
4418 symbolic constants with their values in the matched sequence of symbols (that
4419 is everywhere after comma up to the beginning of the source block) before
4420 performing the match. Thanks to this it can be used for example to process
4421 some block of source under the condition that some symbolic constant has the
4422 given value, like:
4423
4424 match =TRUE, DEBUG { include 'debug.inc' }
4425
4426 which will include the file only when the symbolic constant "DEBUG" was
4427 defined with value "TRUE".
4428
4429
4430 2.3.7 Order of processing
4431
4432 When combining various features of the preprocessor, it's important to know
4433 the order in which they are processed. As it was already noted, the highest
4434 priority has the "fix" directive and the replacements defined with it. This
4435 is done completely before doing any other preprocessing, therefore this
4436 piece of source:
4437
4438 V fix {
4439 macro empty
4440 V
4441 V fix }
4442 V
4443
4444 becomes a valid definition of an empty macroinstruction. It can be interpreted
4445 that the "fix" directive and prioritized symbolic constants are processed in
4446 a separate stage, and all other preprocessing is done after on the resulting
4447 source.
4448 The standard preprocessing that comes after, on each line begins with
4449 recognition of the first symbol. It starts with checking for the preprocessor
4450 directives, and when none of them is detected, preprocessor checks whether the
4451 first symbol is macroinstruction. If no macroinstruction is found, it moves
4452 to the second symbol of line, and again begins with checking for directives,
4453 which in this case is only the "equ" directive, as this is the only one that
4454 occurs as the second symbol in line. If there is no directive, the second
4455 symbol is checked for the case of structure macroinstruction and when none
4456 of those checks gives the positive result, the symbolic constants are replaced
4457 with their values and such line is passed to the assembler.
4458 To see it on the example, assume that there is defined the macroinstruction
4459 called "foo" and the structure macroinstruction called "bar". Those lines:
4460
4461 foo equ
4462 foo bar
4463
4464 would be then both interpreted as invocations of macroinstruction "foo", since
4465 the meaning of the first symbol overrides the meaning of second one.
4466 When the macroinstruction generates the new lines from its definition block,
4467 in every line it first scans for macroinstruction directives, and interpretes
4468 them accordingly. All the other content in the definition block is used to
4469 brew the new lines, replacing the macroinstruction parameters with their values
4470 and then processing the symbol escaping and "#" and "`" operators. The
4471 conversion operator has the higher priority than concatenation and if any of
4472 them operates on the escaped symbol, the escaping is cancelled before finishing
4473 the operation. After this is completed, the newly generated line goes through
4474 the standard preprocessing, as described above.
4475 Though the symbolic constants are usually only replaced in the lines, where
4476 no preprocessor directives nor macroinstructions has been found, there are some
4477 special cases where those replacements are performed in the parts of lines
4478 containing directives. First one is the definition of symbolic constant, where
4479 the replacements are done everywhere after the "equ" keyword and the resulting
4480 value is then assigned to the new constant (see 2.3.2). The second such case
4481 is the "match" directive, where the replacements are done in the symbols
4482 following comma before matching them with pattern. These features can be used
4483 for example to maintain the lists, like this set of definitions:
4484
4485 list equ
4486
4487 macro append item
4488 {
4489 match any, list \{ list equ list,item \}
4490 match , list \{ list equ item \}
4491 }
4492
4493 The "list" constant is here initialized with empty value, and the "append"
4494 macroinstruction can be used to add the new items into this list, separating
4495 them with commas. The first match in this macroinstruction occurs only when
4496 the value of list is not empty (see 2.3.6), in such case the new value for the
4497 list is the previous one with the comma and the new item appended at the end.
4498 The second match happens only when the list is still empty, and in such case
4499 the list is defined to contain just the new item. So starting with the empty
4500 list, the "append 1" would define "list equ 1" and the "append 2" following it
4501 would define "list equ 1,2". One might then need to use this list as the
4502 parameters to some macroinstruction. But it cannot be done directly - if "foo"
4503 is the macroinstruction, then "foo list" would just pass the "list" symbol
4504 as a parameter to macro, since symbolic constants are not unrolled at this
4505 stage. For this purpose again "match" directive comes in handy:
4506
4507 match params, list { foo params }
4508
4509 The value of "list", if it's not empty, matches the "params" keyword, which is
4510 then replaced with matched value when generating the new lines defined by the
4511 block enclosed with braces. So if the "list" had value "1,2", the above line
4512 would generate the line containing "foo 1,2", which would then go through the
4513 standard preprocessing.
4514 The other special case is in the parameters of "rept" directive. The amount
4515 of repetitions and the base value for counter can be specified using
4516 numerical expressions, and if there is a symbolic constant with non-numerical
4517 name used in such an expression, preprocessor tries to evaluate its value as
4518 a numerical expression and if succeeds, it replaces the symbolic constant with
4519 the result of that calculation and continues to evaluate the primary
4520 expression. If the expression inside that symbolic constants also contains
4521 some symbolic constants, preprocessor will try to calculate all the needed
4522 values recursively.
4523 This allows to perform some calculations at the time of preprocessing, as
4524 long as all the values used are the numbers known at the preprocessing stage.
4525 A single repetition with "rept" can be used for the sole purpose of
4526 calculating some value, like in this example:
4527
4528 define a b+4
4529 define b 3
4530 rept 1 result:a*b+2 { define c result }
4531
4532 To compute the base value for "result" counter, preprocessor replaces the "b"
4533 with its value and recursively calculates the value of "a", obtaining 7 as
4534 the result, then it calculates the main expression with the result being 23.
4535 The "c" then gets defined with the first value of counter (because the block
4536 is processed just one time), which is the result of the computation, so the
4537 value of "c" is simple "23" symbol. Note that if "b" is later redefined with
4538 some other numerical value, the next time and expression containing "a" is
4539 calculated, the value of "a" will reflect the new value of "b", because the
4540 symbolic constant contains just the text of the expression.
4541 There is one more special case - when preprocessor goes to checking the
4542 second symbol in the line and it happens to be the colon character (what is
4543 then interpreted by assembler as definition of a label), it stops in this
4544 place and finishes the preprocessing of the first symbol (so if it's the
4545 symbolic constant it gets unrolled) and if it still appears to be the label,
4546 it performs the standard preprocessing starting from the place after the
4547 label. This allows to place preprocessor directives and macroinstructions
4548 after the labels, analogously to the instructions and directives processed
4549 by assembler, like:
4550
4551 start: include 'start.inc'
4552
4553 However if the label becomes broken during preprocessing (for example when
4554 it is the symbolic constant with empty value), only replacing of the symbolic
4555 constants is continued for the rest of line.
4556 It should be remembered, that the jobs performed by preprocessor are the
4557 preliminary operations on the texts symbols, that are done in a simple
4558 single pass before the main process of assembly. The text that is the
4559 result of preprocessing is passed to assembler, and it then does its
4560 multiple passes on it. Thus the control directives, which are recognized and
4561 processed only by the assembler - as they are dependent on the numerical
4562 values that may even vary between passes - are not recognized in any way by
4563 the preprocessor and have no effect on the preprocessing. Consider this
4564 example source:
4565
4566 if 0
4567 a = 1
4568 b equ 2
4569 end if
4570 dd b
4571
4572 When it is preprocessed, they only directive that is recognized by the
4573 preprocessor is the "equ", which defines symbolic constant "b", so later
4574 in the source the "b" symbol is replaced with the value "2". Except for this
4575 replacement, the other lines are passes unchanged to the assembler. So
4576 after preprocessing the above source becomes:
4577
4578 if 0
4579 a = 1
4580 end if
4581 dd 2
4582
4583 Now when assembler processes it, the condition for the "if" is false, and
4584 the "a" constant doesn't get defined. However symbolic constant "b" was
4585 processed normally, even though its definition was put just next to the one
4586 of "a". So because of the possible confusion you should be very careful
4587 every time when mixing the features of preprocessor and assembler - in such
4588 cases it is important to realize what the source will become after the
4589 preprocessing, and thus what the assembler will see and do its multiple passes
4590 on.
4591
4592
4593 2.4 Formatter directives
4594
4595 These directives are actually also a kind of control directives, with the
4596 purpose of controlling the format of generated code.
4597 "format" directive followed by the format identifier allows to select the
4598 output format. This directive should be put at the beginning of the source.
4599 Default output format is a flat binary file, it can also be selected by using
4600 "format binary" directive. This directive can be followed by the "as" keyword
4601 and the quoted string specifying the default file extension for the output
4602 file. Unless the output file name was specified from the command line,
4603 assembler will use this extension when generating the output file.
4604 "use16" and "use32" directives force the assembler to generate 16-bit or
4605 32-bit code, omitting the default setting for selected output format. "use64"
4606 enables generating the code for the long mode of x86-64 processors.
4607 Below are described different output formats with the directives specific to
4608 these formats.
4609
4610
4611 2.4.1 MZ executable
4612
4613 To select the MZ output format, use "format MZ" directive. The default code
4614 setting for this format is 16-bit.
4615 "segment" directive defines a new segment, it should be followed by label,
4616 which value will be the number of defined segment, optionally "use16" or
4617 "use32" word can follow to specify whether code in this segment should be
4618 16-bit or 32-bit. The origin of segment is aligned to paragraph (16 bytes).
4619 All the labels defined then will have values relative to the beginning of this
4620 segment.
4621 "entry" directive sets the entry point for MZ executable, it should be
4622 followed by the far address (name of segment, colon and the offset inside
4623 segment) of desired entry point.
4624 "stack" directive sets up the stack for MZ executable. It can be followed by
4625 numerical expression specifying the size of stack to be created automatically
4626 or by the far address of initial stack frame when you want to set up the stack
4627 manually. When no stack is defined, the stack of default size 4096 bytes will
4628 be created.
4629 "heap" directive should be followed by a 16-bit value defining maximum size
4630 of additional heap in paragraphs (this is heap in addition to stack and
4631 undefined data). Use "heap 0" to always allocate only memory program really
4632 needs. Default size of heap is 65535.
4633
4634
4635 2.4.2 Portable Executable
4636
4637 To select the Portable Executable output format, use "format PE" directive, it
4638 can be followed by additional format settings: first the target subsystem
4639 setting, which can be "console" or "GUI" for Windows applications, "native"
4640 for Windows drivers, "EFI", "EFIboot" or "EFIruntime" for the UEFI, it may be
4641 followed by the minimum version of system that the executable is targeted to
4642 (specified in form of floating-point value). Optional "DLL" and "WDM" keywords
4643 mark the output file as a dynamic link library and WDM driver respectively,
4644 and the "large" keyword marks the executable as able to handle addresses
4645 larger than 2 GB.
4646 After those settings can follow the "at" operator and a numerical expression
4647 specifying the base of PE image and then optionally "on" operator followed by
4648 the quoted string containing file name selects custom MZ stub for PE program
4649 (when specified file is not a MZ executable, it is treated as a flat binary
4650 executable file and converted into MZ format). The default code setting for
4651 this format is 32-bit. The example of fully featured PE format declaration:
4652
4653 format PE GUI 4.0 DLL at 7000000h on 'stub.exe'
4654
4655 To create PE file for the x86-64 architecture, use "PE64" keyword instead of
4656 "PE" in the format declaration, in such case the long mode code is generated
4657 by default.
4658 "section" directive defines a new section, it should be followed by quoted
4659 string defining the name of section, then one or more section flags can
4660 follow. Available flags are: "code", "data", "readable", "writeable",
4661 "executable", "shareable", "discardable", "notpageable". The origin of section
4662 is aligned to page (4096 bytes). Example declaration of PE section:
4663
4664 section '.text' code readable executable
4665
4666 Among with flags also one of the special PE data identifiers can be specified
4667 to mark the whole section as a special data, possible identifiers are
4668 "export", "import", "resource" and "fixups". If the section is marked to
4669 contain fixups, they are generated automatically and no more data needs to be
4670 defined in this section. Also resource data can be generated automatically
4671 from the resource file, it can be achieved by writing the "from" operator and
4672 quoted file name after the "resource" identifier. Below are the examples of
4673 sections containing some special PE data:
4674
4675 section '.reloc' data readable discardable fixups
4676 section '.rsrc' data readable resource from 'my.res'
4677
4678 "entry" directive sets the entry point for Portable Executable, the value of
4679 entry point should follow.
4680 "stack" directive sets up the size of stack for Portable Executable, value
4681 of stack reserve size should follow, optionally value of stack commit
4682 separated with comma can follow. When stack is not defined, it's set by
4683 default to size of 4096 bytes.
4684 "heap" directive chooses the size of heap for Portable Executable, value of
4685 heap reserve size should follow, optionally value of heap commit separated
4686 with comma can follow. When no heap is defined, it is set by default to size
4687 of 65536 bytes, when size of heap commit is unspecified, it is by default set
4688 to zero.
4689 "data" directive begins the definition of special PE data, it should be
4690 followed by one of the data identifiers ("export", "import", "resource" or
4691 "fixups") or by the number of data entry in PE header. The data should be
4692 defined in next lines, ended with "end data" directive. When fixups data
4693 definition is chosen, they are generated automatically and no more data needs
4694 to be defined there. The same applies to the resource data when the "resource"
4695 identifier is followed by "from" operator and quoted file name - in such case
4696 data is taken from the given resource file.
4697 The "rva" operator can be used inside the numerical expressions to obtain
4698 the RVA of the item addressed by the value it is applied to, that is the
4699 offset relative to the base of PE image.
4700
4701
4702 2.4.3 Common Object File Format
4703
4704 To select Common Object File Format, use "format COFF" or "format MS COFF"
4705 directive, depending whether you want to create classic (DJGPP) or Microsoft's
4706 variant of COFF file. The default code setting for this format is 32-bit. To
4707 create the file in Microsoft's COFF format for the x86-64 architecture, use
4708 "format MS64 COFF" setting, in such case long mode code is generated by
4709 default.
4710 "section" directive defines a new section, it should be followed by quoted
4711 string defining the name of section, then one or more section flags can
4712 follow. Section flags available for both COFF variants are "code" and "data",
4713 while flags "readable", "writeable", "executable", "shareable", "discardable",
4714 "notpageable", "linkremove" and "linkinfo" are available only with Microsoft's
4715 COFF variant.
4716 By default section is aligned to double word (four bytes), in case of
4717 Microsoft COFF variant other alignment can be specified by providing the
4718 "align" operator followed by alignment value (any power of two up to 8192)
4719 among the section flags.
4720 "extrn" directive defines the external symbol, it should be followed by the
4721 name of symbol and optionally the size operator specifying the size of data
4722 labeled by this symbol. The name of symbol can be also preceded by quoted
4723 string containing name of the external symbol and the "as" operator.
4724 Some example declarations of external symbols:
4725
4726 extrn exit
4727 extrn '__imp__MessageBoxA@16' as MessageBox:dword
4728
4729 "public" directive declares the existing symbol as public, it should be
4730 followed by the name of symbol, optionally it can be followed by the "as"
4731 operator and the quoted string containing name under which symbol should be
4732 available as public. Some examples of public symbols declarations:
4733
4734 public main
4735 public start as '_start'
4736
4737 Additionally, with COFF format it's possible to specify exported symbol as
4738 static, it's done by preceding the name of symbol with the "static" keyword.
4739 When using the Microsoft's COFF format, the "rva" operator can be used
4740 inside the numerical expressions to obtain the RVA of the item addressed by the
4741 value it is applied to.
4742
4743 2.4.4 Executable and Linkable Format
4744
4745 To select ELF output format, use "format ELF" directive. The default code
4746 setting for this format is 32-bit. To create ELF file for the x86-64
4747 architecture, use "format ELF64" directive, in such case the long mode code is
4748 generated by default.
4749 "section" directive defines a new section, it should be followed by quoted
4750 string defining the name of section, then can follow one or both of the
4751 "executable" and "writeable" flags, optionally also "align" operator followed
4752 by the number specifying the alignment of section (it has to be the power of
4753 two), if no alignment is specified, the default value is used, which is 4 or 8,
4754 depending on which format variant has been chosen.
4755 "extrn" and "public" directives have the same meaning and syntax as when the
4756 COFF output format is selected (described in previous section).
4757 The "rva" operator can be used also in the case of this format (however not
4758 when target architecture is x86-64), it converts the address into the offset
4759 relative to the GOT table, so it may be useful to create position-independent
4760 code. There's also a special "plt" operator, which allows to call the external
4761 functions through the Procedure Linkage Table. You can even create an alias
4762 for external function that will make it always be called through PLT, with
4763 the code like:
4764
4765 extrn 'printf' as _printf
4766 printf = PLT _printf
4767
4768 To create executable file, follow the format choice directive with the
4769 "executable" keyword and optionally the number specifying the brand of the
4770 target operating system (for example value 3 would mark the executable
4771 for Linux system). With this format selected it is allowed to use "entry"
4772 directive followed by the value to set as entry point of program. On the other
4773 hand it makes "extrn" and "public" directives unavailable, and instead of
4774 "section" there should be the "segment" directive used, followed by one or
4775 more segment permission flags and optionally a marker of special ELF
4776 executable segment, which can be "interpreter", "dynamic" or "note". The
4777 origin of segment is aligned to page (4096 bytes), and available permission
4778 flags are: "readable", "writeable" and "executable".
4779
4780 EOF
0
1 flat assembler version 1.71
2 Copyright (c) 1999-2013, Tomasz Grysztar.
3 All rights reserved.
4
5 This program is free for commercial and non-commercial use as long as
6 the following conditions are adhered to.
7
8 Copyright remains Tomasz Grysztar, and as such any Copyright notices
9 in the code are not to be removed.
10
11 Redistribution and use in source and binary forms, with or without
12 modification, are permitted provided that the following conditions are
13 met:
14
15 1. Redistributions of source code must retain the above copyright notice,
16 this list of conditions and the following disclaimer.
17 2. Redistributions in binary form must reproduce the above copyright
18 notice, this list of conditions and the following disclaimer in the
19 documentation and/or other materials provided with the distribution.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
25 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33 The licence and distribution terms for any publically available
34 version or derivative of this code cannot be changed. i.e. this code
35 cannot simply be copied and put under another distribution licence
36 (including the GNU Public Licence).
0
1 ; flat assembler interface for DOS
2 ; Copyright (c) 1999-2014, Tomasz Grysztar.
3 ; All rights reserved.
4
5 format MZ
6 heap 0
7 stack 8000h
8 entry main:start
9
10 include 'modes.inc'
11
12 segment main use16
13
14 start:
15
16 mov ax,ds
17 mov dx,[2Ch]
18 push cs cs
19 pop ds es
20 mov [psp_segment],ax
21 mov [environment_segment],dx
22
23 mov dx,_logo
24 mov ah,9
25 int 21h
26
27 cld
28
29 call go32
30 use32
31
32 call get_params
33 jc information
34
35 call init_memory
36
37 mov esi,_memory_prefix
38 call display_string
39 mov eax,[memory_end]
40 sub eax,[memory_start]
41 add eax,[additional_memory_end]
42 sub eax,[additional_memory]
43 shr eax,10
44 call display_number
45 mov esi,_memory_suffix
46 call display_string
47
48 xor ah,ah
49 int 1Ah
50 mov ax,cx
51 shl eax,16
52 mov ax,dx
53 mov [start_time],eax
54
55 cmp [mode],dpmi
56 je compile
57 jmp main+(first_segment shr 4):first_gate-first_segment
58
59 compile:
60 call preprocessor
61 call parser
62 call assembler
63 call formatter
64
65 finish:
66 call display_user_messages
67 movzx eax,[current_pass]
68 inc eax
69 call display_number
70 mov esi,_passes_suffix
71 call display_string
72 xor ah,ah
73 int 1Ah
74 mov ax,cx
75 shl eax,16
76 mov ax,dx
77 sub eax,[start_time]
78 mov ebx,100
79 mul ebx
80 mov ebx,182
81 div ebx
82 or eax,eax
83 jz display_bytes_count
84 xor edx,edx
85 mov ebx,10
86 div ebx
87 push edx
88 call display_number
89 mov ah,2
90 mov dl,'.'
91 int 21h
92 pop eax
93 call display_number
94 mov esi,_seconds_suffix
95 call display_string
96 display_bytes_count:
97 mov eax,[written_size]
98 call display_number
99 mov esi,_bytes_suffix
100 call display_string
101 xor al,al
102 jmp exit_program
103
104 information:
105 mov esi,_usage
106 call display_string
107 mov al,1
108 jmp exit_program
109
110 get_params:
111 mov [input_file],0
112 mov [output_file],0
113 mov [symbols_file],0
114 mov [memory_setting],0
115 mov [passes_limit],100
116 push ds
117 mov ds,[psp_segment]
118 mov esi,81h
119 mov edi,params
120 find_param:
121 lodsb
122 cmp al,20h
123 je find_param
124 cmp al,'-'
125 je option_param
126 cmp al,0Dh
127 je all_params
128 or al,al
129 jz all_params
130 cmp [es:input_file],0
131 jne get_output_file
132 mov [es:input_file],edi
133 jmp process_param
134 get_output_file:
135 cmp [es:output_file],0
136 jne bad_params
137 mov [es:output_file],edi
138 process_param:
139 cmp al,22h
140 je string_param
141 copy_param:
142 stosb
143 lodsb
144 cmp al,20h
145 je param_end
146 cmp al,0Dh
147 je param_end
148 or al,al
149 jz param_end
150 jmp copy_param
151 string_param:
152 lodsb
153 cmp al,22h
154 je string_param_end
155 cmp al,0Dh
156 je param_end
157 or al,al
158 jz param_end
159 stosb
160 jmp string_param
161 option_param:
162 lodsb
163 cmp al,'m'
164 je memory_option
165 cmp al,'M'
166 je memory_option
167 cmp al,'p'
168 je passes_option
169 cmp al,'P'
170 je passes_option
171 cmp al,'s'
172 je symbols_option
173 cmp al,'S'
174 je symbols_option
175 invalid_option:
176 pop ds
177 stc
178 ret
179 get_option_value:
180 xor eax,eax
181 mov edx,eax
182 get_option_digit:
183 lodsb
184 cmp al,20h
185 je option_value_ok
186 cmp al,0Dh
187 je option_value_ok
188 or al,al
189 jz option_value_ok
190 sub al,30h
191 jc bad_params_value
192 cmp al,9
193 ja bad_params_value
194 imul edx,10
195 jo bad_params_value
196 add edx,eax
197 jc bad_params_value
198 jmp get_option_digit
199 option_value_ok:
200 dec esi
201 clc
202 ret
203 bad_params_value:
204 stc
205 ret
206 memory_option:
207 lodsb
208 cmp al,20h
209 je memory_option
210 cmp al,0Dh
211 je invalid_option
212 or al,al
213 jz invalid_option
214 dec esi
215 call get_option_value
216 jc invalid_option
217 or edx,edx
218 jz invalid_option
219 cmp edx,1 shl (32-10)
220 jae invalid_option
221 mov [es:memory_setting],edx
222 jmp find_param
223 passes_option:
224 lodsb
225 cmp al,20h
226 je passes_option
227 cmp al,0Dh
228 je invalid_option
229 or al,al
230 jz invalid_option
231 dec esi
232 call get_option_value
233 jc bad_params
234 or edx,edx
235 jz invalid_option
236 cmp edx,10000h
237 ja invalid_option
238 mov [es:passes_limit],dx
239 jmp find_param
240 symbols_option:
241 mov [es:symbols_file],edi
242 find_symbols_file_name:
243 lodsb
244 cmp al,20h
245 jne process_param
246 jmp find_symbols_file_name
247 param_end:
248 dec esi
249 string_param_end:
250 xor al,al
251 stosb
252 jmp find_param
253 all_params:
254 xor al,al
255 stosb
256 pop ds
257 cmp [input_file],0
258 je no_input_file
259 clc
260 ret
261 bad_params:
262 pop ds
263 no_input_file:
264 stc
265 ret
266
267 include '..\version.inc'
268
269 _logo db 'flat assembler version ',VERSION_STRING,24h
270 _copyright db 'Copyright (c) 1999-2014, Tomasz Grysztar',0Dh,0Ah,0
271
272 _usage db 0Dh,0Ah
273 db 'usage: fasm <source> [output]',0Dh,0Ah
274 db 'optional settings:',0Dh,0Ah
275 db ' -m <limit> set the limit in kilobytes for the available memory',0Dh,0Ah
276 db ' -p <limit> set the maximum allowed number of passes',0Dh,0Ah
277 db ' -s <file> dump symbolic information for debugging',0Dh,0Ah
278 db 0
279 _memory_prefix db ' (',0
280 _memory_suffix db ' kilobytes memory)',0Dh,0Ah,0
281 _passes_suffix db ' passes, ',0
282 _seconds_suffix db ' seconds, ',0
283 _bytes_suffix db ' bytes.',0Dh,0Ah,0
284
285 error_prefix db 'error: ',0
286 error_suffix db '.'
287 cr_lf db 0Dh,0Ah,0
288 line_number_start db ' [',0
289 line_data_start db ':',0Dh,0Ah,0
290
291 align 16
292 first_segment:
293
294 include '..\preproce.inc'
295 include '..\parser.inc'
296 include '..\exprpars.inc'
297
298 align 16
299 second_segment:
300
301 include '..\exprcalc.inc'
302 include '..\errors.inc'
303 include '..\symbdump.inc'
304
305 include 'system.inc'
306
307 first_gate:
308 call preprocessor
309 call parser
310 jmp main+(second_segment shr 4):second_gate-second_segment
311 first_segment_top = $ - first_segment
312
313 include '..\assemble.inc'
314 include '..\formats.inc'
315 include '..\x86_64.inc'
316 include '..\avx.inc'
317
318 second_gate:
319 call assembler
320 call formatter
321 jmp main:finish
322
323 second_segment_top = $ - second_segment
324
325 if first_segment_top>=10000h | second_segment_top>=10000h
326 if UNREAL_ENABLED>0
327 UNREAL_ENABLED = -1
328 else
329 UNREAL_ENABLED = 0
330 end if
331 else
332 if UNREAL_ENABLED<0
333 UNREAL_ENABLED = -1
334 else
335 UNREAL_ENABLED = 1
336 end if
337 end if
338
339 include '..\tables.inc'
340 include '..\messages.inc'
341
342 align 4
343
344 include '..\variable.inc'
345
346 memory_setting dd ?
347 start_time dd ?
348 params rb 100h
349
350 mode dw ?
351 real_mode_segment dw ?
352 displayed_count dd ?
353 last_displayed rb 2
354
355 segment buffer
356
357 rb 1000h
0
1 ; flat assembler interface for DOS
2 ; Copyright (c) 1999-2014, Tomasz Grysztar.
3 ; All rights reserved.
4
5 segment modes use16
6
7 real32:
8 mov ax,7202h
9 push ax
10 popf
11 pushf
12 pop bx
13 cmp ax,bx
14 je processor_ok
15 call init_error
16 db 'required 80386 or better',24h
17 processor_ok:
18 mov eax,ds
19 shl eax,4
20 mov [program_base],eax
21 mov eax,buffer
22 shl eax,4
23 sub eax,[program_base]
24 mov [buffer_address],eax
25
26 if UNREAL_ENABLED>0
27
28 smsw ax
29 test al,1
30 jnz dpmi
31 mov eax,cs ; calculate linear address of GDT
32 shl eax,4
33 or dword [cs:real32_GDT+10],eax
34 or dword [cs:real16_GDT+10],eax
35 add [cs:real32_GDT_address],eax
36 add [cs:real16_GDT_address],eax
37 cli
38 lgdt [cs:real32_GDTR]
39 mov eax,cr0
40 or al,1
41 mov cr0,eax
42 jmp 1 shl 3:test_pm32
43 no_rm32:
44 sti
45 jmp dpmi
46 test_pm32:
47 use32
48 mov eax,cr0
49 and al,not 1
50 mov cr0,eax
51 mov ebx,0FFFFh
52 jmp modes:test_rm32
53 test_rm32:
54 inc ebx
55 jz short no_rm32
56 lgdt [cs:real16_GDTR]
57 mov eax,cr0
58 or al,1
59 mov cr0,eax
60 jmp 1 shl 3:test_pm16
61 test_pm16:
62 use16
63 mov eax,cr0
64 and al,not 1
65 mov cr0,eax
66 jmp modes:test_rm16
67 test_rm16:
68 sti
69 mov bx,(400h+(100h*interrupt.size)) shr 4
70 mov ah,48h
71 int 21h
72 jc not_enough_memory
73 push ds es
74 mov es,ax
75 push cs
76 pop ds
77 movzx eax,ax
78 shl eax,4
79 mov [real32_IDT_base],eax
80 mov dx,100h
81 xor bx,bx
82 mov di,400h
83 init_interrupts:
84 mov si,interrupt
85 mov [si+interrupt.vector],bx
86 mov word [es:bx],di
87 mov word [es:bx+2],es
88 mov cx,interrupt.size
89 rep movsb
90 add bx,4
91 dec dx
92 jnz init_interrupts
93 pop es ds
94 call modes:switch_real32
95 use32
96 mov [mode],real32
97 retfw
98 use16
99
100 switch_real32:
101 pushfw
102 push eax
103 push word ds
104 push word es
105 push word fs
106 push word gs
107 cli
108 mov eax,ss
109 mov cr3,eax
110 lgdt [cs:real32_GDTR]
111 mov eax,cr0 ; switch to protected mode
112 or al,1
113 mov cr0,eax
114 jmp 1 shl 3:pm32_start
115 pm32_start:
116 use32
117 mov ax,2 shl 3 ; load 32-bit data descriptor
118 mov ds,ax ; to all data segment registers
119 mov es,ax
120 mov fs,ax
121 mov gs,ax
122 mov ss,ax
123 mov eax,cr0 ; switch back to real mode
124 and al,not 1
125 mov cr0,eax
126 jmp modes:pm32_end
127 pm32_end:
128 mov eax,cr3
129 mov ss,ax
130 lidt [cs:real32_IDTR]
131 pop word gs
132 pop word fs
133 pop word es
134 pop word ds
135 pop eax
136 popfw
137 retfw
138
139 switch_real16:
140 pushfw
141 push eax
142 cli
143 lgdt [cs:real16_GDTR]
144 mov eax,cr0 ; switch to protected mode
145 or al,1
146 mov cr0,eax
147 jmp 1 shl 3:pm16_start
148 pm16_start:
149 use16
150 mov eax,cr0 ; switch back to real mode
151 and al,not 1
152 mov cr0,eax
153 jmp modes:pm16_end
154 pm16_end:
155 lidt [cs:real16_IDTR]
156 pop eax
157 popfw
158 retfd
159 use32
160
161 interrupt:
162 call modes:switch_real16
163 use16
164 movzx esp,sp
165 push word [esp+4]
166 push cs
167 call .real16
168 pushfw
169 pop word [esp+4]
170 call modes:switch_real32
171 use32
172 iretw
173 .real16:
174 use16
175 push eax
176 push ds
177 xor ax,ax
178 mov ds,ax
179 mov eax,[word 0]
180 label .vector word at $-2-interrupt
181 pop ds
182 xchg eax,[esp]
183 retfw
184 .size = $-interrupt
185
186 label real32_GDTR pword
187 real32_GDT_limit dw 3*8-1 ; limit of GDT
188 real32_GDT_address dd real32_GDT ; linear address of GDT
189 real32_GDT rw 4 ; null descriptor
190 dw 0FFFFh,0,9A00h,0CFh ; 32-bit code descriptor
191 dw 0FFFFh,0,9200h,08Fh ; 4 GB data descriptor
192 label real16_GDTR pword
193 real16_GDT_limit dw 2*8-1 ; limit of GDT
194 real16_GDT_address dd real16_GDT ; linear address of GDT
195 real16_GDT rw 4 ; null descriptor
196 dw 0FFFFh,0,9A00h,0 ; 16-bit code descriptor
197
198 label real32_IDTR pword
199 real32_IDT_limit dw 3FFh
200 real32_IDT_base dd ?
201 label real16_IDTR pword
202 real16_IDT_limit dw 3FFh
203 real16_IDT_base dd 0
204
205 end if
206
207 dpmi:
208 mov ax,1687h
209 int 2Fh
210 or ax,ax ; DPMI installed?
211 jnz no_dpmi
212 test bl,1 ; 32-bit programs supported?
213 jz no_dpmi
214 mov word [cs:mode_switch],di
215 mov word [cs:mode_switch+2],es
216 mov bx,si ; allocate memory for DPMI data
217 mov ah,48h
218 int 21h
219 jc not_enough_memory
220 mov ds,[environment_segment]
221 mov es,ax
222 mov ax,1
223 call far [cs:mode_switch] ; switch to protected mode
224 jc no_dpmi
225 mov cx,1
226 xor ax,ax
227 int 31h ; allocate descriptor for code
228 mov si,ax
229 xor ax,ax
230 int 31h ; allocate descriptor for data
231 mov di,ax
232 mov dx,cs
233 lar cx,dx
234 shr cx,8
235 or cx,0C000h
236 mov bx,si
237 mov ax,9
238 int 31h ; set code descriptor access rights
239 mov dx,ds
240 lar cx,dx
241 shr cx,8
242 or cx,0C000h
243 mov bx,di
244 int 31h ; set data descriptor access rights
245 mov ecx,main
246 shl ecx,4
247 mov dx,cx
248 shr ecx,16
249 mov ax,7
250 int 31h ; set data descriptor base address
251 movzx ecx,word [esp+2]
252 shl ecx,4
253 mov dx,cx
254 shr ecx,16
255 mov bx,si
256 int 31h ; set code descriptor base address
257 mov cx,0FFFFh
258 mov dx,0FFFFh
259 mov ax,8 ; set segment limit to 4 GB
260 int 31h
261 mov bx,di
262 int 31h
263 mov ax,ds
264 mov ds,di
265 mov [psp_segment],es
266 mov [environment_segment],ax
267 mov es,di
268 mov [mode],dpmi
269 pop ebx
270 movzx ebx,bx
271 push esi
272 push ebx
273 retfd
274
275 init_error:
276 push cs
277 pop ds
278 mov dx,init_error_prefix
279 mov ah,9
280 int 21h
281 pop dx
282 int 21h
283 mov dx,init_error_suffix
284 int 21h
285 mov ax,04CFFh
286 int 21h
287
288 init_error_prefix db 0Dh,0Ah,'error: ',24h
289 init_error_suffix db '.',0Dh,0Ah,24h
290
291 mode_switch dd ?
292
293 not_enough_memory:
294 call init_error
295 db 'not enough conventional memory',24h
296
297 if UNREAL_ENABLED>0
298
299 no_dpmi:
300 smsw ax
301 test al,1
302 jz no_real32
303 call init_error
304 db 'system is in protected mode without 32-bit DPMI services',24h
305 no_real32:
306 call init_error
307 db 'processor is not able to enter 32-bit real mode',24h
308
309 else
310
311 no_dpmi:
312 call init_error
313 db 'no 32-bit DPMI services are available',24h
314
315 end if
316
317 use32
318
319 if UNREAL_ENABLED>0
320
321 init_real32_memory:
322 mov ax,4300h ; check for XMS
323 int 2Fh
324 cmp al,80h ; XMS present?
325 je xms_init
326 mov ax,0E801h ; check for large free extended memory
327 int 15h
328 jnc large_raw_memory
329 mov ah,88h ; how much extended memory free?
330 int 15h
331 or ax,ax
332 jz no_extended_memory
333 movzx eax,ax ; convert AX kilobytes to pointer
334 shl eax,10
335 jmp use_raw_memory
336 large_raw_memory:
337 movzx ecx,cx
338 shl ecx,10
339 movzx edx,dx
340 shl edx,16
341 mov eax,ecx
342 add eax,edx
343 use_raw_memory:
344 add eax,100000h
345 sub eax,[program_base]
346 mov [memory_end],eax
347 push ds
348 push 0 ; DS := 0
349 pop ds
350 call enable_a20 ; enable A20
351 call test_a20 ; is A20 enabled?
352 jz a20_ok
353 pop ds
354 jmp no_extended_memory
355 a20_ok:
356 lds bx,dword [4*19h]
357 mov eax,100000h ; initial free extended memory base
358 cmp dword [bx+12h],'VDIS' ; VDISK memory allocation?
359 jne short no_vdisk ; if present, get base of free memory
360 mov eax,dword [bx+2Ch] ; get first free extended memory byte
361 add eax,0Fh ; align on paragraph
362 and eax,0FFFFF0h ; address is only 24bit
363 no_vdisk:
364 push 0FFFFh ; DS := FFFFh for ext mem addressing
365 pop ds
366 cmp dword [13h],'VDIS' ; VDISK memory allocation?
367 jne short vdisk_ok ; if present, get base of free memory
368 movzx ebx,word [2Eh] ; get first free kilobyte
369 shl ebx,10
370 cmp eax,ebx ; pick larger of 2 addresses
371 ja short vdisk_ok
372 mov eax,ebx
373 vdisk_ok:
374 pop ds
375 sub eax,[program_base]
376 mov [memory_start],eax
377 mov edx,[memory_setting]
378 shl edx,10
379 jz extended_memory_ok
380 mov eax,[memory_end]
381 sub eax,[memory_start]
382 sub eax,edx
383 jbe extended_memory_ok
384 sub [memory_end],eax
385 jmp extended_memory_ok
386 enable_a20:
387 call test_a20 ; is A20 already enabled?
388 jz a20_enabled ; if yes, done
389 in al,92h ; PS/2 A20 enable
390 or al,2
391 out 92h,al
392 call test_a20 ; is A20 enabled?
393 jz a20_enabled ; if yes, done
394 call kb_wait ; AT A20 enable
395 jnz a20_enabled
396 mov al,0D1h
397 out 64h,al
398 call kb_wait
399 jnz a20_enabled
400 mov al,0DFh
401 out 60h,al
402 call kb_wait
403 a20_enabled:
404 retn
405 kb_wait: ; wait for safe to write to 8042
406 xor cx,cx
407 .loop:
408 in al,64h ; read 8042 status
409 test al,2 ; buffer full?
410 loopnz .loop ; if yes, loop
411 retn
412 test_a20: ; test for enabled A20
413 mov al,[0] ; get byte from 0:0
414 mov ah,al ; preserve old byte
415 not al ; modify byte
416 xchg al,[100000h] ; put modified byte to 0FFFFh:10h
417 cmp ah,[0] ; set zero if byte at 0:0 not modified
418 mov [100000h],al ; restore byte at 0FFFFh:10h
419 retn ; return, zero if A20 enabled
420 xms_init:
421 push es
422 mov ax,4310h ; get XMS driver address
423 int 2Fh
424 mov word [cs:xms_proc],bx ; store XMS driver address
425 mov word [cs:xms_proc+2],es
426 pop es
427 mov ah,3 ; enable A20
428 call call_xms
429 cmp ax,1 ; error enabling A20?
430 jne no_extended_memory
431 mov ah,88h ; get free extended memory size (XMS 3.0)
432 xor bl,bl
433 call call_xms
434 or bl,bl
435 jz xms_large_init
436 mov ah,8 ; get free extended memory size
437 xor bl,bl
438 call call_xms
439 or bl,bl
440 jnz no_extended_memory
441 mov dx,ax
442 movzx eax,ax
443 shl eax,10
444 mov [memory_end],eax
445 mov ah,9 ; allocate largest memory block
446 xms_allocate:
447 mov ecx,[memory_setting]
448 shl ecx,10
449 jz xms_size_ok
450 cmp ecx,[memory_end]
451 jae xms_size_ok
452 mov [memory_end],ecx
453 mov edx,[memory_setting]
454 xms_size_ok:
455 call call_xms
456 mov [cs:xms_handle],dx
457 cmp ax,1
458 jne no_extended_memory
459 mov ah,0Ch ; lock extended memory block
460 call call_xms
461 cmp ax,1
462 jne no_extended_memory
463 shl edx,16
464 mov dx,bx
465 sub edx,[program_base]
466 mov [memory_start],edx ; store memory block address
467 add [memory_end],edx
468 jmp extended_memory_ok
469 xms_large_init:
470 mov edx,eax
471 shl eax,10
472 mov [memory_end],eax
473 mov ah,89h ; allocate largest memory block (XMS 3.0)
474 jmp xms_allocate
475 call_xms:
476 call modes:switch_real16
477 use16
478 call far dword [cs:xms_proc]
479 call modes:switch_real32
480 use32
481 retn
482 no_extended_memory:
483 xor eax,eax
484 mov [memory_start],eax
485 extended_memory_ok:
486 mov ah,48h ; get free conventional memory size
487 mov bx,-1
488 int 21h
489 movzx ecx,bx
490 shl ecx,4
491 mov ah,48h ; allocate all conventional memory
492 int 21h
493 movzx edi,ax
494 shl edi,4
495 sub edi,[program_base]
496 mov [additional_memory],edi
497 mov [additional_memory_end],edi
498 add [additional_memory_end],ecx
499 cmp [memory_start],0
500 je only_conventional_memory
501 mov eax,[memory_end]
502 sub eax,[memory_start]
503 shr eax,2
504 cmp eax,ecx
505 jbe real32_memory_ok
506 mov eax,[memory_end]
507 mov ebx,[memory_start]
508 sub eax,ebx
509 shr eax,2
510 mov [additional_memory],ebx
511 add ebx,eax
512 mov [additional_memory_end],ebx
513 mov [memory_start],ebx
514 real32_memory_ok:
515 retf
516 only_conventional_memory:
517 shr ecx,2 ; use part of conventional memory
518 add edi,ecx ; as a substitute for extended memory
519 mov [memory_start],edi
520 xchg [additional_memory_end],edi
521 mov [memory_end],edi
522 retf
523
524 free_real32_memory:
525 cmp [cs:xms_handle],0
526 je no_xms
527 mov ah,0Dh ; unlock extended memory block
528 mov dx,[cs:xms_handle]
529 call call_xms
530 mov ah,0Ah ; free extended memory block
531 call call_xms
532 no_xms:
533 retf
534
535 xms_proc dd ? ; XMS driver pointer
536 xms_handle dw ? ; handle of XMS memory block
537
538 end if
0
1 ; flat assembler interface for DOS
2 ; Copyright (c) 1999-2014, Tomasz Grysztar.
3 ; All rights reserved.
4
5 go32:
6 use16
7 call modes:real32
8 use32
9 retw
10
11 program_base dd ?
12 buffer_address dd ?
13 psp_segment dw ?
14 environment_segment dw ?
15
16 if UNREAL_ENABLED>0
17
18 init_memory:
19 mov [stack_limit],0
20 cmp [mode],dpmi
21 je init_dpmi_memory
22 call modes:init_real32_memory
23 ret
24 dos_int:
25 cmp [mode],dpmi
26 je dpmi_dos_int
27 stc
28 int 21h
29 ret
30 dos_int_with_buffer:
31 cmp [mode],dpmi
32 je dpmi_dos_int_with_buffer
33 push ds buffer
34 pop ds
35 stc
36 int 21h
37 pop ds
38 ret
39 exit_program:
40 cmp [mode],dpmi
41 je exit_state_ok
42 push eax
43 call modes:free_real32_memory
44 pop eax
45 exit_state_ok:
46 mov ah,4Ch
47 int 21h
48
49 else
50
51 init_memory:
52 mov [stack_limit],0
53 jmp init_dpmi_memory
54 dos_int:
55 jmp dpmi_dos_int
56 dos_int_with_buffer:
57 jmp dpmi_dos_int_with_buffer
58 exit_program:
59 mov ah,4Ch
60 int 21h
61
62 end if
63
64 init_dpmi_memory:
65 mov ax,500h ; get free memory information
66 mov edi,[buffer_address]
67 int 31h
68 mov ebx,[edi]
69 allocate_dpmi_memory:
70 mov edx,[memory_setting]
71 shl edx,10
72 jz dpmi_memory_size_ok
73 cmp ebx,edx
74 jbe dpmi_memory_size_ok
75 mov ebx,edx
76 dpmi_memory_size_ok:
77 mov [memory_end],ebx
78 mov ecx,ebx
79 shr ebx,16
80 mov ax,501h
81 int 31h
82 jnc dpmi_memory_ok
83 mov ebx,[memory_end]
84 shr ebx,1
85 cmp ebx,4000h
86 jb out_of_memory
87 jmp allocate_dpmi_memory
88 dpmi_memory_ok:
89 shl ebx,16
90 mov bx,cx
91 sub ebx,[program_base]
92 jc out_of_memory
93 mov [memory_start],ebx
94 add [memory_end],ebx
95 mov ax,100h ; get free conventional memory size
96 mov bx,-1
97 int 31h
98 movzx ecx,bx
99 shl ecx,4
100 jecxz no_conventional_memory
101 mov ax,100h ; allocate all conventional memory
102 int 31h
103 movzx edi,ax
104 shl edi,4
105 sub edi,[program_base]
106 jc no_conventional_memory
107 mov [additional_memory],edi
108 mov [additional_memory_end],edi
109 add [additional_memory_end],ecx
110 mov eax,[memory_end]
111 sub eax,[memory_start]
112 shr eax,2
113 cmp eax,ecx
114 ja no_conventional_memory
115 ret
116 no_conventional_memory:
117 mov eax,[memory_end]
118 mov ebx,[memory_start]
119 sub eax,ebx
120 shr eax,2
121 mov [additional_memory],ebx
122 add ebx,eax
123 mov [additional_memory_end],ebx
124 mov [memory_start],ebx
125 ret
126
127 dpmi_dos_int:
128 mov [real_mode_segment],main
129 simulate_real_mode:
130 push 0 ; SS:SP (DPMI will allocate stack)
131 push 0 ; CS:IP (ignored)
132 push 0
133 push [real_mode_segment] ; DS
134 push [real_mode_segment] ; ES
135 stc
136 pushfw
137 push eax
138 push ecx
139 push edx
140 push ebx
141 push 0
142 push ebp
143 push esi
144 push edi
145 mov ax,300h
146 mov bx,21h
147 xor cx,cx
148 mov edi,esp
149 push es ss
150 pop es
151 int 31h
152 pop es
153 mov edi,[esp]
154 mov esi,[esp+4]
155 mov ebp,[esp+8]
156 mov ebx,[esp+10h]
157 mov edx,[esp+14h]
158 mov ecx,[esp+18h]
159 mov ah,[esp+20h]
160 add esp,32h
161 sahf
162 mov eax,[esp-32h+1Ch]
163 ret
164 dpmi_dos_int_with_buffer:
165 mov [real_mode_segment],buffer
166 jmp simulate_real_mode
167
168 get_environment_variable:
169 mov ebx,esi
170 push ds
171 mov ds,[environment_segment]
172 xor esi,esi
173 compare_variable_names:
174 mov edx,ebx
175 compare_character:
176 lodsb
177 mov ah,[es:edx]
178 inc edx
179 cmp al,'='
180 je end_of_variable_name
181 or ah,ah
182 jz next_variable
183 sub ah,al
184 jz compare_character
185 cmp ah,20h
186 jne next_variable
187 cmp al,41h
188 jb next_variable
189 cmp al,5Ah
190 jna compare_character
191 next_variable:
192 lodsb
193 or al,al
194 jnz next_variable
195 cmp byte [esi],0
196 jne compare_variable_names
197 pop ds
198 ret
199 end_of_variable_name:
200 or ah,ah
201 jnz next_variable
202 copy_variable_value:
203 lodsb
204 cmp edi,[es:memory_end]
205 jae out_of_memory
206 stosb
207 or al,al
208 jnz copy_variable_value
209 dec edi
210 pop ds
211 ret
212
213 open:
214 push esi edi
215 call adapt_path
216 mov ax,716Ch
217 mov bx,100000b
218 mov dx,1
219 xor cx,cx
220 xor si,si
221 call dos_int_with_buffer
222 jnc open_done
223 cmp ax,7100h
224 je old_open
225 stc
226 jmp open_done
227 old_open:
228 mov ax,3D00h
229 xor dx,dx
230 call dos_int_with_buffer
231 open_done:
232 mov bx,ax
233 pop edi esi
234 ret
235 adapt_path:
236 mov esi,edx
237 mov edi,[buffer_address]
238 copy_path:
239 lodsb
240 cmp al,'/'
241 jne path_char_ok
242 mov al,'\'
243 path_char_ok:
244 stosb
245 or al,al
246 jnz copy_path
247 ret
248 create:
249 push esi edi
250 call adapt_path
251 mov ax,716Ch
252 mov bx,100001b
253 mov dx,10010b
254 xor cx,cx
255 xor si,si
256 xor di,di
257 call dos_int_with_buffer
258 jnc create_done
259 cmp ax,7100h
260 je old_create
261 stc
262 jmp create_done
263 old_create:
264 mov ah,3Ch
265 xor cx,cx
266 xor dx,dx
267 call dos_int_with_buffer
268 create_done:
269 mov bx,ax
270 pop edi esi
271 ret
272 write:
273 push edx esi edi ebp
274 mov ebp,ecx
275 mov esi,edx
276 .loop:
277 mov ecx,1000h
278 sub ebp,1000h
279 jnc .write
280 add ebp,1000h
281 mov ecx,ebp
282 xor ebp,ebp
283 .write:
284 push ecx
285 mov edi,[buffer_address]
286 shr ecx,2
287 rep movsd
288 mov ecx,[esp]
289 and ecx,11b
290 rep movsb
291 pop ecx
292 mov ah,40h
293 xor dx,dx
294 call dos_int_with_buffer
295 or ebp,ebp
296 jnz .loop
297 pop ebp edi esi edx
298 ret
299 read:
300 push edx esi edi ebp
301 mov ebp,ecx
302 mov edi,edx
303 .loop:
304 mov ecx,1000h
305 sub ebp,1000h
306 jnc .read
307 add ebp,1000h
308 mov ecx,ebp
309 xor ebp,ebp
310 .read:
311 push ecx
312 mov ah,3Fh
313 xor dx,dx
314 call dos_int_with_buffer
315 cmp ax,cx
316 jne .eof
317 mov esi,[buffer_address]
318 mov ecx,[esp]
319 shr ecx,2
320 rep movsd
321 pop ecx
322 and ecx,11b
323 rep movsb
324 or ebp,ebp
325 jnz .loop
326 .exit:
327 pop ebp edi esi edx
328 ret
329 .eof:
330 pop ecx
331 stc
332 jmp .exit
333 close:
334 mov ah,3Eh
335 int 21h
336 ret
337 lseek:
338 mov ah,42h
339 mov ecx,edx
340 shr ecx,16
341 int 21h
342 pushf
343 shl edx,16
344 popf
345 mov dx,ax
346 mov eax,edx
347 ret
348
349 display_string:
350 lods byte [esi]
351 or al,al
352 jz string_end
353 mov dl,al
354 mov ah,2
355 int 21h
356 jmp display_string
357 string_end:
358 ret
359 display_number:
360 push ebx
361 mov ecx,1000000000
362 xor edx,edx
363 xor bl,bl
364 display_loop:
365 div ecx
366 push edx
367 cmp ecx,1
368 je display_digit
369 or bl,bl
370 jnz display_digit
371 or al,al
372 jz digit_ok
373 not bl
374 display_digit:
375 mov dl,al
376 add dl,30h
377 mov ah,2
378 int 21h
379 digit_ok:
380 mov eax,ecx
381 xor edx,edx
382 mov ecx,10
383 div ecx
384 mov ecx,eax
385 pop eax
386 or ecx,ecx
387 jnz display_loop
388 pop ebx
389 ret
390
391 display_user_messages:
392 mov [displayed_count],0
393 call show_display_buffer
394 cmp [displayed_count],1
395 jb line_break_ok
396 je make_line_break
397 mov ax,word [last_displayed]
398 cmp ax,0A0Dh
399 je line_break_ok
400 cmp ax,0D0Ah
401 je line_break_ok
402 make_line_break:
403 mov ah,2
404 mov dl,0Dh
405 int 21h
406 mov dl,0Ah
407 int 21h
408 line_break_ok:
409 ret
410 display_block:
411 add [displayed_count],ecx
412 cmp ecx,1
413 ja take_last_two_characters
414 jb display_character
415 mov al,[last_displayed+1]
416 mov ah,[esi]
417 mov word [last_displayed],ax
418 jmp display_character
419 take_last_two_characters:
420 mov ax,[esi+ecx-2]
421 mov word [last_displayed],ax
422 display_character:
423 lods byte [esi]
424 mov dl,al
425 mov ah,2
426 int 21h
427 loopd display_character
428 ret
429
430 fatal_error:
431 mov esi,error_prefix
432 call display_string
433 pop esi
434 call display_string
435 mov esi,error_suffix
436 call display_string
437 mov al,0FFh
438 jmp exit_program
439 assembler_error:
440 call display_user_messages
441 push dword 0
442 mov ebx,[current_line]
443 get_error_lines:
444 mov eax,[ebx]
445 cmp byte [eax],0
446 je get_next_error_line
447 push ebx
448 test byte [ebx+7],80h
449 jz display_error_line
450 mov edx,ebx
451 find_definition_origin:
452 mov edx,[edx+12]
453 test byte [edx+7],80h
454 jnz find_definition_origin
455 push edx
456 get_next_error_line:
457 mov ebx,[ebx+8]
458 jmp get_error_lines
459 display_error_line:
460 mov esi,[ebx]
461 call display_string
462 mov esi,line_number_start
463 call display_string
464 mov eax,[ebx+4]
465 and eax,7FFFFFFFh
466 call display_number
467 mov dl,']'
468 mov ah,2
469 int 21h
470 pop esi
471 cmp ebx,esi
472 je line_number_ok
473 mov dl,20h
474 mov ah,2
475 int 21h
476 push esi
477 mov esi,[esi]
478 movzx ecx,byte [esi]
479 inc esi
480 call display_block
481 mov esi,line_number_start
482 call display_string
483 pop esi
484 mov eax,[esi+4]
485 and eax,7FFFFFFFh
486 call display_number
487 mov dl,']'
488 mov ah,2
489 int 21h
490 line_number_ok:
491 mov esi,line_data_start
492 call display_string
493 mov esi,ebx
494 mov edx,[esi]
495 call open
496 mov al,2
497 xor edx,edx
498 call lseek
499 mov edx,[esi+8]
500 sub eax,edx
501 jz line_data_displayed
502 mov [counter],eax
503 xor al,al
504 call lseek
505 mov esi,[additional_memory]
506 read_line_data:
507 mov ecx,100h
508 cmp ecx,[counter]
509 jbe bytes_count_ok
510 mov ecx,[counter]
511 bytes_count_ok:
512 sub [counter],ecx
513 lea eax,[esi+ecx]
514 cmp eax,[additional_memory_end]
515 ja out_of_memory
516 push ecx
517 mov edx,esi
518 call read
519 pop ecx
520 get_line_data:
521 mov al,[esi]
522 cmp al,0Ah
523 je display_line_data
524 cmp al,0Dh
525 je display_line_data
526 cmp al,1Ah
527 je display_line_data
528 or al,al
529 jz display_line_data
530 inc esi
531 loop get_line_data
532 cmp [counter],0
533 ja read_line_data
534 display_line_data:
535 call close
536 mov ecx,esi
537 mov esi,[additional_memory]
538 sub ecx,esi
539 call display_block
540 line_data_displayed:
541 mov esi,cr_lf
542 call display_string
543 pop ebx
544 or ebx,ebx
545 jnz display_error_line
546 mov esi,error_prefix
547 call display_string
548 pop esi
549 call display_string
550 mov esi,error_suffix
551 call display_string
552 mov al,2
553 jmp exit_program
554
555 make_timestamp:
556 mov ah,2Ah
557 int 21h
558 push dx cx
559 movzx ecx,cx
560 mov eax,ecx
561 sub eax,1970
562 mov ebx,365
563 mul ebx
564 mov ebp,eax
565 mov eax,ecx
566 sub eax,1969
567 shr eax,2
568 add ebp,eax
569 mov eax,ecx
570 sub eax,1901
571 mov ebx,100
572 div ebx
573 sub ebp,eax
574 mov eax,ecx
575 xor edx,edx
576 sub eax,1601
577 mov ebx,400
578 div ebx
579 add ebp,eax
580 movzx ecx,byte [esp+3]
581 mov eax,ecx
582 dec eax
583 mov ebx,30
584 mul ebx
585 add ebp,eax
586 cmp ecx,8
587 jbe months_correction
588 mov eax,ecx
589 sub eax,7
590 shr eax,1
591 add ebp,eax
592 mov ecx,8
593 months_correction:
594 mov eax,ecx
595 shr eax,1
596 add ebp,eax
597 cmp ecx,2
598 pop cx
599 jbe day_correction_ok
600 sub ebp,2
601 test ecx,11b
602 jnz day_correction_ok
603 xor edx,edx
604 mov eax,ecx
605 mov ebx,100
606 div ebx
607 or edx,edx
608 jnz day_correction
609 mov eax,ecx
610 mov ebx,400
611 div ebx
612 or edx,edx
613 jnz day_correction_ok
614 day_correction:
615 inc ebp
616 day_correction_ok:
617 pop dx
618 movzx eax,dl
619 dec eax
620 add eax,ebp
621 mov ebx,24
622 mul ebx
623 push eax
624 mov ah,2Ch
625 int 21h
626 pop eax
627 push dx
628 movzx ebx,ch
629 add eax,ebx
630 mov ebx,60
631 mul ebx
632 movzx ebx,cl
633 add eax,ebx
634 mov ebx,60
635 mul ebx
636 pop bx
637 movzx ebx,bh
638 add eax,ebx
639 adc edx,0
640 ret
0
1 ; flat assembler interface for Linux
2 ; Copyright (c) 1999-2014, Tomasz Grysztar.
3 ; All rights reserved.
4
5 format ELF executable 3
6 entry start
7
8 segment readable executable
9
10 start:
11
12 mov [con_handle],1
13 mov esi,_logo
14 call display_string
15
16 mov [command_line],esp
17 pop eax
18 lea esp,[esp+eax*4]
19 pop eax
20 pop [environment]
21 call get_params
22 jc information
23
24 call init_memory
25
26 mov esi,_memory_prefix
27 call display_string
28 mov eax,[memory_end]
29 sub eax,[memory_start]
30 add eax,[additional_memory_end]
31 sub eax,[additional_memory]
32 shr eax,10
33 call display_number
34 mov esi,_memory_suffix
35 call display_string
36
37 mov eax,78
38 mov ebx,buffer
39 xor ecx,ecx
40 int 0x80
41 mov eax,dword [buffer]
42 mov ecx,1000
43 mul ecx
44 mov ebx,eax
45 mov eax,dword [buffer+4]
46 div ecx
47 add eax,ebx
48 mov [start_time],eax
49
50 call preprocessor
51 call parser
52 call assembler
53 call formatter
54
55 call display_user_messages
56 movzx eax,[current_pass]
57 inc eax
58 call display_number
59 mov esi,_passes_suffix
60 call display_string
61 mov eax,78
62 mov ebx,buffer
63 xor ecx,ecx
64 int 0x80
65 mov eax,dword [buffer]
66 mov ecx,1000
67 mul ecx
68 mov ebx,eax
69 mov eax,dword [buffer+4]
70 div ecx
71 add eax,ebx
72 sub eax,[start_time]
73 jnc time_ok
74 add eax,3600000
75 time_ok:
76 xor edx,edx
77 mov ebx,100
78 div ebx
79 or eax,eax
80 jz display_bytes_count
81 xor edx,edx
82 mov ebx,10
83 div ebx
84 push edx
85 call display_number
86 mov dl,'.'
87 call display_character
88 pop eax
89 call display_number
90 mov esi,_seconds_suffix
91 call display_string
92 display_bytes_count:
93 mov eax,[written_size]
94 call display_number
95 mov esi,_bytes_suffix
96 call display_string
97 xor al,al
98 jmp exit_program
99
100 information:
101 mov esi,_usage
102 call display_string
103 mov al,1
104 jmp exit_program
105
106 get_params:
107 mov ebx,[command_line]
108 mov [input_file],0
109 mov [output_file],0
110 mov [symbols_file],0
111 mov [memory_setting],0
112 mov [passes_limit],100
113 mov ecx,[ebx]
114 add ebx,8
115 dec ecx
116 jz bad_params
117 get_param:
118 mov esi,[ebx]
119 mov al,[esi]
120 cmp al,'-'
121 je option_param
122 cmp [input_file],0
123 jne get_output_file
124 mov [input_file],esi
125 jmp next_param
126 get_output_file:
127 cmp [output_file],0
128 jne bad_params
129 mov [output_file],esi
130 jmp next_param
131 option_param:
132 inc esi
133 lodsb
134 cmp al,'m'
135 je memory_option
136 cmp al,'M'
137 je memory_option
138 cmp al,'p'
139 je passes_option
140 cmp al,'P'
141 je passes_option
142 cmp al,'s'
143 je symbols_option
144 cmp al,'S'
145 je symbols_option
146 bad_params:
147 stc
148 ret
149 memory_option:
150 cmp byte [esi],0
151 jne get_memory_setting
152 dec ecx
153 jz bad_params
154 add ebx,4
155 mov esi,[ebx]
156 get_memory_setting:
157 call get_option_value
158 or edx,edx
159 jz bad_params
160 cmp edx,1 shl (32-10)
161 jae bad_params
162 mov [memory_setting],edx
163 jmp next_param
164 passes_option:
165 cmp byte [esi],0
166 jne get_passes_setting
167 dec ecx
168 jz bad_params
169 add ebx,4
170 mov esi,[ebx]
171 get_passes_setting:
172 call get_option_value
173 or edx,edx
174 jz bad_params
175 cmp edx,10000h
176 ja bad_params
177 mov [passes_limit],dx
178 next_param:
179 add ebx,4
180 dec ecx
181 jnz get_param
182 cmp [input_file],0
183 je bad_params
184 clc
185 ret
186 symbols_option:
187 cmp byte [esi],0
188 jne get_symbols_setting
189 dec ecx
190 jz bad_params
191 add ebx,4
192 mov esi,[ebx]
193 get_symbols_setting:
194 mov [symbols_file],esi
195 jmp next_param
196 get_option_value:
197 xor eax,eax
198 mov edx,eax
199 get_option_digit:
200 lodsb
201 cmp al,20h
202 je option_value_ok
203 or al,al
204 jz option_value_ok
205 sub al,30h
206 jc invalid_option_value
207 cmp al,9
208 ja invalid_option_value
209 imul edx,10
210 jo invalid_option_value
211 add edx,eax
212 jc invalid_option_value
213 jmp get_option_digit
214 option_value_ok:
215 dec esi
216 clc
217 ret
218 invalid_option_value:
219 stc
220 ret
221
222 include 'system.inc'
223
224 include '..\version.inc'
225
226 _copyright db 'Copyright (c) 1999-2014, Tomasz Grysztar',0xA,0
227
228 _logo db 'flat assembler version ',VERSION_STRING,0
229 _usage db 0xA
230 db 'usage: fasm <source> [output]',0xA
231 db 'optional settings:',0xA
232 db ' -m <limit> set the limit in kilobytes for the available memory',0Dh,0Ah
233 db ' -p <limit> set the maximum allowed number of passes',0Dh,0Ah
234 db ' -s <file> dump symbolic information for debugging',0Dh,0Ah
235 db 0
236 _memory_prefix db ' (',0
237 _memory_suffix db ' kilobytes memory)',0xA,0
238 _passes_suffix db ' passes, ',0
239 _seconds_suffix db ' seconds, ',0
240 _bytes_suffix db ' bytes.',0xA,0
241
242 include '..\errors.inc'
243 include '..\symbdump.inc'
244 include '..\preproce.inc'
245 include '..\parser.inc'
246 include '..\exprpars.inc'
247 include '..\assemble.inc'
248 include '..\exprcalc.inc'
249 include '..\formats.inc'
250 include '..\x86_64.inc'
251 include '..\avx.inc'
252
253 include '..\tables.inc'
254 include '..\messages.inc'
255
256 segment readable writeable
257
258 align 4
259
260 include '..\variable.inc'
261
262 command_line dd ?
263 memory_setting dd ?
264 environment dd ?
265 timestamp dq ?
266 start_time dd ?
267 con_handle dd ?
268 displayed_count dd ?
269 last_displayed db ?
270 character db ?
271
272 buffer rb 1000h
0
1 ; flat assembler interface for Linux
2 ; Copyright (c) 1999-2014, Tomasz Grysztar.
3 ; All rights reserved.
4
5 O_ACCMODE = 0003o
6 O_RDONLY = 0000o
7 O_WRONLY = 0001o
8 O_RDWR = 0002o
9 O_CREAT = 0100o
10 O_EXCL = 0200o
11 O_NOCTTY = 0400o
12 O_TRUNC = 1000o
13 O_APPEND = 2000o
14 O_NONBLOCK = 4000o
15
16 S_ISUID = 4000o
17 S_ISGID = 2000o
18 S_ISVTX = 1000o
19 S_IRUSR = 0400o
20 S_IWUSR = 0200o
21 S_IXUSR = 0100o
22 S_IRGRP = 0040o
23 S_IWGRP = 0020o
24 S_IXGRP = 0010o
25 S_IROTH = 0004o
26 S_IWOTH = 0002o
27 S_IXOTH = 0001o
28
29 init_memory:
30 mov eax,esp
31 and eax,not 0FFFh
32 add eax,1000h-10000h
33 mov [stack_limit],eax
34 xor ebx,ebx
35 mov eax,45
36 int 0x80
37 mov [additional_memory],eax
38 mov ecx,[memory_setting]
39 shl ecx,10
40 jnz allocate_memory
41 mov ecx,1000000h
42 allocate_memory:
43 mov ebx,[additional_memory]
44 add ebx,ecx
45 mov eax,45
46 int 0x80
47 mov [memory_end],eax
48 sub eax,[additional_memory]
49 shr eax,2
50 add eax,[additional_memory]
51 mov [additional_memory_end],eax
52 mov [memory_start],eax
53 ret
54
55 exit_program:
56 movzx ebx,al
57 mov eax,1
58 int 0x80
59
60 get_environment_variable:
61 mov ebx,esi
62 mov esi,[environment]
63 compare_variable_names:
64 mov edx,ebx
65 compare_character:
66 lodsb
67 mov ah,[edx]
68 inc edx
69 cmp al,'='
70 je end_of_variable_name
71 or ah,ah
72 jz next_variable
73 sub ah,al
74 jz compare_character
75 cmp ah,20h
76 jne next_variable
77 cmp al,41h
78 jb next_variable
79 cmp al,5Ah
80 jna compare_character
81 next_variable:
82 lodsb
83 or al,al
84 jnz next_variable
85 cmp byte [esi],0
86 jne compare_variable_names
87 ret
88 end_of_variable_name:
89 or ah,ah
90 jnz next_variable
91 copy_variable_value:
92 lodsb
93 cmp edi,[memory_end]
94 jae out_of_memory
95 stosb
96 or al,al
97 jnz copy_variable_value
98 dec edi
99 ret
100
101 open:
102 push esi edi ebp
103 call adapt_path
104 mov eax,5
105 mov ebx,buffer
106 mov ecx,O_RDONLY
107 xor edx,edx
108 int 0x80
109 pop ebp edi esi
110 test eax,eax
111 js file_error
112 mov ebx,eax
113 clc
114 ret
115 adapt_path:
116 mov esi,edx
117 mov edi,buffer
118 copy_path:
119 lods byte [esi]
120 cmp al,'\'
121 jne path_char_ok
122 mov al,'/'
123 path_char_ok:
124 stos byte [edi]
125 or al,al
126 jnz copy_path
127 cmp edi,buffer+1000h
128 ja out_of_memory
129 ret
130 create:
131 push esi edi ebp edx
132 call adapt_path
133 mov ebx,buffer
134 mov ecx,O_CREAT+O_TRUNC+O_WRONLY
135 mov edx,S_IRUSR+S_IWUSR+S_IRGRP+S_IROTH
136 pop eax
137 cmp eax,[output_file]
138 jne do_create
139 cmp [output_format],5
140 jne do_create
141 bt [format_flags],0
142 jnc do_create
143 or edx,S_IXUSR+S_IXGRP+S_IXOTH
144 do_create:
145 mov eax,5
146 int 0x80
147 pop ebp edi esi
148 test eax,eax
149 js file_error
150 mov ebx,eax
151 clc
152 ret
153 close:
154 mov eax,6
155 int 0x80
156 ret
157 read:
158 push ecx edx esi edi ebp
159 mov eax,3
160 xchg ecx,edx
161 int 0x80
162 pop ebp edi esi edx ecx
163 test eax,eax
164 js file_error
165 cmp eax,ecx
166 jne file_error
167 clc
168 ret
169 file_error:
170 stc
171 ret
172 write:
173 push edx esi edi ebp
174 mov eax,4
175 xchg ecx,edx
176 int 0x80
177 pop ebp edi esi edx
178 test eax,eax
179 js file_error
180 clc
181 ret
182 lseek:
183 mov ecx,edx
184 xor edx,edx
185 mov dl,al
186 mov eax,19
187 int 0x80
188 ret
189
190 display_string:
191 push ebx
192 mov edi,esi
193 mov edx,esi
194 or ecx,-1
195 xor al,al
196 repne scasb
197 neg ecx
198 sub ecx,2
199 mov eax,4
200 mov ebx,[con_handle]
201 xchg ecx,edx
202 int 0x80
203 pop ebx
204 ret
205 display_character:
206 push ebx
207 mov [character],dl
208 mov eax,4
209 mov ebx,[con_handle]
210 mov ecx,character
211 mov edx,1
212 int 0x80
213 pop ebx
214 ret
215 display_number:
216 push ebx
217 mov ecx,1000000000
218 xor edx,edx
219 xor bl,bl
220 display_loop:
221 div ecx
222 push edx
223 cmp ecx,1
224 je display_digit
225 or bl,bl
226 jnz display_digit
227 or al,al
228 jz digit_ok
229 not bl
230 display_digit:
231 mov dl,al
232 add dl,30h
233 push ebx ecx
234 call display_character
235 pop ecx ebx
236 digit_ok:
237 mov eax,ecx
238 xor edx,edx
239 mov ecx,10
240 div ecx
241 mov ecx,eax
242 pop eax
243 or ecx,ecx
244 jnz display_loop
245 pop ebx
246 ret
247
248 display_user_messages:
249 mov [displayed_count],0
250 call show_display_buffer
251 cmp [displayed_count],0
252 je line_break_ok
253 cmp [last_displayed],0Ah
254 je line_break_ok
255 mov dl,0Ah
256 call display_character
257 line_break_ok:
258 ret
259 display_block:
260 jecxz block_displayed
261 add [displayed_count],ecx
262 mov al,[esi+ecx-1]
263 mov [last_displayed],al
264 push ebx
265 mov eax,4
266 mov ebx,[con_handle]
267 mov edx,ecx
268 mov ecx,esi
269 int 0x80
270 pop ebx
271 block_displayed:
272 ret
273
274 fatal_error:
275 mov [con_handle],2
276 mov esi,error_prefix
277 call display_string
278 pop esi
279 call display_string
280 mov esi,error_suffix
281 call display_string
282 mov al,0FFh
283 jmp exit_program
284 assembler_error:
285 mov [con_handle],2
286 call display_user_messages
287 push dword 0
288 mov ebx,[current_line]
289 get_error_lines:
290 mov eax,[ebx]
291 cmp byte [eax],0
292 je get_next_error_line
293 push ebx
294 test byte [ebx+7],80h
295 jz display_error_line
296 mov edx,ebx
297 find_definition_origin:
298 mov edx,[edx+12]
299 test byte [edx+7],80h
300 jnz find_definition_origin
301 push edx
302 get_next_error_line:
303 mov ebx,[ebx+8]
304 jmp get_error_lines
305 display_error_line:
306 mov esi,[ebx]
307 call display_string
308 mov esi,line_number_start
309 call display_string
310 mov eax,[ebx+4]
311 and eax,7FFFFFFFh
312 call display_number
313 mov dl,']'
314 call display_character
315 pop esi
316 cmp ebx,esi
317 je line_number_ok
318 mov dl,20h
319 call display_character
320 push esi
321 mov esi,[esi]
322 movzx ecx,byte [esi]
323 inc esi
324 call display_block
325 mov esi,line_number_start
326 call display_string
327 pop esi
328 mov eax,[esi+4]
329 and eax,7FFFFFFFh
330 call display_number
331 mov dl,']'
332 call display_character
333 line_number_ok:
334 mov esi,line_data_start
335 call display_string
336 mov esi,ebx
337 mov edx,[esi]
338 call open
339 mov al,2
340 xor edx,edx
341 call lseek
342 mov edx,[esi+8]
343 sub eax,edx
344 jz line_data_displayed
345 push eax
346 xor al,al
347 call lseek
348 mov ecx,[esp]
349 mov edx,[additional_memory]
350 lea eax,[edx+ecx]
351 cmp eax,[additional_memory_end]
352 ja out_of_memory
353 call read
354 call close
355 pop ecx
356 mov esi,[additional_memory]
357 get_line_data:
358 mov al,[esi]
359 cmp al,0Ah
360 je display_line_data
361 cmp al,0Dh
362 je display_line_data
363 cmp al,1Ah
364 je display_line_data
365 or al,al
366 jz display_line_data
367 inc esi
368 loop get_line_data
369 display_line_data:
370 mov ecx,esi
371 mov esi,[additional_memory]
372 sub ecx,esi
373 call display_block
374 line_data_displayed:
375 mov esi,lf
376 call display_string
377 pop ebx
378 or ebx,ebx
379 jnz display_error_line
380 mov esi,error_prefix
381 call display_string
382 pop esi
383 call display_string
384 mov esi,error_suffix
385 call display_string
386 mov al,2
387 jmp exit_program
388
389 make_timestamp:
390 mov eax,13
391 mov ebx,timestamp
392 int 0x80
393 mov eax,dword [timestamp]
394 mov edx,dword [timestamp+4]
395 ret
396
397 error_prefix db 'error: ',0
398 error_suffix db '.'
399 lf db 0xA,0
400 line_number_start db ' [',0
401 line_data_start db ':',0xA,0
0
1 ; flat assembler interface for Win32
2 ; Copyright (c) 1999-2014, Tomasz Grysztar.
3 ; All rights reserved.
4
5 format PE console
6
7 section '.text' code readable executable
8
9 start:
10
11 mov [con_handle],STD_OUTPUT_HANDLE
12 mov esi,_logo
13 call display_string
14
15 call get_params
16 jc information
17
18 call init_memory
19
20 mov esi,_memory_prefix
21 call display_string
22 mov eax,[memory_end]
23 sub eax,[memory_start]
24 add eax,[additional_memory_end]
25 sub eax,[additional_memory]
26 shr eax,10
27 call display_number
28 mov esi,_memory_suffix
29 call display_string
30
31 call [GetTickCount]
32 mov [start_time],eax
33
34 call preprocessor
35 call parser
36 call assembler
37 call formatter
38
39 call display_user_messages
40 movzx eax,[current_pass]
41 inc eax
42 call display_number
43 mov esi,_passes_suffix
44 call display_string
45 call [GetTickCount]
46 sub eax,[start_time]
47 xor edx,edx
48 mov ebx,100
49 div ebx
50 or eax,eax
51 jz display_bytes_count
52 xor edx,edx
53 mov ebx,10
54 div ebx
55 push edx
56 call display_number
57 mov dl,'.'
58 call display_character
59 pop eax
60 call display_number
61 mov esi,_seconds_suffix
62 call display_string
63 display_bytes_count:
64 mov eax,[written_size]
65 call display_number
66 mov esi,_bytes_suffix
67 call display_string
68 xor al,al
69 jmp exit_program
70
71 information:
72 mov esi,_usage
73 call display_string
74 mov al,1
75 jmp exit_program
76
77 get_params:
78 mov [input_file],0
79 mov [output_file],0
80 mov [symbols_file],0
81 mov [memory_setting],0
82 mov [passes_limit],100
83 call [GetCommandLine]
84 mov esi,eax
85 mov edi,params
86 find_command_start:
87 lodsb
88 cmp al,20h
89 je find_command_start
90 cmp al,22h
91 je skip_quoted_name
92 skip_name:
93 lodsb
94 cmp al,20h
95 je find_param
96 or al,al
97 jz all_params
98 jmp skip_name
99 skip_quoted_name:
100 lodsb
101 cmp al,22h
102 je find_param
103 or al,al
104 jz all_params
105 jmp skip_quoted_name
106 find_param:
107 lodsb
108 cmp al,20h
109 je find_param
110 cmp al,'-'
111 je option_param
112 cmp al,0Dh
113 je all_params
114 or al,al
115 jz all_params
116 cmp [input_file],0
117 jne get_output_file
118 mov [input_file],edi
119 jmp process_param
120 get_output_file:
121 cmp [output_file],0
122 jne bad_params
123 mov [output_file],edi
124 process_param:
125 cmp al,22h
126 je string_param
127 copy_param:
128 stosb
129 lodsb
130 cmp al,20h
131 je param_end
132 cmp al,0Dh
133 je param_end
134 or al,al
135 jz param_end
136 jmp copy_param
137 string_param:
138 lodsb
139 cmp al,22h
140 je string_param_end
141 cmp al,0Dh
142 je param_end
143 or al,al
144 jz param_end
145 stosb
146 jmp string_param
147 option_param:
148 lodsb
149 cmp al,'m'
150 je memory_option
151 cmp al,'M'
152 je memory_option
153 cmp al,'p'
154 je passes_option
155 cmp al,'P'
156 je passes_option
157 cmp al,'s'
158 je symbols_option
159 cmp al,'S'
160 je symbols_option
161 bad_params:
162 stc
163 ret
164 get_option_value:
165 xor eax,eax
166 mov edx,eax
167 get_option_digit:
168 lodsb
169 cmp al,20h
170 je option_value_ok
171 cmp al,0Dh
172 je option_value_ok
173 or al,al
174 jz option_value_ok
175 sub al,30h
176 jc invalid_option_value
177 cmp al,9
178 ja invalid_option_value
179 imul edx,10
180 jo invalid_option_value
181 add edx,eax
182 jc invalid_option_value
183 jmp get_option_digit
184 option_value_ok:
185 dec esi
186 clc
187 ret
188 invalid_option_value:
189 stc
190 ret
191 memory_option:
192 lodsb
193 cmp al,20h
194 je memory_option
195 cmp al,0Dh
196 je bad_params
197 or al,al
198 jz bad_params
199 dec esi
200 call get_option_value
201 or edx,edx
202 jz bad_params
203 cmp edx,1 shl (32-10)
204 jae bad_params
205 mov [memory_setting],edx
206 jmp find_param
207 passes_option:
208 lodsb
209 cmp al,20h
210 je passes_option
211 cmp al,0Dh
212 je bad_params
213 or al,al
214 jz bad_params
215 dec esi
216 call get_option_value
217 or edx,edx
218 jz bad_params
219 cmp edx,10000h
220 ja bad_params
221 mov [passes_limit],dx
222 jmp find_param
223 symbols_option:
224 mov [symbols_file],edi
225 find_symbols_file_name:
226 lodsb
227 cmp al,20h
228 jne process_param
229 jmp find_symbols_file_name
230 param_end:
231 dec esi
232 string_param_end:
233 xor al,al
234 stosb
235 jmp find_param
236 all_params:
237 cmp [input_file],0
238 je bad_params
239 clc
240 ret
241
242 include 'system.inc'
243
244 include '..\errors.inc'
245 include '..\symbdump.inc'
246 include '..\preproce.inc'
247 include '..\parser.inc'
248 include '..\exprpars.inc'
249 include '..\assemble.inc'
250 include '..\exprcalc.inc'
251 include '..\formats.inc'
252 include '..\x86_64.inc'
253 include '..\avx.inc'
254
255 include '..\tables.inc'
256 include '..\messages.inc'
257
258 section '.data' data readable writeable
259
260 include '..\version.inc'
261
262 _copyright db 'Copyright (c) 1999-2014, Tomasz Grysztar',0Dh,0Ah,0
263
264 _logo db 'flat assembler version ',VERSION_STRING,0
265 _usage db 0Dh,0Ah
266 db 'usage: fasm <source> [output]',0Dh,0Ah
267 db 'optional settings:',0Dh,0Ah
268 db ' -m <limit> set the limit in kilobytes for the available memory',0Dh,0Ah
269 db ' -p <limit> set the maximum allowed number of passes',0Dh,0Ah
270 db ' -s <file> dump symbolic information for debugging',0Dh,0Ah
271 db 0
272 _memory_prefix db ' (',0
273 _memory_suffix db ' kilobytes memory)',0Dh,0Ah,0
274 _passes_suffix db ' passes, ',0
275 _seconds_suffix db ' seconds, ',0
276 _bytes_suffix db ' bytes.',0Dh,0Ah,0
277
278 align 4
279
280 include '..\variable.inc'
281
282 con_handle dd ?
283 memory_setting dd ?
284 start_time dd ?
285 bytes_count dd ?
286 displayed_count dd ?
287 character db ?
288 last_displayed rb 2
289
290 params rb 1000h
291 options rb 1000h
292 buffer rb 4000h
293
294 stack 10000h
295
296 section '.idata' import data readable writeable
297
298 dd 0,0,0,rva kernel_name,rva kernel_table
299 dd 0,0,0,0,0
300
301 kernel_table:
302 ExitProcess dd rva _ExitProcess
303 CreateFile dd rva _CreateFileA
304 ReadFile dd rva _ReadFile
305 WriteFile dd rva _WriteFile
306 CloseHandle dd rva _CloseHandle
307 SetFilePointer dd rva _SetFilePointer
308 GetCommandLine dd rva _GetCommandLineA
309 GetEnvironmentVariable dd rva _GetEnvironmentVariable
310 GetStdHandle dd rva _GetStdHandle
311 VirtualAlloc dd rva _VirtualAlloc
312 VirtualFree dd rva _VirtualFree
313 GetTickCount dd rva _GetTickCount
314 GetSystemTime dd rva _GetSystemTime
315 GlobalMemoryStatus dd rva _GlobalMemoryStatus
316 dd 0
317
318 kernel_name db 'KERNEL32.DLL',0
319
320 _ExitProcess dw 0
321 db 'ExitProcess',0
322 _CreateFileA dw 0
323 db 'CreateFileA',0
324 _ReadFile dw 0
325 db 'ReadFile',0
326 _WriteFile dw 0
327 db 'WriteFile',0
328 _CloseHandle dw 0
329 db 'CloseHandle',0
330 _SetFilePointer dw 0
331 db 'SetFilePointer',0
332 _GetCommandLineA dw 0
333 db 'GetCommandLineA',0
334 _GetEnvironmentVariable dw 0
335 db 'GetEnvironmentVariableA',0
336 _GetStdHandle dw 0
337 db 'GetStdHandle',0
338 _VirtualAlloc dw 0
339 db 'VirtualAlloc',0
340 _VirtualFree dw 0
341 db 'VirtualFree',0
342 _GetTickCount dw 0
343 db 'GetTickCount',0
344 _GetSystemTime dw 0
345 db 'GetSystemTime',0
346 _GlobalMemoryStatus dw 0
347 db 'GlobalMemoryStatus',0
348
349 section '.reloc' fixups data readable discardable
0
1 ; flat assembler interface for Win32
2 ; Copyright (c) 1999-2014, Tomasz Grysztar.
3 ; All rights reserved.
4
5 CREATE_NEW = 1
6 CREATE_ALWAYS = 2
7 OPEN_EXISTING = 3
8 OPEN_ALWAYS = 4
9 TRUNCATE_EXISTING = 5
10
11 FILE_SHARE_READ = 1
12 FILE_SHARE_WRITE = 2
13 FILE_SHARE_DELETE = 4
14
15 GENERIC_READ = 80000000h
16 GENERIC_WRITE = 40000000h
17
18 STD_INPUT_HANDLE = 0FFFFFFF6h
19 STD_OUTPUT_HANDLE = 0FFFFFFF5h
20 STD_ERROR_HANDLE = 0FFFFFFF4h
21
22 MEM_COMMIT = 1000h
23 MEM_RESERVE = 2000h
24 MEM_DECOMMIT = 4000h
25 MEM_RELEASE = 8000h
26 MEM_FREE = 10000h
27 MEM_PRIVATE = 20000h
28 MEM_MAPPED = 40000h
29 MEM_RESET = 80000h
30 MEM_TOP_DOWN = 100000h
31
32 PAGE_NOACCESS = 1
33 PAGE_READONLY = 2
34 PAGE_READWRITE = 4
35 PAGE_WRITECOPY = 8
36 PAGE_EXECUTE = 10h
37 PAGE_EXECUTE_READ = 20h
38 PAGE_EXECUTE_READWRITE = 40h
39 PAGE_EXECUTE_WRITECOPY = 80h
40 PAGE_GUARD = 100h
41 PAGE_NOCACHE = 200h
42
43 init_memory:
44 xor eax,eax
45 mov [memory_start],eax
46 mov eax,esp
47 and eax,not 0FFFh
48 add eax,1000h-10000h
49 mov [stack_limit],eax
50 mov eax,[memory_setting]
51 shl eax,10
52 jnz allocate_memory
53 push buffer
54 call [GlobalMemoryStatus]
55 mov eax,dword [buffer+20]
56 mov edx,dword [buffer+12]
57 cmp eax,0
58 jl large_memory
59 cmp edx,0
60 jl large_memory
61 shr eax,2
62 add eax,edx
63 jmp allocate_memory
64 large_memory:
65 mov eax,80000000h
66 allocate_memory:
67 mov edx,eax
68 shr edx,2
69 mov ecx,eax
70 sub ecx,edx
71 mov [memory_end],ecx
72 mov [additional_memory_end],edx
73 push PAGE_READWRITE
74 push MEM_COMMIT
75 push eax
76 push 0
77 call [VirtualAlloc]
78 or eax,eax
79 jz not_enough_memory
80 mov [memory_start],eax
81 add eax,[memory_end]
82 mov [memory_end],eax
83 mov [additional_memory],eax
84 add [additional_memory_end],eax
85 ret
86 not_enough_memory:
87 mov eax,[additional_memory_end]
88 shl eax,1
89 cmp eax,4000h
90 jb out_of_memory
91 jmp allocate_memory
92
93 exit_program:
94 movzx eax,al
95 push eax
96 mov eax,[memory_start]
97 test eax,eax
98 jz do_exit
99 push MEM_RELEASE
100 push 0
101 push eax
102 call [VirtualFree]
103 do_exit:
104 call [ExitProcess]
105
106 get_environment_variable:
107 mov ecx,[memory_end]
108 sub ecx,edi
109 cmp ecx,4000h
110 jbe buffer_for_variable_ok
111 mov ecx,4000h
112 buffer_for_variable_ok:
113 push ecx
114 push edi
115 push esi
116 call [GetEnvironmentVariable]
117 add edi,eax
118 cmp edi,[memory_end]
119 jae out_of_memory
120 ret
121
122 open:
123 push 0
124 push 0
125 push OPEN_EXISTING
126 push 0
127 push FILE_SHARE_READ
128 push GENERIC_READ
129 push edx
130 call [CreateFile]
131 cmp eax,-1
132 je file_error
133 mov ebx,eax
134 clc
135 ret
136 file_error:
137 stc
138 ret
139 create:
140 push 0
141 push 0
142 push CREATE_ALWAYS
143 push 0
144 push FILE_SHARE_READ
145 push GENERIC_WRITE
146 push edx
147 call [CreateFile]
148 cmp eax,-1
149 je file_error
150 mov ebx,eax
151 clc
152 ret
153 write:
154 push 0
155 push bytes_count
156 push ecx
157 push edx
158 push ebx
159 call [WriteFile]
160 or eax,eax
161 jz file_error
162 clc
163 ret
164 read:
165 mov ebp,ecx
166 push 0
167 push bytes_count
168 push ecx
169 push edx
170 push ebx
171 call [ReadFile]
172 or eax,eax
173 jz file_error
174 cmp ebp,[bytes_count]
175 jne file_error
176 clc
177 ret
178 close:
179 push ebx
180 call [CloseHandle]
181 ret
182 lseek:
183 movzx eax,al
184 push eax
185 push 0
186 push edx
187 push ebx
188 call [SetFilePointer]
189 ret
190
191 display_string:
192 push [con_handle]
193 call [GetStdHandle]
194 mov ebp,eax
195 mov edi,esi
196 or ecx,-1
197 xor al,al
198 repne scasb
199 neg ecx
200 sub ecx,2
201 push 0
202 push bytes_count
203 push ecx
204 push esi
205 push ebp
206 call [WriteFile]
207 ret
208 display_character:
209 push ebx
210 mov [character],dl
211 push [con_handle]
212 call [GetStdHandle]
213 mov ebx,eax
214 push 0
215 push bytes_count
216 push 1
217 push character
218 push ebx
219 call [WriteFile]
220 pop ebx
221 ret
222 display_number:
223 push ebx
224 mov ecx,1000000000
225 xor edx,edx
226 xor bl,bl
227 display_loop:
228 div ecx
229 push edx
230 cmp ecx,1
231 je display_digit
232 or bl,bl
233 jnz display_digit
234 or al,al
235 jz digit_ok
236 not bl
237 display_digit:
238 mov dl,al
239 add dl,30h
240 push ecx
241 call display_character
242 pop ecx
243 digit_ok:
244 mov eax,ecx
245 xor edx,edx
246 mov ecx,10
247 div ecx
248 mov ecx,eax
249 pop eax
250 or ecx,ecx
251 jnz display_loop
252 pop ebx
253 ret
254
255 display_user_messages:
256 mov [displayed_count],0
257 call show_display_buffer
258 cmp [displayed_count],1
259 jb line_break_ok
260 je make_line_break
261 mov ax,word [last_displayed]
262 cmp ax,0A0Dh
263 je line_break_ok
264 cmp ax,0D0Ah
265 je line_break_ok
266 make_line_break:
267 mov word [buffer],0A0Dh
268 push [con_handle]
269 call [GetStdHandle]
270 push 0
271 push bytes_count
272 push 2
273 push buffer
274 push eax
275 call [WriteFile]
276 line_break_ok:
277 ret
278 display_block:
279 add [displayed_count],ecx
280 cmp ecx,1
281 ja take_last_two_characters
282 jb block_displayed
283 mov al,[last_displayed+1]
284 mov ah,[esi]
285 mov word [last_displayed],ax
286 jmp block_ok
287 take_last_two_characters:
288 mov ax,[esi+ecx-2]
289 mov word [last_displayed],ax
290 block_ok:
291 push ecx
292 push [con_handle]
293 call [GetStdHandle]
294 pop ecx
295 push 0
296 push bytes_count
297 push ecx
298 push esi
299 push eax
300 call [WriteFile]
301 block_displayed:
302 ret
303
304 fatal_error:
305 mov [con_handle],STD_ERROR_HANDLE
306 mov esi,error_prefix
307 call display_string
308 pop esi
309 call display_string
310 mov esi,error_suffix
311 call display_string
312 mov al,0FFh
313 jmp exit_program
314 assembler_error:
315 mov [con_handle],STD_ERROR_HANDLE
316 call display_user_messages
317 push dword 0
318 mov ebx,[current_line]
319 get_error_lines:
320 mov eax,[ebx]
321 cmp byte [eax],0
322 je get_next_error_line
323 push ebx
324 test byte [ebx+7],80h
325 jz display_error_line
326 mov edx,ebx
327 find_definition_origin:
328 mov edx,[edx+12]
329 test byte [edx+7],80h
330 jnz find_definition_origin
331 push edx
332 get_next_error_line:
333 mov ebx,[ebx+8]
334 jmp get_error_lines
335 display_error_line:
336 mov esi,[ebx]
337 call display_string
338 mov esi,line_number_start
339 call display_string
340 mov eax,[ebx+4]
341 and eax,7FFFFFFFh
342 call display_number
343 mov dl,']'
344 call display_character
345 pop esi
346 cmp ebx,esi
347 je line_number_ok
348 mov dl,20h
349 call display_character
350 push esi
351 mov esi,[esi]
352 movzx ecx,byte [esi]
353 inc esi
354 call display_block
355 mov esi,line_number_start
356 call display_string
357 pop esi
358 mov eax,[esi+4]
359 and eax,7FFFFFFFh
360 call display_number
361 mov dl,']'
362 call display_character
363 line_number_ok:
364 mov esi,line_data_start
365 call display_string
366 mov esi,ebx
367 mov edx,[esi]
368 call open
369 mov al,2
370 xor edx,edx
371 call lseek
372 mov edx,[esi+8]
373 sub eax,edx
374 jz line_data_displayed
375 push eax
376 xor al,al
377 call lseek
378 mov ecx,[esp]
379 mov edx,[additional_memory]
380 lea eax,[edx+ecx]
381 cmp eax,[additional_memory_end]
382 ja out_of_memory
383 call read
384 call close
385 pop ecx
386 mov esi,[additional_memory]
387 get_line_data:
388 mov al,[esi]
389 cmp al,0Ah
390 je display_line_data
391 cmp al,0Dh
392 je display_line_data
393 cmp al,1Ah
394 je display_line_data
395 or al,al
396 jz display_line_data
397 inc esi
398 loop get_line_data
399 display_line_data:
400 mov ecx,esi
401 mov esi,[additional_memory]
402 sub ecx,esi
403 call display_block
404 line_data_displayed:
405 mov esi,cr_lf
406 call display_string
407 pop ebx
408 or ebx,ebx
409 jnz display_error_line
410 mov esi,error_prefix
411 call display_string
412 pop esi
413 call display_string
414 mov esi,error_suffix
415 call display_string
416 mov al,2
417 jmp exit_program
418
419 make_timestamp:
420 push buffer
421 call [GetSystemTime]
422 movzx ecx,word [buffer]
423 mov eax,ecx
424 sub eax,1970
425 mov ebx,365
426 mul ebx
427 mov ebp,eax
428 mov eax,ecx
429 sub eax,1969
430 shr eax,2
431 add ebp,eax
432 mov eax,ecx
433 sub eax,1901
434 mov ebx,100
435 div ebx
436 sub ebp,eax
437 mov eax,ecx
438 xor edx,edx
439 sub eax,1601
440 mov ebx,400
441 div ebx
442 add ebp,eax
443 movzx ecx,word [buffer+2]
444 mov eax,ecx
445 dec eax
446 mov ebx,30
447 mul ebx
448 add ebp,eax
449 cmp ecx,8
450 jbe months_correction
451 mov eax,ecx
452 sub eax,7
453 shr eax,1
454 add ebp,eax
455 mov ecx,8
456 months_correction:
457 mov eax,ecx
458 shr eax,1
459 add ebp,eax
460 cmp ecx,2
461 jbe day_correction_ok
462 sub ebp,2
463 movzx ecx,word [buffer]
464 test ecx,11b
465 jnz day_correction_ok
466 xor edx,edx
467 mov eax,ecx
468 mov ebx,100
469 div ebx
470 or edx,edx
471 jnz day_correction
472 mov eax,ecx
473 mov ebx,400
474 div ebx
475 or edx,edx
476 jnz day_correction_ok
477 day_correction:
478 inc ebp
479 day_correction_ok:
480 movzx eax,word [buffer+6]
481 dec eax
482 add eax,ebp
483 mov ebx,24
484 mul ebx
485 movzx ecx,word [buffer+8]
486 add eax,ecx
487 mov ebx,60
488 mul ebx
489 movzx ecx,word [buffer+10]
490 add eax,ecx
491 mov ebx,60
492 mul ebx
493 movzx ecx,word [buffer+12]
494 add eax,ecx
495 adc edx,0
496 ret
497
498 error_prefix db 'error: ',0
499 error_suffix db '.'
500 cr_lf db 0Dh,0Ah,0
501 line_number_start db ' [',0
502 line_data_start db ':',0Dh,0Ah,0
0
1 ; flat assembler core
2 ; Copyright (c) 1999-2014, Tomasz Grysztar.
3 ; All rights reserved.
4
5 assembler:
6 xor eax,eax
7 mov [stub_size],eax
8 mov [current_pass],ax
9 mov [resolver_flags],eax
10 mov [number_of_sections],eax
11 mov [actual_fixups_size],eax
12 assembler_loop:
13 mov eax,[labels_list]
14 mov [tagged_blocks],eax
15 mov eax,[additional_memory]
16 mov [free_additional_memory],eax
17 mov eax,[additional_memory_end]
18 mov [structures_buffer],eax
19 mov esi,[source_start]
20 mov edi,[code_start]
21 xor eax,eax
22 mov dword [adjustment],eax
23 mov dword [adjustment+4],eax
24 mov [addressing_space],eax
25 mov [error_line],eax
26 mov [counter],eax
27 mov [format_flags],eax
28 mov [number_of_relocations],eax
29 mov [undefined_data_end],eax
30 mov [file_extension],eax
31 mov [next_pass_needed],al
32 mov [output_format],al
33 mov [adjustment_sign],al
34 mov [code_type],16
35 call init_addressing_space
36 pass_loop:
37 call assemble_line
38 jnc pass_loop
39 mov eax,[additional_memory_end]
40 cmp eax,[structures_buffer]
41 je pass_done
42 sub eax,18h
43 mov eax,[eax+4]
44 mov [current_line],eax
45 jmp missing_end_directive
46 pass_done:
47 call close_pass
48 mov eax,[labels_list]
49 check_symbols:
50 cmp eax,[memory_end]
51 jae symbols_checked
52 test byte [eax+8],8
53 jz symbol_defined_ok
54 mov cx,[current_pass]
55 cmp cx,[eax+18]
56 jne symbol_defined_ok
57 test byte [eax+8],1
58 jz symbol_defined_ok
59 sub cx,[eax+16]
60 cmp cx,1
61 jne symbol_defined_ok
62 and byte [eax+8],not 1
63 or [next_pass_needed],-1
64 symbol_defined_ok:
65 test byte [eax+8],10h
66 jz use_prediction_ok
67 mov cx,[current_pass]
68 and byte [eax+8],not 10h
69 test byte [eax+8],20h
70 jnz check_use_prediction
71 cmp cx,[eax+18]
72 jne use_prediction_ok
73 test byte [eax+8],8
74 jz use_prediction_ok
75 jmp use_misprediction
76 check_use_prediction:
77 test byte [eax+8],8
78 jz use_misprediction
79 cmp cx,[eax+18]
80 je use_prediction_ok
81 use_misprediction:
82 or [next_pass_needed],-1
83 use_prediction_ok:
84 test byte [eax+8],40h
85 jz check_next_symbol
86 and byte [eax+8],not 40h
87 test byte [eax+8],4
88 jnz define_misprediction
89 mov cx,[current_pass]
90 test byte [eax+8],80h
91 jnz check_define_prediction
92 cmp cx,[eax+16]
93 jne check_next_symbol
94 test byte [eax+8],1
95 jz check_next_symbol
96 jmp define_misprediction
97 check_define_prediction:
98 test byte [eax+8],1
99 jz define_misprediction
100 cmp cx,[eax+16]
101 je check_next_symbol
102 define_misprediction:
103 or [next_pass_needed],-1
104 check_next_symbol:
105 add eax,LABEL_STRUCTURE_SIZE
106 jmp check_symbols
107 symbols_checked:
108 cmp [next_pass_needed],0
109 jne next_pass
110 mov eax,[error_line]
111 or eax,eax
112 jz assemble_ok
113 mov [current_line],eax
114 cmp [error],undefined_symbol
115 jne error_confirmed
116 mov eax,[error_info]
117 or eax,eax
118 jz error_confirmed
119 test byte [eax+8],1
120 jnz next_pass
121 error_confirmed:
122 call error_handler
123 error_handler:
124 mov eax,[error]
125 sub eax,error_handler
126 add [esp],eax
127 ret
128 next_pass:
129 inc [current_pass]
130 mov ax,[current_pass]
131 cmp ax,[passes_limit]
132 je code_cannot_be_generated
133 jmp assembler_loop
134 assemble_ok:
135 ret
136
137 create_addressing_space:
138 mov ebx,[addressing_space]
139 test ebx,ebx
140 jz init_addressing_space
141 test byte [ebx+0Ah],1
142 jnz illegal_instruction
143 mov eax,edi
144 sub eax,[ebx+18h]
145 mov [ebx+1Ch],eax
146 init_addressing_space:
147 mov ebx,[tagged_blocks]
148 mov dword [ebx-4],10h
149 mov dword [ebx-8],20h
150 sub ebx,8+20h
151 cmp ebx,edi
152 jbe out_of_memory
153 mov [tagged_blocks],ebx
154 mov [addressing_space],ebx
155 xor eax,eax
156 mov [ebx],edi
157 mov [ebx+4],eax
158 mov [ebx+8],eax
159 mov [ebx+10h],eax
160 mov [ebx+14h],eax
161 mov [ebx+18h],edi
162 mov [ebx+1Ch],eax
163 ret
164
165 assemble_line:
166 mov eax,[tagged_blocks]
167 sub eax,100h
168 cmp edi,eax
169 ja out_of_memory
170 lods byte [esi]
171 cmp al,1
172 je assemble_instruction
173 jb source_end
174 cmp al,3
175 jb define_label
176 je define_constant
177 cmp al,4
178 je label_addressing_space
179 cmp al,0Fh
180 je new_line
181 cmp al,13h
182 je code_type_setting
183 cmp al,10h
184 jne illegal_instruction
185 lods byte [esi]
186 jmp segment_prefix
187 code_type_setting:
188 lods byte [esi]
189 mov [code_type],al
190 jmp instruction_assembled
191 new_line:
192 lods dword [esi]
193 mov [current_line],eax
194 mov [prefixed_instruction],0
195 cmp [symbols_file],0
196 je continue_line
197 cmp [next_pass_needed],0
198 jne continue_line
199 mov ebx,[tagged_blocks]
200 mov dword [ebx-4],1
201 mov dword [ebx-8],14h
202 sub ebx,8+14h
203 cmp ebx,edi
204 jbe out_of_memory
205 mov [tagged_blocks],ebx
206 mov [ebx],eax
207 mov [ebx+4],edi
208 mov eax,[addressing_space]
209 mov [ebx+8],eax
210 mov al,[code_type]
211 mov [ebx+10h],al
212 continue_line:
213 cmp byte [esi],0Fh
214 je line_assembled
215 jmp assemble_line
216 define_label:
217 lods dword [esi]
218 cmp eax,0Fh
219 jb invalid_use_of_symbol
220 je reserved_word_used_as_symbol
221 mov ebx,eax
222 lods byte [esi]
223 mov [label_size],al
224 call make_label
225 jmp continue_line
226 make_label:
227 mov eax,edi
228 xor edx,edx
229 xor cl,cl
230 mov ebp,[addressing_space]
231 sub eax,[ds:ebp]
232 sbb edx,[ds:ebp+4]
233 sbb cl,[ds:ebp+8]
234 jp label_value_ok
235 call recoverable_overflow
236 label_value_ok:
237 mov [address_sign],cl
238 test byte [ds:ebp+0Ah],1
239 jnz make_virtual_label
240 or byte [ebx+9],1
241 xchg eax,[ebx]
242 xchg edx,[ebx+4]
243 mov ch,[ebx+9]
244 shr ch,1
245 and ch,1
246 neg ch
247 sub eax,[ebx]
248 sbb edx,[ebx+4]
249 sbb ch,cl
250 mov dword [adjustment],eax
251 mov dword [adjustment+4],edx
252 mov [adjustment_sign],ch
253 or al,ch
254 or eax,edx
255 setnz ah
256 jmp finish_label
257 make_virtual_label:
258 and byte [ebx+9],not 1
259 cmp eax,[ebx]
260 mov [ebx],eax
261 setne ah
262 cmp edx,[ebx+4]
263 mov [ebx+4],edx
264 setne al
265 or ah,al
266 finish_label:
267 mov ebp,[addressing_space]
268 mov ch,[ds:ebp+9]
269 mov cl,[label_size]
270 mov edx,[ds:ebp+14h]
271 mov ebp,[ds:ebp+10h]
272 finish_label_symbol:
273 mov al,[address_sign]
274 xor al,[ebx+9]
275 and al,10b
276 or ah,al
277 xor [ebx+9],al
278 cmp cl,[ebx+10]
279 mov [ebx+10],cl
280 setne al
281 or ah,al
282 cmp ch,[ebx+11]
283 mov [ebx+11],ch
284 setne al
285 or ah,al
286 cmp ebp,[ebx+12]
287 mov [ebx+12],ebp
288 setne al
289 or ah,al
290 or ch,ch
291 jz label_symbol_ok
292 cmp edx,[ebx+20]
293 mov [ebx+20],edx
294 setne al
295 or ah,al
296 label_symbol_ok:
297 mov cx,[current_pass]
298 xchg [ebx+16],cx
299 mov edx,[current_line]
300 mov [ebx+28],edx
301 and byte [ebx+8],not 2
302 test byte [ebx+8],1
303 jz new_label
304 cmp cx,[ebx+16]
305 je symbol_already_defined
306 btr dword [ebx+8],10
307 jc requalified_label
308 inc cx
309 sub cx,[ebx+16]
310 setnz al
311 or ah,al
312 jz label_made
313 test byte [ebx+8],8
314 jz label_made
315 mov cx,[current_pass]
316 cmp cx,[ebx+18]
317 jne label_made
318 requalified_label:
319 or [next_pass_needed],-1
320 label_made:
321 ret
322 new_label:
323 or byte [ebx+8],1
324 ret
325 define_constant:
326 lods dword [esi]
327 inc esi
328 cmp eax,0Fh
329 jb invalid_use_of_symbol
330 je reserved_word_used_as_symbol
331 mov edx,[eax+8]
332 push edx
333 cmp [current_pass],0
334 je get_constant_value
335 test dl,4
336 jnz get_constant_value
337 mov cx,[current_pass]
338 cmp cx,[eax+16]
339 je get_constant_value
340 or dl,4
341 mov [eax+8],dl
342 get_constant_value:
343 push eax
344 mov al,byte [esi-1]
345 push eax
346 or [size_override],-1
347 call get_value
348 pop ebx
349 mov ch,bl
350 pop ebx
351 pop ecx
352 test cl,4
353 jnz constant_referencing_mode_ok
354 and byte [ebx+8],not 4
355 constant_referencing_mode_ok:
356 xor cl,cl
357 mov ch,[value_type]
358 cmp ch,3
359 je invalid_use_of_symbol
360 make_constant:
361 and byte [ebx+9],not 1
362 cmp eax,[ebx]
363 mov [ebx],eax
364 setne ah
365 cmp edx,[ebx+4]
366 mov [ebx+4],edx
367 setne al
368 or ah,al
369 mov al,[value_sign]
370 xor al,[ebx+9]
371 and al,10b
372 or ah,al
373 xor [ebx+9],al
374 cmp cl,[ebx+10]
375 mov [ebx+10],cl
376 setne al
377 or ah,al
378 cmp ch,[ebx+11]
379 mov [ebx+11],ch
380 setne al
381 or ah,al
382 xor edx,edx
383 cmp edx,[ebx+12]
384 mov [ebx+12],edx
385 setne al
386 or ah,al
387 or ch,ch
388 jz constant_symbol_ok
389 mov edx,[symbol_identifier]
390 cmp edx,[ebx+20]
391 mov [ebx+20],edx
392 setne al
393 or ah,al
394 constant_symbol_ok:
395 mov cx,[current_pass]
396 xchg [ebx+16],cx
397 mov edx,[current_line]
398 mov [ebx+28],edx
399 test byte [ebx+8],1
400 jz new_constant
401 cmp cx,[ebx+16]
402 jne redeclare_constant
403 test byte [ebx+8],2
404 jz symbol_already_defined
405 or byte [ebx+8],4
406 and byte [ebx+9],not 4
407 jmp instruction_assembled
408 redeclare_constant:
409 btr dword [ebx+8],10
410 jc requalified_constant
411 inc cx
412 sub cx,[ebx+16]
413 setnz al
414 or ah,al
415 jz instruction_assembled
416 test byte [ebx+8],4
417 jnz instruction_assembled
418 test byte [ebx+8],8
419 jz instruction_assembled
420 mov cx,[current_pass]
421 cmp cx,[ebx+18]
422 jne instruction_assembled
423 requalified_constant:
424 or [next_pass_needed],-1
425 jmp instruction_assembled
426 new_constant:
427 or byte [ebx+8],1+2
428 jmp instruction_assembled
429 label_addressing_space:
430 lods dword [esi]
431 cmp eax,0Fh
432 jb invalid_use_of_symbol
433 je reserved_word_used_as_symbol
434 mov cx,[current_pass]
435 test byte [eax+8],1
436 jz make_addressing_space_label
437 cmp cx,[eax+16]
438 je symbol_already_defined
439 test byte [eax+9],4
440 jnz make_addressing_space_label
441 or [next_pass_needed],-1
442 make_addressing_space_label:
443 mov dx,[eax+8]
444 and dx,not (2 or 100h)
445 or dx,1 or 4 or 400h
446 mov [eax+8],dx
447 mov [eax+16],cx
448 mov edx,[current_line]
449 mov [eax+28],edx
450 mov ebx,[addressing_space]
451 mov [eax],ebx
452 or byte [ebx+0Ah],2
453 jmp continue_line
454 assemble_instruction:
455 ; mov [operand_size],0
456 ; mov [size_override],0
457 ; mov [operand_prefix],0
458 ; mov [opcode_prefix],0
459 and dword [operand_size],0
460 ; mov [rex_prefix],0
461 ; mov [vex_required],0
462 ; mov [vex_register],0
463 ; mov [immediate_size],0
464 and dword [rex_prefix],0
465 call instruction_handler
466 instruction_handler:
467 movzx ebx,word [esi]
468 mov al,[esi+2]
469 add esi,3
470 add [esp],ebx
471 ret
472 instruction_assembled:
473 mov al,[esi]
474 cmp al,0Fh
475 je line_assembled
476 or al,al
477 jnz extra_characters_on_line
478 line_assembled:
479 clc
480 ret
481 source_end:
482 dec esi
483 stc
484 ret
485
486 org_directive:
487 lods byte [esi]
488 cmp al,'('
489 jne invalid_argument
490 cmp byte [esi],'.'
491 je invalid_value
492 call get_qword_value
493 mov cl,[value_type]
494 test cl,1
495 jnz invalid_use_of_symbol
496 push eax
497 mov ebx,[addressing_space]
498 mov eax,edi
499 sub eax,[ebx+18h]
500 mov [ebx+1Ch],eax
501 test byte [ebx+0Ah],1
502 jnz in_virtual
503 call init_addressing_space
504 jmp org_space_ok
505 in_virtual:
506 call close_virtual_addressing_space
507 call init_addressing_space
508 or byte [ebx+0Ah],1
509 org_space_ok:
510 pop eax
511 mov [ebx+9],cl
512 mov cl,[value_sign]
513 sub [ebx],eax
514 sbb [ebx+4],edx
515 sbb byte [ebx+8],cl
516 jp org_value_ok
517 call recoverable_overflow
518 org_value_ok:
519 mov edx,[symbol_identifier]
520 mov [ebx+14h],edx
521 cmp [output_format],1
522 ja instruction_assembled
523 cmp edi,[code_start]
524 jne instruction_assembled
525 cmp eax,100h
526 jne instruction_assembled
527 bts [format_flags],0
528 jmp instruction_assembled
529 label_directive:
530 lods byte [esi]
531 cmp al,2
532 jne invalid_argument
533 lods dword [esi]
534 cmp eax,0Fh
535 jb invalid_use_of_symbol
536 je reserved_word_used_as_symbol
537 inc esi
538 mov ebx,eax
539 mov [label_size],0
540 lods byte [esi]
541 cmp al,':'
542 je get_label_size
543 dec esi
544 cmp al,11h
545 jne label_size_ok
546 get_label_size:
547 lods word [esi]
548 cmp al,11h
549 jne invalid_argument
550 mov [label_size],ah
551 label_size_ok:
552 cmp byte [esi],80h
553 je get_free_label_value
554 call make_label
555 jmp instruction_assembled
556 get_free_label_value:
557 inc esi
558 lods byte [esi]
559 cmp al,'('
560 jne invalid_argument
561 push ebx ecx
562 or byte [ebx+8],4
563 cmp byte [esi],'.'
564 je invalid_value
565 call get_address_value
566 or bh,bh
567 setnz ch
568 xchg ch,cl
569 mov bp,cx
570 shl ebp,16
571 xchg bl,bh
572 mov bp,bx
573 pop ecx ebx
574 and byte [ebx+8],not 4
575 mov ch,[value_type]
576 test ch,1
577 jnz invalid_use_of_symbol
578 make_free_label:
579 and byte [ebx+9],not 1
580 cmp eax,[ebx]
581 mov [ebx],eax
582 setne ah
583 cmp edx,[ebx+4]
584 mov [ebx+4],edx
585 setne al
586 or ah,al
587 mov edx,[address_symbol]
588 mov cl,[label_size]
589 call finish_label_symbol
590 jmp instruction_assembled
591 load_directive:
592 lods byte [esi]
593 cmp al,2
594 jne invalid_argument
595 lods dword [esi]
596 cmp eax,0Fh
597 jb invalid_use_of_symbol
598 je reserved_word_used_as_symbol
599 inc esi
600 push eax
601 mov al,1
602 cmp byte [esi],11h
603 jne load_size_ok
604 lods byte [esi]
605 lods byte [esi]
606 load_size_ok:
607 cmp al,8
608 ja invalid_value
609 mov [operand_size],al
610 and dword [value],0
611 and dword [value+4],0
612 lods byte [esi]
613 cmp al,82h
614 jne invalid_argument
615 call get_data_point
616 jc value_loaded
617 push esi edi
618 mov esi,ebx
619 mov edi,value
620 rep movs byte [edi],[esi]
621 pop edi esi
622 value_loaded:
623 mov [value_sign],0
624 mov eax,dword [value]
625 mov edx,dword [value+4]
626 pop ebx
627 xor cx,cx
628 jmp make_constant
629 get_data_point:
630 mov ebx,[addressing_space]
631 mov ecx,edi
632 sub ecx,[ebx+18h]
633 mov [ebx+1Ch],ecx
634 lods byte [esi]
635 cmp al,'('
636 jne invalid_argument
637 cmp byte [esi],11h
638 jne get_data_address
639 cmp word [esi+1+4],'):'
640 jne get_data_address
641 inc esi
642 lods dword [esi]
643 add esi,2
644 cmp byte [esi],'('
645 jne invalid_argument
646 inc esi
647 cmp eax,0Fh
648 jbe reserved_word_used_as_symbol
649 mov edx,undefined_symbol
650 test byte [eax+8],1
651 jz addressing_space_unavailable
652 mov edx,symbol_out_of_scope
653 mov cx,[eax+16]
654 cmp cx,[current_pass]
655 jne addressing_space_unavailable
656 test byte [eax+9],4
657 jz invalid_use_of_symbol
658 mov ebx,eax
659 mov ax,[current_pass]
660 mov [ebx+18],ax
661 or byte [ebx+8],8
662 cmp [symbols_file],0
663 je get_addressing_space
664 cmp [next_pass_needed],0
665 jne get_addressing_space
666 call store_label_reference
667 get_addressing_space:
668 mov ebx,[ebx]
669 get_data_address:
670 push ebx
671 cmp byte [esi],'.'
672 je invalid_value
673 or [size_override],-1
674 call get_address_value
675 pop ebp
676 call calculate_relative_offset
677 cmp [next_pass_needed],0
678 jne data_address_type_ok
679 cmp [value_type],0
680 jne invalid_use_of_symbol
681 data_address_type_ok:
682 mov ebx,edi
683 xor ecx,ecx
684 add ebx,eax
685 adc edx,ecx
686 mov eax,ebx
687 sub eax,[ds:ebp+18h]
688 sbb edx,ecx
689 jnz bad_data_address
690 mov cl,[operand_size]
691 add eax,ecx
692 cmp eax,[ds:ebp+1Ch]
693 ja bad_data_address
694 clc
695 ret
696 addressing_space_unavailable:
697 cmp [error_line],0
698 jne get_data_address
699 push [current_line]
700 pop [error_line]
701 mov [error],edx
702 mov [error_info],eax
703 jmp get_data_address
704 bad_data_address:
705 call recoverable_overflow
706 stc
707 ret
708 store_directive:
709 cmp byte [esi],11h
710 je sized_store
711 lods byte [esi]
712 cmp al,'('
713 jne invalid_argument
714 call get_byte_value
715 xor edx,edx
716 movzx eax,al
717 mov [operand_size],1
718 jmp store_value_ok
719 sized_store:
720 or [size_override],-1
721 call get_value
722 store_value_ok:
723 cmp [value_type],0
724 jne invalid_use_of_symbol
725 mov dword [value],eax
726 mov dword [value+4],edx
727 lods byte [esi]
728 cmp al,80h
729 jne invalid_argument
730 call get_data_point
731 jc instruction_assembled
732 push esi edi
733 mov esi,value
734 mov edi,ebx
735 rep movs byte [edi],[esi]
736 mov eax,edi
737 pop edi esi
738 cmp ebx,[undefined_data_end]
739 jae instruction_assembled
740 cmp eax,[undefined_data_start]
741 jbe instruction_assembled
742 mov [undefined_data_start],eax
743 jmp instruction_assembled
744
745 display_directive:
746 lods byte [esi]
747 cmp al,'('
748 jne invalid_argument
749 cmp byte [esi],0
750 jne display_byte
751 inc esi
752 lods dword [esi]
753 mov ecx,eax
754 push edi
755 mov edi,[tagged_blocks]
756 sub edi,8
757 sub edi,eax
758 cmp edi,[esp]
759 jbe out_of_memory
760 mov [tagged_blocks],edi
761 rep movs byte [edi],[esi]
762 stos dword [edi]
763 xor eax,eax
764 stos dword [edi]
765 pop edi
766 inc esi
767 jmp display_next
768 display_byte:
769 call get_byte_value
770 push edi
771 mov edi,[tagged_blocks]
772 sub edi,8+1
773 mov [tagged_blocks],edi
774 stos byte [edi]
775 mov eax,1
776 stos dword [edi]
777 dec eax
778 stos dword [edi]
779 pop edi
780 display_next:
781 cmp edi,[tagged_blocks]
782 ja out_of_memory
783 lods byte [esi]
784 cmp al,','
785 je display_directive
786 dec esi
787 jmp instruction_assembled
788 show_display_buffer:
789 mov eax,[tagged_blocks]
790 or eax,eax
791 jz display_done
792 mov esi,[labels_list]
793 cmp esi,eax
794 je display_done
795 display_messages:
796 sub esi,8
797 mov eax,[esi+4]
798 mov ecx,[esi]
799 sub esi,ecx
800 test eax,eax
801 jnz skip_block
802 push esi
803 call display_block
804 pop esi
805 skip_block:
806 cmp esi,[tagged_blocks]
807 jne display_messages
808 display_done:
809 ret
810
811 times_directive:
812 lods byte [esi]
813 cmp al,'('
814 jne invalid_argument
815 cmp byte [esi],'.'
816 je invalid_value
817 call get_count_value
818 cmp eax,0
819 je zero_times
820 cmp byte [esi],':'
821 jne times_argument_ok
822 inc esi
823 times_argument_ok:
824 push [counter]
825 push [counter_limit]
826 mov [counter_limit],eax
827 mov [counter],1
828 times_loop:
829 mov eax,esp
830 sub eax,100h
831 jc stack_overflow
832 cmp eax,[stack_limit]
833 jb stack_overflow
834 push esi
835 or [prefixed_instruction],-1
836 call continue_line
837 mov eax,[counter_limit]
838 cmp [counter],eax
839 je times_done
840 inc [counter]
841 pop esi
842 jmp times_loop
843 times_done:
844 pop eax
845 pop [counter_limit]
846 pop [counter]
847 jmp instruction_assembled
848 zero_times:
849 call skip_symbol
850 jnc zero_times
851 jmp instruction_assembled
852
853 virtual_directive:
854 lods byte [esi]
855 cmp al,80h
856 jne virtual_at_current
857 lods byte [esi]
858 cmp al,'('
859 jne invalid_argument
860 cmp byte [esi],'.'
861 je invalid_value
862 call get_address_value
863 mov ebp,[address_symbol]
864 or bh,bh
865 setnz ch
866 jmp set_virtual
867 virtual_at_current:
868 dec esi
869 mov ebp,[addressing_space]
870 mov al,[ds:ebp+9]
871 mov [value_type],al
872 mov eax,edi
873 xor edx,edx
874 xor cl,cl
875 sub eax,[ds:ebp]
876 sbb edx,[ds:ebp+4]
877 sbb cl,[ds:ebp+8]
878 mov [address_sign],cl
879 mov bx,[ds:ebp+10h]
880 mov cx,[ds:ebp+10h+2]
881 xchg bh,bl
882 xchg ch,cl
883 mov ebp,[ds:ebp+14h]
884 set_virtual:
885 xchg bl,bh
886 xchg cl,ch
887 shl ecx,16
888 mov cx,bx
889 push ecx eax
890 call allocate_structure_data
891 mov word [ebx],virtual_directive-instruction_handler
892 mov ecx,[addressing_space]
893 mov [ebx+12],ecx
894 mov [ebx+8],edi
895 mov ecx,[current_line]
896 mov [ebx+4],ecx
897 mov ebx,[addressing_space]
898 mov eax,edi
899 sub eax,[ebx+18h]
900 mov [ebx+1Ch],eax
901 call init_addressing_space
902 or byte [ebx+0Ah],1
903 pop eax
904 mov cl,[address_sign]
905 not eax
906 not edx
907 not cl
908 add eax,1
909 adc edx,0
910 adc cl,0
911 add eax,edi
912 adc edx,0
913 adc cl,0
914 mov [ebx],eax
915 mov [ebx+4],edx
916 mov [ebx+8],cl
917 pop dword [ebx+10h]
918 mov [ebx+14h],ebp
919 mov al,[value_type]
920 test al,1
921 jnz invalid_use_of_symbol
922 mov [ebx+9],al
923 jmp instruction_assembled
924 allocate_structure_data:
925 mov ebx,[structures_buffer]
926 sub ebx,18h
927 cmp ebx,[free_additional_memory]
928 jb out_of_memory
929 mov [structures_buffer],ebx
930 ret
931 find_structure_data:
932 mov ebx,[structures_buffer]
933 scan_structures:
934 cmp ebx,[additional_memory_end]
935 je no_such_structure
936 cmp ax,[ebx]
937 je structure_data_found
938 add ebx,18h
939 jmp scan_structures
940 structure_data_found:
941 ret
942 no_such_structure:
943 stc
944 ret
945 end_virtual:
946 call find_structure_data
947 jc unexpected_instruction
948 push ebx
949 call close_virtual_addressing_space
950 pop ebx
951 mov eax,[ebx+12]
952 mov [addressing_space],eax
953 mov edi,[ebx+8]
954 remove_structure_data:
955 push esi edi
956 mov ecx,ebx
957 sub ecx,[structures_buffer]
958 shr ecx,2
959 lea esi,[ebx-4]
960 lea edi,[esi+18h]
961 std
962 rep movs dword [edi],[esi]
963 cld
964 add [structures_buffer],18h
965 pop edi esi
966 ret
967 close_virtual_addressing_space:
968 mov ebx,[addressing_space]
969 mov eax,edi
970 sub eax,[ebx+18h]
971 mov [ebx+1Ch],eax
972 test byte [ebx+0Ah],2
973 jz addressing_space_closed
974 push esi edi ecx edx
975 mov ecx,eax
976 mov eax,[tagged_blocks]
977 mov dword [eax-4],11h
978 mov dword [eax-8],ecx
979 sub eax,8
980 sub eax,ecx
981 mov [tagged_blocks],eax
982 lea edi,[eax+ecx-1]
983 xchg eax,[ebx+18h]
984 lea esi,[eax+ecx-1]
985 mov eax,edi
986 sub eax,esi
987 std
988 shr ecx,1
989 jnc virtual_byte_ok
990 movs byte [edi],[esi]
991 virtual_byte_ok:
992 dec esi
993 dec edi
994 shr ecx,1
995 jnc virtual_word_ok
996 movs word [edi],[esi]
997 virtual_word_ok:
998 sub esi,2
999 sub edi,2
1000 rep movs dword [edi],[esi]
1001 cld
1002 xor edx,edx
1003 add [ebx],eax
1004 adc dword [ebx+4],edx
1005 adc byte [ebx+8],dl
1006 pop edx ecx edi esi
1007 addressing_space_closed:
1008 ret
1009 repeat_directive:
1010 cmp [prefixed_instruction],0
1011 jne unexpected_instruction
1012 lods byte [esi]
1013 cmp al,'('
1014 jne invalid_argument
1015 cmp byte [esi],'.'
1016 je invalid_value
1017 call get_count_value
1018 cmp eax,0
1019 je zero_repeat
1020 call allocate_structure_data
1021 mov word [ebx],repeat_directive-instruction_handler
1022 xchg eax,[counter_limit]
1023 mov [ebx+10h],eax
1024 mov eax,1
1025 xchg eax,[counter]
1026 mov [ebx+14h],eax
1027 mov [ebx+8],esi
1028 mov eax,[current_line]
1029 mov [ebx+4],eax
1030 jmp instruction_assembled
1031 end_repeat:
1032 cmp [prefixed_instruction],0
1033 jne unexpected_instruction
1034 call find_structure_data
1035 jc unexpected_instruction
1036 mov eax,[counter_limit]
1037 inc [counter]
1038 cmp [counter],eax
1039 jbe continue_repeating
1040 stop_repeat:
1041 mov eax,[ebx+10h]
1042 mov [counter_limit],eax
1043 mov eax,[ebx+14h]
1044 mov [counter],eax
1045 call remove_structure_data
1046 jmp instruction_assembled
1047 continue_repeating:
1048 mov esi,[ebx+8]
1049 jmp instruction_assembled
1050 zero_repeat:
1051 mov al,[esi]
1052 or al,al
1053 jz missing_end_directive
1054 cmp al,0Fh
1055 jne extra_characters_on_line
1056 call find_end_repeat
1057 jmp instruction_assembled
1058 find_end_repeat:
1059 call find_structure_end
1060 cmp ax,repeat_directive-instruction_handler
1061 jne unexpected_instruction
1062 ret
1063 while_directive:
1064 cmp [prefixed_instruction],0
1065 jne unexpected_instruction
1066 call allocate_structure_data
1067 mov word [ebx],while_directive-instruction_handler
1068 mov eax,1
1069 xchg eax,[counter]
1070 mov [ebx+10h],eax
1071 mov [ebx+8],esi
1072 mov eax,[current_line]
1073 mov [ebx+4],eax
1074 do_while:
1075 push ebx
1076 call calculate_logical_expression
1077 or al,al
1078 jnz while_true
1079 mov al,[esi]
1080 or al,al
1081 jz missing_end_directive
1082 cmp al,0Fh
1083 jne extra_characters_on_line
1084 stop_while:
1085 call find_end_while
1086 pop ebx
1087 mov eax,[ebx+10h]
1088 mov [counter],eax
1089 call remove_structure_data
1090 jmp instruction_assembled
1091 while_true:
1092 pop ebx
1093 jmp instruction_assembled
1094 end_while:
1095 cmp [prefixed_instruction],0
1096 jne unexpected_instruction
1097 call find_structure_data
1098 jc unexpected_instruction
1099 mov eax,[ebx+4]
1100 mov [current_line],eax
1101 inc [counter]
1102 jz too_many_repeats
1103 mov esi,[ebx+8]
1104 jmp do_while
1105 find_end_while:
1106 call find_structure_end
1107 cmp ax,while_directive-instruction_handler
1108 jne unexpected_instruction
1109 ret
1110 if_directive:
1111 cmp [prefixed_instruction],0
1112 jne unexpected_instruction
1113 call calculate_logical_expression
1114 mov dl,al
1115 mov al,[esi]
1116 or al,al
1117 jz missing_end_directive
1118 cmp al,0Fh
1119 jne extra_characters_on_line
1120 or dl,dl
1121 jnz if_true
1122 call find_else
1123 jc instruction_assembled
1124 mov al,[esi]
1125 cmp al,1
1126 jne else_true
1127 cmp word [esi+1],if_directive-instruction_handler
1128 jne else_true
1129 add esi,4
1130 jmp if_directive
1131 if_true:
1132 xor al,al
1133 make_if_structure:
1134 call allocate_structure_data
1135 mov word [ebx],if_directive-instruction_handler
1136 mov byte [ebx+2],al
1137 mov eax,[current_line]
1138 mov [ebx+4],eax
1139 jmp instruction_assembled
1140 else_true:
1141 or al,al
1142 jz missing_end_directive
1143 cmp al,0Fh
1144 jne extra_characters_on_line
1145 or al,-1
1146 jmp make_if_structure
1147 else_directive:
1148 cmp [prefixed_instruction],0
1149 jne unexpected_instruction
1150 mov ax,if_directive-instruction_handler
1151 call find_structure_data
1152 jc unexpected_instruction
1153 cmp byte [ebx+2],0
1154 jne unexpected_instruction
1155 found_else:
1156 mov al,[esi]
1157 cmp al,1
1158 jne skip_else
1159 cmp word [esi+1],if_directive-instruction_handler
1160 jne skip_else
1161 add esi,4
1162 call find_else
1163 jnc found_else
1164 call remove_structure_data
1165 jmp instruction_assembled
1166 skip_else:
1167 or al,al
1168 jz missing_end_directive
1169 cmp al,0Fh
1170 jne extra_characters_on_line
1171 call find_end_if
1172 call remove_structure_data
1173 jmp instruction_assembled
1174 end_if:
1175 cmp [prefixed_instruction],0
1176 jne unexpected_instruction
1177 call find_structure_data
1178 jc unexpected_instruction
1179 call remove_structure_data
1180 jmp instruction_assembled
1181 find_else:
1182 call find_structure_end
1183 cmp ax,else_directive-instruction_handler
1184 je else_found
1185 cmp ax,if_directive-instruction_handler
1186 jne unexpected_instruction
1187 stc
1188 ret
1189 else_found:
1190 clc
1191 ret
1192 find_end_if:
1193 call find_structure_end
1194 cmp ax,if_directive-instruction_handler
1195 jne unexpected_instruction
1196 ret
1197 find_structure_end:
1198 push [error_line]
1199 mov eax,[current_line]
1200 mov [error_line],eax
1201 find_end_directive:
1202 call skip_symbol
1203 jnc find_end_directive
1204 lods byte [esi]
1205 cmp al,0Fh
1206 jne no_end_directive
1207 lods dword [esi]
1208 mov [current_line],eax
1209 skip_labels:
1210 cmp byte [esi],2
1211 jne labels_ok
1212 add esi,6
1213 jmp skip_labels
1214 labels_ok:
1215 cmp byte [esi],1
1216 jne find_end_directive
1217 mov ax,[esi+1]
1218 cmp ax,prefix_instruction-instruction_handler
1219 je find_end_directive
1220 add esi,4
1221 cmp ax,repeat_directive-instruction_handler
1222 je skip_repeat
1223 cmp ax,while_directive-instruction_handler
1224 je skip_while
1225 cmp ax,if_directive-instruction_handler
1226 je skip_if
1227 cmp ax,else_directive-instruction_handler
1228 je structure_end
1229 cmp ax,end_directive-instruction_handler
1230 jne find_end_directive
1231 cmp byte [esi],1
1232 jne find_end_directive
1233 mov ax,[esi+1]
1234 add esi,4
1235 cmp ax,repeat_directive-instruction_handler
1236 je structure_end
1237 cmp ax,while_directive-instruction_handler
1238 je structure_end
1239 cmp ax,if_directive-instruction_handler
1240 jne find_end_directive
1241 structure_end:
1242 pop [error_line]
1243 ret
1244 no_end_directive:
1245 mov eax,[error_line]
1246 mov [current_line],eax
1247 jmp missing_end_directive
1248 skip_repeat:
1249 call find_end_repeat
1250 jmp find_end_directive
1251 skip_while:
1252 call find_end_while
1253 jmp find_end_directive
1254 skip_if:
1255 call skip_if_block
1256 jmp find_end_directive
1257 skip_if_block:
1258 call find_else
1259 jc if_block_skipped
1260 cmp byte [esi],1
1261 jne skip_after_else
1262 cmp word [esi+1],if_directive-instruction_handler
1263 jne skip_after_else
1264 add esi,4
1265 jmp skip_if_block
1266 skip_after_else:
1267 call find_end_if
1268 if_block_skipped:
1269 ret
1270 end_directive:
1271 lods byte [esi]
1272 cmp al,1
1273 jne invalid_argument
1274 lods word [esi]
1275 inc esi
1276 cmp ax,virtual_directive-instruction_handler
1277 je end_virtual
1278 cmp ax,repeat_directive-instruction_handler
1279 je end_repeat
1280 cmp ax,while_directive-instruction_handler
1281 je end_while
1282 cmp ax,if_directive-instruction_handler
1283 je end_if
1284 cmp ax,data_directive-instruction_handler
1285 je end_data
1286 jmp invalid_argument
1287 break_directive:
1288 mov ebx,[structures_buffer]
1289 mov al,[esi]
1290 or al,al
1291 jz find_breakable_structure
1292 cmp al,0Fh
1293 jne extra_characters_on_line
1294 find_breakable_structure:
1295 cmp ebx,[additional_memory_end]
1296 je unexpected_instruction
1297 mov ax,[ebx]
1298 cmp ax,repeat_directive-instruction_handler
1299 je break_repeat
1300 cmp ax,while_directive-instruction_handler
1301 je break_while
1302 cmp ax,if_directive-instruction_handler
1303 je break_if
1304 add ebx,18h
1305 jmp find_breakable_structure
1306 break_if:
1307 push [current_line]
1308 mov eax,[ebx+4]
1309 mov [current_line],eax
1310 call remove_structure_data
1311 call skip_if_block
1312 pop [current_line]
1313 mov ebx,[structures_buffer]
1314 jmp find_breakable_structure
1315 break_repeat:
1316 push ebx
1317 call find_end_repeat
1318 pop ebx
1319 jmp stop_repeat
1320 break_while:
1321 push ebx
1322 jmp stop_while
1323
1324 data_bytes:
1325 call define_data
1326 lods byte [esi]
1327 cmp al,'('
1328 je get_byte
1329 cmp al,'?'
1330 jne invalid_argument
1331 mov eax,edi
1332 mov byte [edi],0
1333 inc edi
1334 jmp undefined_data
1335 get_byte:
1336 cmp byte [esi],0
1337 je get_string
1338 call get_byte_value
1339 stos byte [edi]
1340 ret
1341 get_string:
1342 inc esi
1343 lods dword [esi]
1344 mov ecx,eax
1345 lea eax,[edi+ecx]
1346 cmp eax,[tagged_blocks]
1347 ja out_of_memory
1348 rep movs byte [edi],[esi]
1349 inc esi
1350 ret
1351 undefined_data:
1352 mov ebp,[addressing_space]
1353 test byte [ds:ebp+0Ah],1
1354 jz mark_undefined_data
1355 ret
1356 mark_undefined_data:
1357 cmp eax,[undefined_data_end]
1358 je undefined_data_ok
1359 mov [undefined_data_start],eax
1360 undefined_data_ok:
1361 mov [undefined_data_end],edi
1362 ret
1363 define_data:
1364 cmp edi,[tagged_blocks]
1365 jae out_of_memory
1366 cmp byte [esi],'('
1367 jne simple_data_value
1368 mov ebx,esi
1369 inc esi
1370 call skip_expression
1371 xchg esi,ebx
1372 cmp byte [ebx],81h
1373 jne simple_data_value
1374 inc esi
1375 call get_count_value
1376 inc esi
1377 or eax,eax
1378 jz duplicate_zero_times
1379 cmp byte [esi],'{'
1380 jne duplicate_single_data_value
1381 inc esi
1382 duplicate_data:
1383 push eax esi
1384 duplicated_values:
1385 cmp edi,[tagged_blocks]
1386 jae out_of_memory
1387 call near dword [esp+8]
1388 lods byte [esi]
1389 cmp al,','
1390 je duplicated_values
1391 cmp al,'}'
1392 jne invalid_argument
1393 pop ebx eax
1394 dec eax
1395 jz data_defined
1396 mov esi,ebx
1397 jmp duplicate_data
1398 duplicate_single_data_value:
1399 cmp edi,[tagged_blocks]
1400 jae out_of_memory
1401 push eax esi
1402 call near dword [esp+8]
1403 pop ebx eax
1404 dec eax
1405 jz data_defined
1406 mov esi,ebx
1407 jmp duplicate_single_data_value
1408 duplicate_zero_times:
1409 cmp byte [esi],'{'
1410 jne skip_single_data_value
1411 inc esi
1412 skip_data_value:
1413 call skip_symbol
1414 jc invalid_argument
1415 cmp byte [esi],'}'
1416 jne skip_data_value
1417 inc esi
1418 jmp data_defined
1419 skip_single_data_value:
1420 call skip_symbol
1421 jmp data_defined
1422 simple_data_value:
1423 cmp edi,[tagged_blocks]
1424 jae out_of_memory
1425 call near dword [esp]
1426 data_defined:
1427 lods byte [esi]
1428 cmp al,','
1429 je define_data
1430 dec esi
1431 add esp,4
1432 jmp instruction_assembled
1433 data_unicode:
1434 or [base_code],-1
1435 jmp define_words
1436 data_words:
1437 mov [base_code],0
1438 define_words:
1439 call define_data
1440 lods byte [esi]
1441 cmp al,'('
1442 je get_word
1443 cmp al,'?'
1444 jne invalid_argument
1445 mov eax,edi
1446 and word [edi],0
1447 scas word [edi]
1448 jmp undefined_data
1449 ret
1450 get_word:
1451 cmp [base_code],0
1452 je word_data_value
1453 cmp byte [esi],0
1454 je word_string
1455 word_data_value:
1456 call get_word_value
1457 call mark_relocation
1458 stos word [edi]
1459 ret
1460 word_string:
1461 inc esi
1462 lods dword [esi]
1463 mov ecx,eax
1464 jecxz word_string_ok
1465 lea eax,[edi+ecx*2]
1466 cmp eax,[tagged_blocks]
1467 ja out_of_memory
1468 xor ah,ah
1469 copy_word_string:
1470 lods byte [esi]
1471 stos word [edi]
1472 loop copy_word_string
1473 word_string_ok:
1474 inc esi
1475 ret
1476 data_dwords:
1477 call define_data
1478 lods byte [esi]
1479 cmp al,'('
1480 je get_dword
1481 cmp al,'?'
1482 jne invalid_argument
1483 mov eax,edi
1484 and dword [edi],0
1485 scas dword [edi]
1486 jmp undefined_data
1487 get_dword:
1488 push esi
1489 call get_dword_value
1490 pop ebx
1491 cmp byte [esi],':'
1492 je complex_dword
1493 call mark_relocation
1494 stos dword [edi]
1495 ret
1496 complex_dword:
1497 mov esi,ebx
1498 cmp byte [esi],'.'
1499 je invalid_value
1500 call get_word_value
1501 push eax
1502 inc esi
1503 lods byte [esi]
1504 cmp al,'('
1505 jne invalid_operand
1506 mov al,[value_type]
1507 push eax
1508 cmp byte [esi],'.'
1509 je invalid_value
1510 call get_word_value
1511 call mark_relocation
1512 stos word [edi]
1513 pop eax
1514 mov [value_type],al
1515 pop eax
1516 call mark_relocation
1517 stos word [edi]
1518 ret
1519 data_pwords:
1520 call define_data
1521 lods byte [esi]
1522 cmp al,'('
1523 je get_pword
1524 cmp al,'?'
1525 jne invalid_argument
1526 mov eax,edi
1527 and dword [edi],0
1528 scas dword [edi]
1529 and word [edi],0
1530 scas word [edi]
1531 jmp undefined_data
1532 get_pword:
1533 push esi
1534 call get_pword_value
1535 pop ebx
1536 cmp byte [esi],':'
1537 je complex_pword
1538 call mark_relocation
1539 stos dword [edi]
1540 mov ax,dx
1541 stos word [edi]
1542 ret
1543 complex_pword:
1544 mov esi,ebx
1545 cmp byte [esi],'.'
1546 je invalid_value
1547 call get_word_value
1548 push eax
1549 inc esi
1550 lods byte [esi]
1551 cmp al,'('
1552 jne invalid_operand
1553 mov al,[value_type]
1554 push eax
1555 cmp byte [esi],'.'
1556 je invalid_value
1557 call get_dword_value
1558 call mark_relocation
1559 stos dword [edi]
1560 pop eax
1561 mov [value_type],al
1562 pop eax
1563 call mark_relocation
1564 stos word [edi]
1565 ret
1566 data_qwords:
1567 call define_data
1568 lods byte [esi]
1569 cmp al,'('
1570 je get_qword
1571 cmp al,'?'
1572 jne invalid_argument
1573 mov eax,edi
1574 and dword [edi],0
1575 scas dword [edi]
1576 and dword [edi],0
1577 scas dword [edi]
1578 jmp undefined_data
1579 get_qword:
1580 call get_qword_value
1581 call mark_relocation
1582 stos dword [edi]
1583 mov eax,edx
1584 stos dword [edi]
1585 ret
1586 data_twords:
1587 call define_data
1588 lods byte [esi]
1589 cmp al,'('
1590 je get_tword
1591 cmp al,'?'
1592 jne invalid_argument
1593 mov eax,edi
1594 and dword [edi],0
1595 scas dword [edi]
1596 and dword [edi],0
1597 scas dword [edi]
1598 and word [edi],0
1599 scas word [edi]
1600 jmp undefined_data
1601 get_tword:
1602 cmp byte [esi],'.'
1603 jne complex_tword
1604 inc esi
1605 cmp word [esi+8],8000h
1606 je fp_zero_tword
1607 mov eax,[esi]
1608 stos dword [edi]
1609 mov eax,[esi+4]
1610 stos dword [edi]
1611 mov ax,[esi+8]
1612 add ax,3FFFh
1613 jo value_out_of_range
1614 cmp ax,7FFFh
1615 jge value_out_of_range
1616 cmp ax,0
1617 jg tword_exp_ok
1618 mov cx,ax
1619 neg cx
1620 inc cx
1621 cmp cx,64
1622 jae value_out_of_range
1623 cmp cx,32
1624 ja large_shift
1625 mov eax,[esi]
1626 mov edx,[esi+4]
1627 mov ebx,edx
1628 shr edx,cl
1629 shrd eax,ebx,cl
1630 jmp tword_mantissa_shift_done
1631 large_shift:
1632 sub cx,32
1633 xor edx,edx
1634 mov eax,[esi+4]
1635 shr eax,cl
1636 tword_mantissa_shift_done:
1637 jnc store_shifted_mantissa
1638 add eax,1
1639 adc edx,0
1640 store_shifted_mantissa:
1641 mov [edi-8],eax
1642 mov [edi-4],edx
1643 xor ax,ax
1644 test edx,1 shl 31
1645 jz tword_exp_ok
1646 inc ax
1647 tword_exp_ok:
1648 mov bl,[esi+11]
1649 shl bx,15
1650 or ax,bx
1651 stos word [edi]
1652 add esi,13
1653 ret
1654 fp_zero_tword:
1655 xor eax,eax
1656 stos dword [edi]
1657 stos dword [edi]
1658 mov al,[esi+11]
1659 shl ax,15
1660 stos word [edi]
1661 add esi,13
1662 ret
1663 complex_tword:
1664 call get_word_value
1665 push eax
1666 cmp byte [esi],':'
1667 jne invalid_operand
1668 inc esi
1669 lods byte [esi]
1670 cmp al,'('
1671 jne invalid_operand
1672 mov al,[value_type]
1673 push eax
1674 cmp byte [esi],'.'
1675 je invalid_value
1676 call get_qword_value
1677 call mark_relocation
1678 stos dword [edi]
1679 mov eax,edx
1680 stos dword [edi]
1681 pop eax
1682 mov [value_type],al
1683 pop eax
1684 call mark_relocation
1685 stos word [edi]
1686 ret
1687 data_file:
1688 lods word [esi]
1689 cmp ax,'('
1690 jne invalid_argument
1691 add esi,4
1692 call open_binary_file
1693 mov eax,[esi-4]
1694 lea esi,[esi+eax+1]
1695 mov al,2
1696 xor edx,edx
1697 call lseek
1698 push eax
1699 xor edx,edx
1700 cmp byte [esi],':'
1701 jne position_ok
1702 inc esi
1703 cmp byte [esi],'('
1704 jne invalid_argument
1705 inc esi
1706 cmp byte [esi],'.'
1707 je invalid_value
1708 push ebx
1709 call get_count_value
1710 pop ebx
1711 mov edx,eax
1712 sub [esp],edx
1713 jc value_out_of_range
1714 position_ok:
1715 cmp byte [esi],','
1716 jne size_ok
1717 inc esi
1718 cmp byte [esi],'('
1719 jne invalid_argument
1720 inc esi
1721 cmp byte [esi],'.'
1722 je invalid_value
1723 push ebx edx
1724 call get_count_value
1725 pop edx ebx
1726 cmp eax,[esp]
1727 ja value_out_of_range
1728 mov [esp],eax
1729 size_ok:
1730 xor al,al
1731 call lseek
1732 pop ecx
1733 mov edx,edi
1734 add edi,ecx
1735 jc out_of_memory
1736 cmp edi,[tagged_blocks]
1737 ja out_of_memory
1738 call read
1739 jc error_reading_file
1740 call close
1741 lods byte [esi]
1742 cmp al,','
1743 je data_file
1744 dec esi
1745 jmp instruction_assembled
1746 open_binary_file:
1747 push esi
1748 push edi
1749 mov eax,[current_line]
1750 find_current_source_path:
1751 mov esi,[eax]
1752 test byte [eax+7],80h
1753 jz get_current_path
1754 mov eax,[eax+8]
1755 jmp find_current_source_path
1756 get_current_path:
1757 lodsb
1758 stosb
1759 or al,al
1760 jnz get_current_path
1761 cut_current_path:
1762 cmp edi,[esp]
1763 je current_path_ok
1764 cmp byte [edi-1],'\'
1765 je current_path_ok
1766 cmp byte [edi-1],'/'
1767 je current_path_ok
1768 dec edi
1769 jmp cut_current_path
1770 current_path_ok:
1771 mov esi,[esp+4]
1772 call expand_path
1773 pop edx
1774 mov esi,edx
1775 call open
1776 jnc file_opened
1777 mov edx,[include_paths]
1778 search_in_include_paths:
1779 push edx esi
1780 mov edi,esi
1781 mov esi,[esp+4]
1782 call get_include_directory
1783 mov [esp+4],esi
1784 mov esi,[esp+8]
1785 call expand_path
1786 pop edx
1787 mov esi,edx
1788 call open
1789 pop edx
1790 jnc file_opened
1791 cmp byte [edx],0
1792 jne search_in_include_paths
1793 mov edi,esi
1794 mov esi,[esp]
1795 push edi
1796 call expand_path
1797 pop edx
1798 mov esi,edx
1799 call open
1800 jc file_not_found
1801 file_opened:
1802 mov edi,esi
1803 pop esi
1804 ret
1805 reserve_bytes:
1806 lods byte [esi]
1807 cmp al,'('
1808 jne invalid_argument
1809 cmp byte [esi],'.'
1810 je invalid_value
1811 call get_count_value
1812 mov ecx,eax
1813 mov edx,ecx
1814 add edx,edi
1815 jc out_of_memory
1816 cmp edx,[tagged_blocks]
1817 ja out_of_memory
1818 push edi
1819 cmp [next_pass_needed],0
1820 je zero_bytes
1821 add edi,ecx
1822 jmp reserved_data
1823 zero_bytes:
1824 xor eax,eax
1825 shr ecx,1
1826 jnc bytes_stosb_ok
1827 stos byte [edi]
1828 bytes_stosb_ok:
1829 shr ecx,1
1830 jnc bytes_stosw_ok
1831 stos word [edi]
1832 bytes_stosw_ok:
1833 rep stos dword [edi]
1834 reserved_data:
1835 pop eax
1836 call undefined_data
1837 jmp instruction_assembled
1838 reserve_words:
1839 lods byte [esi]
1840 cmp al,'('
1841 jne invalid_argument
1842 cmp byte [esi],'.'
1843 je invalid_value
1844 call get_count_value
1845 mov ecx,eax
1846 mov edx,ecx
1847 shl edx,1
1848 jc out_of_memory
1849 add edx,edi
1850 jc out_of_memory
1851 cmp edx,[tagged_blocks]
1852 ja out_of_memory
1853 push edi
1854 cmp [next_pass_needed],0
1855 je zero_words
1856 lea edi,[edi+ecx*2]
1857 jmp reserved_data
1858 zero_words:
1859 xor eax,eax
1860 shr ecx,1
1861 jnc words_stosw_ok
1862 stos word [edi]
1863 words_stosw_ok:
1864 rep stos dword [edi]
1865 jmp reserved_data
1866 reserve_dwords:
1867 lods byte [esi]
1868 cmp al,'('
1869 jne invalid_argument
1870 cmp byte [esi],'.'
1871 je invalid_value
1872 call get_count_value
1873 mov ecx,eax
1874 mov edx,ecx
1875 shl edx,1
1876 jc out_of_memory
1877 shl edx,1
1878 jc out_of_memory
1879 add edx,edi
1880 jc out_of_memory
1881 cmp edx,[tagged_blocks]
1882 ja out_of_memory
1883 push edi
1884 cmp [next_pass_needed],0
1885 je zero_dwords
1886 lea edi,[edi+ecx*4]
1887 jmp reserved_data
1888 zero_dwords:
1889 xor eax,eax
1890 rep stos dword [edi]
1891 jmp reserved_data
1892 reserve_pwords:
1893 lods byte [esi]
1894 cmp al,'('
1895 jne invalid_argument
1896 cmp byte [esi],'.'
1897 je invalid_value
1898 call get_count_value
1899 mov ecx,eax
1900 shl ecx,1
1901 jc out_of_memory
1902 add ecx,eax
1903 mov edx,ecx
1904 shl edx,1
1905 jc out_of_memory
1906 add edx,edi
1907 jc out_of_memory
1908 cmp edx,[tagged_blocks]
1909 ja out_of_memory
1910 push edi
1911 cmp [next_pass_needed],0
1912 je zero_words
1913 lea edi,[edi+ecx*2]
1914 jmp reserved_data
1915 reserve_qwords:
1916 lods byte [esi]
1917 cmp al,'('
1918 jne invalid_argument
1919 cmp byte [esi],'.'
1920 je invalid_value
1921 call get_count_value
1922 mov ecx,eax
1923 shl ecx,1
1924 jc out_of_memory
1925 mov edx,ecx
1926 shl edx,1
1927 jc out_of_memory
1928 shl edx,1
1929 jc out_of_memory
1930 add edx,edi
1931 jc out_of_memory
1932 cmp edx,[tagged_blocks]
1933 ja out_of_memory
1934 push edi
1935 cmp [next_pass_needed],0
1936 je zero_dwords
1937 lea edi,[edi+ecx*4]
1938 jmp reserved_data
1939 reserve_twords:
1940 lods byte [esi]
1941 cmp al,'('
1942 jne invalid_argument
1943 cmp byte [esi],'.'
1944 je invalid_value
1945 call get_count_value
1946 mov ecx,eax
1947 shl ecx,2
1948 jc out_of_memory
1949 add ecx,eax
1950 mov edx,ecx
1951 shl edx,1
1952 jc out_of_memory
1953 add edx,edi
1954 jc out_of_memory
1955 cmp edx,[tagged_blocks]
1956 ja out_of_memory
1957 push edi
1958 cmp [next_pass_needed],0
1959 je zero_words
1960 lea edi,[edi+ecx*2]
1961 jmp reserved_data
1962 align_directive:
1963 lods byte [esi]
1964 cmp al,'('
1965 jne invalid_argument
1966 cmp byte [esi],'.'
1967 je invalid_value
1968 call get_count_value
1969 mov edx,eax
1970 dec edx
1971 test eax,edx
1972 jnz invalid_align_value
1973 or eax,eax
1974 jz invalid_align_value
1975 cmp eax,1
1976 je instruction_assembled
1977 mov ecx,edi
1978 mov ebp,[addressing_space]
1979 sub ecx,[ds:ebp]
1980 cmp dword [ds:ebp+10h],0
1981 jne section_not_aligned_enough
1982 cmp byte [ds:ebp+9],0
1983 je make_alignment
1984 cmp [output_format],3
1985 je pe_alignment
1986 mov ebx,[ds:ebp+14h]
1987 cmp byte [ebx],0
1988 jne section_not_aligned_enough
1989 cmp eax,[ebx+10h]
1990 jbe make_alignment
1991 jmp section_not_aligned_enough
1992 pe_alignment:
1993 cmp eax,1000h
1994 ja section_not_aligned_enough
1995 make_alignment:
1996 dec eax
1997 and ecx,eax
1998 jz instruction_assembled
1999 neg ecx
2000 add ecx,eax
2001 inc ecx
2002 mov edx,ecx
2003 add edx,edi
2004 jc out_of_memory
2005 cmp edx,[tagged_blocks]
2006 ja out_of_memory
2007 push edi
2008 cmp [next_pass_needed],0
2009 je nops
2010 add edi,ecx
2011 jmp reserved_data
2012 invalid_align_value:
2013 cmp [error_line],0
2014 jne instruction_assembled
2015 mov eax,[current_line]
2016 mov [error_line],eax
2017 mov [error],invalid_value
2018 jmp instruction_assembled
2019 nops:
2020 mov eax,90909090h
2021 shr ecx,1
2022 jnc nops_stosb_ok
2023 stos byte [edi]
2024 nops_stosb_ok:
2025 shr ecx,1
2026 jnc nops_stosw_ok
2027 stos word [edi]
2028 nops_stosw_ok:
2029 rep stos dword [edi]
2030 jmp reserved_data
2031 err_directive:
2032 mov al,[esi]
2033 cmp al,0Fh
2034 je invoked_error
2035 or al,al
2036 jz invoked_error
2037 jmp extra_characters_on_line
2038 assert_directive:
2039 call calculate_logical_expression
2040 or al,al
2041 jnz instruction_assembled
2042 cmp [error_line],0
2043 jne instruction_assembled
2044 mov eax,[current_line]
2045 mov [error_line],eax
2046 mov [error],assertion_failed
2047 jmp instruction_assembled
0
1 ; flat assembler core
2 ; Copyright (c) 1999-2014, Tomasz Grysztar.
3 ; All rights reserved.
4
5 avx_single_source_pd_instruction:
6 or [vex_required],2
7 jmp avx_pd_instruction
8 avx_pd_instruction_imm8:
9 mov [immediate_size],1
10 avx_pd_instruction:
11 mov [opcode_prefix],66h
12 mov [mmx_size],0
13 jmp avx_instruction
14 avx_single_source_ps_instruction:
15 or [vex_required],2
16 jmp avx_ps_instruction
17 avx_ps_instruction_imm8:
18 mov [immediate_size],1
19 avx_ps_instruction:
20 mov [mmx_size],0
21 jmp avx_instruction
22 avx_sd_instruction_imm8:
23 mov [immediate_size],1
24 avx_sd_instruction:
25 mov [opcode_prefix],0F2h
26 mov [mmx_size],8
27 jmp avx_instruction
28 avx_ss_instruction_imm8:
29 mov [immediate_size],1
30 avx_ss_instruction:
31 mov [opcode_prefix],0F3h
32 mov [mmx_size],4
33 jmp avx_instruction
34 avx_cmp_pd_instruction:
35 mov [opcode_prefix],66h
36 avx_cmp_ps_instruction:
37 mov [mmx_size],0
38 mov byte [value],al
39 mov al,0C2h
40 jmp avx_instruction
41 avx_cmp_sd_instruction:
42 mov [opcode_prefix],0F2h
43 mov [mmx_size],8
44 mov byte [value],al
45 mov al,0C2h
46 jmp avx_instruction
47 avx_cmp_ss_instruction:
48 mov [opcode_prefix],0F3h
49 mov [mmx_size],4
50 mov byte [value],al
51 mov al,0C2h
52 jmp avx_instruction
53 avx_comiss_instruction:
54 or [vex_required],2
55 mov [mmx_size],4
56 jmp avx_instruction
57 avx_comisd_instruction:
58 or [vex_required],2
59 mov [opcode_prefix],66h
60 mov [mmx_size],8
61 jmp avx_instruction
62 avx_haddps_instruction:
63 mov [opcode_prefix],0F2h
64 mov [mmx_size],0
65 jmp avx_instruction
66 avx_movshdup_instruction:
67 or [vex_required],2
68 mov [opcode_prefix],0F3h
69 mov [mmx_size],0
70 jmp avx_instruction
71 avx_128bit_instruction:
72 mov [mmx_size],16
73 mov [opcode_prefix],66h
74 avx_instruction:
75 mov [base_code],0Fh
76 mov [extended_code],al
77 avx_common:
78 or [vex_required],1
79 lods byte [esi]
80 call get_size_operator
81 cmp al,10h
82 jne invalid_operand
83 avx_reg:
84 lods byte [esi]
85 call convert_avx_register
86 mov [postbyte_register],al
87 avx_vex_reg:
88 test [vex_required],2
89 jnz avx_vex_reg_ok
90 lods byte [esi]
91 cmp al,','
92 jne invalid_operand
93 call take_avx_register
94 mov [vex_register],al
95 avx_vex_reg_ok:
96 cmp [mmx_size],0
97 je avx_regs_size_ok
98 cmp ah,16
99 jne invalid_operand
100 avx_regs_size_ok:
101 lods byte [esi]
102 cmp al,','
103 jne invalid_operand
104 call take_avx_rm
105 jc avx_regs_reg
106 mov al,[extended_code]
107 mov ah,[supplemental_code]
108 cmp al,0C2h
109 je sse_cmp_mem_ok
110 cmp ax,443Ah
111 je sse_cmp_mem_ok
112 mov al,[base_code]
113 and al,11011100b
114 cmp al,11001100b
115 je sse_cmp_mem_ok
116 cmp [immediate_size],1
117 je mmx_imm8
118 cmp [immediate_size],0
119 jge instruction_ready
120 cmp byte [esi],','
121 jne invalid_operand
122 inc esi
123 call take_avx_register
124 shl al,4
125 or byte [value],al
126 test al,80h
127 jz avx_regs_mem_reg_store
128 cmp [code_type],64
129 jne invalid_operand
130 avx_regs_mem_reg_store:
131 call take_imm4_if_needed
132 call store_instruction_with_imm8
133 jmp instruction_assembled
134 avx_regs_reg:
135 mov bl,al
136 mov al,[extended_code]
137 mov ah,[supplemental_code]
138 cmp al,0C2h
139 je sse_cmp_nomem_ok
140 cmp ax,443Ah
141 je sse_cmp_nomem_ok
142 mov al,[base_code]
143 and al,11011100b
144 cmp al,11001100b
145 je sse_cmp_nomem_ok
146 cmp [immediate_size],1
147 je mmx_nomem_imm8
148 cmp [immediate_size],0
149 jge nomem_instruction_ready
150 lods byte [esi]
151 cmp al,','
152 jne invalid_operand
153 mov al,bl
154 shl al,4
155 or byte [value],al
156 test al,80h
157 jz avx_regs_reg_
158 cmp [code_type],64
159 jne invalid_operand
160 avx_regs_reg_:
161 call take_avx_rm
162 jc avx_regs_reg_reg
163 cmp [immediate_size],-2
164 jg invalid_operand
165 or [rex_prefix],8
166 call take_imm4_if_needed
167 call store_instruction_with_imm8
168 jmp instruction_assembled
169 avx_regs_reg_reg:
170 shl al,4
171 and byte [value],1111b
172 or byte [value],al
173 call take_imm4_if_needed
174 call store_nomem_instruction
175 mov al,byte [value]
176 stos byte [edi]
177 jmp instruction_assembled
178 take_avx_rm:
179 xor cl,cl
180 xchg cl,[operand_size]
181 lods byte [esi]
182 call get_size_operator
183 cmp al,'['
184 je take_avx_mem
185 mov [operand_size],cl
186 cmp al,10h
187 jne invalid_operand
188 lods byte [esi]
189 call convert_avx_register
190 cmp [mmx_size],0
191 je avx_reg_ok
192 cmp ah,16
193 jne invalid_operand
194 avx_reg_ok:
195 stc
196 ret
197 take_avx_mem:
198 push ecx
199 call get_address
200 pop eax
201 cmp [mmx_size],0
202 jne avx_smem
203 xchg al,[operand_size]
204 or al,al
205 jz avx_mem_ok
206 cmp al,[operand_size]
207 jne operand_sizes_do_not_match
208 avx_mem_ok:
209 clc
210 ret
211 avx_smem:
212 xchg al,[operand_size]
213 or al,al
214 jz avx_smem_ok
215 cmp al,[mmx_size]
216 jne invalid_operand_size
217 avx_smem_ok:
218 clc
219 ret
220 take_imm4_if_needed:
221 cmp [immediate_size],-3
222 jne imm4_ok
223 push ebx ecx edx
224 lods byte [esi]
225 cmp al,','
226 jne invalid_operand
227 lods byte [esi]
228 cmp al,'('
229 jne invalid_operand
230 call get_byte_value
231 test al,11110000b
232 jnz value_out_of_range
233 or byte [value],al
234 pop edx ecx ebx
235 imm4_ok:
236 ret
237
238 avx_single_source_128bit_instruction_38:
239 or [vex_required],2
240 avx_128bit_instruction_38:
241 mov [mmx_size],16
242 jmp avx_instruction_38_setup
243 avx_single_source_instruction_38:
244 or [vex_required],2
245 avx_instruction_38:
246 mov [mmx_size],0
247 avx_instruction_38_setup:
248 mov [opcode_prefix],66h
249 mov [supplemental_code],al
250 mov al,38h
251 jmp avx_instruction
252 avx_instruction_38_w1:
253 or [rex_prefix],8
254 jmp avx_instruction_38
255
256 avx_ss_instruction_3a_imm8:
257 mov [mmx_size],4
258 jmp avx_instruction_3a_imm8_setup
259 avx_sd_instruction_3a_imm8:
260 mov [mmx_size],8
261 jmp avx_instruction_3a_imm8_setup
262 avx_single_source_128bit_instruction_3a_imm8:
263 or [vex_required],2
264 avx_128bit_instruction_3a_imm8:
265 mov [mmx_size],16
266 jmp avx_instruction_3a_imm8_setup
267 avx_triple_source_instruction_3a:
268 mov [mmx_size],0
269 mov [immediate_size],-1
270 mov byte [value],0
271 jmp avx_instruction_3a_setup
272 avx_single_source_instruction_3a_imm8:
273 or [vex_required],2
274 avx_instruction_3a_imm8:
275 mov [mmx_size],0
276 avx_instruction_3a_imm8_setup:
277 mov [immediate_size],1
278 avx_instruction_3a_setup:
279 mov [opcode_prefix],66h
280 mov [supplemental_code],al
281 mov al,3Ah
282 jmp avx_instruction
283 avx_pclmulqdq_instruction:
284 mov byte [value],al
285 mov [mmx_size],16
286 mov al,44h
287 jmp avx_instruction_3a_setup
288
289 avx_permq_instruction:
290 or [vex_required],2
291 or [rex_prefix],8
292 avx_perm2f128_instruction:
293 mov [immediate_size],1
294 mov ah,3Ah
295 jmp avx_perm_instruction
296 avx_permd_instruction:
297 mov ah,38h
298 avx_perm_instruction:
299 mov [opcode_prefix],66h
300 mov [base_code],0Fh
301 mov [extended_code],ah
302 mov [supplemental_code],al
303 mov [mmx_size],0
304 or [vex_required],1
305 call take_avx_register
306 cmp ah,32
307 jne invalid_operand_size
308 mov [postbyte_register],al
309 jmp avx_vex_reg
310
311 avx_movdqu_instruction:
312 mov [opcode_prefix],0F3h
313 jmp avx_movps_instruction
314 avx_movpd_instruction:
315 mov [opcode_prefix],66h
316 avx_movps_instruction:
317 mov [mmx_size],0
318 or [vex_required],2
319 mov [base_code],0Fh
320 mov [extended_code],al
321 lods byte [esi]
322 call get_size_operator
323 cmp al,10h
324 je avx_reg
325 inc [extended_code]
326 test [extended_code],1
327 jnz avx_mem
328 add [extended_code],-1+10h
329 avx_mem:
330 cmp al,'['
331 jne invalid_operand
332 call get_address
333 lods byte [esi]
334 cmp al,','
335 jne invalid_operand
336 call take_avx_register
337 mov [postbyte_register],al
338 jmp instruction_ready
339 avx_movntpd_instruction:
340 mov [opcode_prefix],66h
341 avx_movntps_instruction:
342 or [vex_required],1
343 mov [base_code],0Fh
344 mov [extended_code],al
345 lods byte [esi]
346 call get_size_operator
347 jmp avx_mem
348 avx_lddqu_instruction:
349 mov [opcode_prefix],0F2h
350 mov [mmx_size],0
351 xor cx,cx
352 avx_load_instruction:
353 mov [base_code],0Fh
354 mov [extended_code],al
355 or [vex_required],1
356 call take_avx_register
357 or cl,cl
358 jz avx_load_reg_ok
359 cmp ah,cl
360 jne invalid_operand
361 avx_load_reg_ok:
362 cmp [mmx_size],0
363 je avx_load_reg_
364 xor ah,ah
365 avx_load_reg_:
366 xchg ah,[operand_size]
367 push eax
368 lods byte [esi]
369 cmp al,','
370 jne invalid_operand
371 lods byte [esi]
372 call get_size_operator
373 cmp al,10h
374 je avx_load_reg_reg
375 cmp al,'['
376 jne invalid_operand
377 call get_address
378 pop eax
379 xchg ah,[operand_size]
380 mov [postbyte_register],al
381 mov al,[mmx_size]
382 or al,al
383 jz instruction_ready
384 or ah,ah
385 jz instruction_ready
386 cmp al,ah
387 jne invalid_operand_size
388 jmp instruction_ready
389 avx_load_reg_reg:
390 lods byte [esi]
391 call convert_avx_register
392 cmp ch,ah
393 jne invalid_operand
394 mov bl,al
395 pop eax
396 xchg ah,[operand_size]
397 mov [postbyte_register],al
398 jmp nomem_instruction_ready
399
400 avx_movntdqa_instruction:
401 mov [mmx_size],0
402 xor cx,cx
403 jmp avx_load_instruction_38
404 avx_broadcastss_instruction:
405 mov [mmx_size],4
406 xor cl,cl
407 mov ch,16
408 jmp avx_load_instruction_38
409 avx_broadcastsd_instruction:
410 mov [mmx_size],8
411 mov cl,32
412 mov ch,16
413 jmp avx_load_instruction_38
414 avx_pbroadcastb_instruction:
415 mov [mmx_size],1
416 jmp avx_pbroadcast_instruction
417 avx_pbroadcastw_instruction:
418 mov [mmx_size],2
419 jmp avx_pbroadcast_instruction
420 avx_pbroadcastd_instruction:
421 mov [mmx_size],4
422 jmp avx_pbroadcast_instruction
423 avx_pbroadcastq_instruction:
424 mov [mmx_size],8
425 avx_pbroadcast_instruction:
426 xor cl,cl
427 mov ch,16
428 jmp avx_load_instruction_38
429 avx_broadcastf128_instruction:
430 mov [mmx_size],16
431 mov cl,32
432 xor ch,ch
433 avx_load_instruction_38:
434 mov [opcode_prefix],66h
435 mov [supplemental_code],al
436 mov al,38h
437 jmp avx_load_instruction
438 avx_movlpd_instruction:
439 mov [opcode_prefix],66h
440 avx_movlps_instruction:
441 mov [base_code],0Fh
442 mov [extended_code],al
443 mov [mmx_size],8
444 or [vex_required],1
445 lods byte [esi]
446 call get_size_operator
447 cmp al,10h
448 jne avx_movlps_mem
449 lods byte [esi]
450 call convert_avx_register
451 mov [postbyte_register],al
452 lods byte [esi]
453 cmp al,','
454 jne invalid_operand
455 call take_avx_register
456 mov [vex_register],al
457 cmp [operand_size],16
458 jne invalid_operand
459 mov [operand_size],0
460 lods byte [esi]
461 cmp al,','
462 jne invalid_operand
463 call take_avx_rm
464 jc invalid_operand
465 jmp instruction_ready
466 avx_movlps_mem:
467 cmp al,'['
468 jne invalid_operand
469 call get_address
470 mov al,[operand_size]
471 or al,al
472 jz avx_movlps_mem_size_ok
473 cmp al,[mmx_size]
474 jne invalid_operand_size
475 mov [operand_size],0
476 avx_movlps_mem_size_ok:
477 lods byte [esi]
478 cmp al,','
479 jne invalid_operand
480 call take_avx_register
481 cmp ah,16
482 jne invalid_operand
483 mov [postbyte_register],al
484 inc [extended_code]
485 jmp instruction_ready
486 avx_movhlps_instruction:
487 mov [base_code],0Fh
488 mov [extended_code],al
489 or [vex_required],1
490 call take_avx_register
491 cmp ah,16
492 jne invalid_operand
493 mov [postbyte_register],al
494 lods byte [esi]
495 cmp al,','
496 jne invalid_operand
497 call take_avx_register
498 mov [vex_register],al
499 lods byte [esi]
500 cmp al,','
501 jne invalid_operand
502 call take_avx_register
503 mov bl,al
504 jmp nomem_instruction_ready
505 avx_maskmov_w1_instruction:
506 or [rex_prefix],8
507 avx_maskmov_instruction:
508 call setup_66_0f_38
509 mov [mmx_size],0
510 or [vex_required],1
511 lods byte [esi]
512 call get_size_operator
513 cmp al,10h
514 jne avx_maskmov_mem
515 lods byte [esi]
516 call convert_avx_register
517 mov [postbyte_register],al
518 lods byte [esi]
519 cmp al,','
520 jne invalid_operand
521 call take_avx_register
522 mov [vex_register],al
523 lods byte [esi]
524 cmp al,','
525 jne invalid_operand
526 call take_avx_rm
527 jc invalid_operand
528 jmp instruction_ready
529 avx_maskmov_mem:
530 cmp al,'['
531 jne invalid_operand
532 call get_address
533 lods byte [esi]
534 cmp al,','
535 jne invalid_operand
536 call take_avx_register
537 mov [vex_register],al
538 lods byte [esi]
539 cmp al,','
540 jne invalid_operand
541 call take_avx_register
542 mov [postbyte_register],al
543 add [supplemental_code],2
544 jmp instruction_ready
545 setup_66_0f_38:
546 mov [extended_code],38h
547 mov [supplemental_code],al
548 mov [base_code],0Fh
549 mov [opcode_prefix],66h
550 ret
551 avx_movd_instruction:
552 or [vex_required],1
553 jmp movd_instruction
554 avx_movq_instruction:
555 or [vex_required],1
556 jmp movq_instruction
557 avx_movddup_instruction:
558 or [vex_required],1
559 mov [opcode_prefix],0F2h
560 mov [base_code],0Fh
561 mov [extended_code],al
562 lods byte [esi]
563 call get_size_operator
564 cmp al,10h
565 jne invalid_operand
566 lods byte [esi]
567 call convert_avx_register
568 mov [postbyte_register],al
569 mov [mmx_size],0
570 cmp ah,32
571 je avx_regs_size_ok
572 mov [mmx_size],8
573 jmp avx_regs_size_ok
574 avx_movmskpd_instruction:
575 mov [opcode_prefix],66h
576 avx_movmskps_instruction:
577 mov [base_code],0Fh
578 mov [extended_code],50h
579 or [vex_required],1
580 lods byte [esi]
581 call get_size_operator
582 cmp al,10h
583 jne invalid_operand
584 lods byte [esi]
585 call convert_register
586 mov [postbyte_register],al
587 cmp ah,4
588 je avx_movmskps_reg_ok
589 cmp ah,8
590 jne invalid_operand_size
591 cmp [code_type],64
592 jne invalid_operand
593 avx_movmskps_reg_ok:
594 mov [operand_size],0
595 lods byte [esi]
596 cmp al,','
597 jne invalid_operand
598 call take_avx_register
599 mov bl,al
600 jmp nomem_instruction_ready
601 avx_movsd_instruction:
602 mov [opcode_prefix],0F2h
603 mov [mmx_size],8
604 jmp avx_movs_instruction
605 avx_movss_instruction:
606 mov [opcode_prefix],0F3h
607 mov [mmx_size],4
608 avx_movs_instruction:
609 or [vex_required],1
610 mov [base_code],0Fh
611 mov [extended_code],10h
612 lods byte [esi]
613 call get_size_operator
614 cmp al,10h
615 jne avx_movlps_mem
616 lods byte [esi]
617 call convert_xmm_register
618 mov [postbyte_register],al
619 xor cl,cl
620 xchg cl,[operand_size]
621 lods byte [esi]
622 cmp al,','
623 jne invalid_operand
624 lods byte [esi]
625 call get_size_operator
626 cmp al,10h
627 jne avx_movs_reg_mem
628 mov [operand_size],cl
629 lods byte [esi]
630 call convert_avx_register
631 mov [vex_register],al
632 lods byte [esi]
633 cmp al,','
634 jne invalid_operand
635 call take_avx_register
636 mov bl,al
637 cmp bl,8
638 jb nomem_instruction_ready
639 inc [extended_code]
640 xchg bl,[postbyte_register]
641 jmp nomem_instruction_ready
642 avx_movs_reg_mem:
643 cmp al,'['
644 jne invalid_operand
645 call get_address
646 mov al,[operand_size]
647 or al,al
648 jz avx_movs_reg_mem_ok
649 cmp al,[mmx_size]
650 jne invalid_operand_size
651 avx_movs_reg_mem_ok:
652 jmp instruction_ready
653
654 avx_cvtdq2pd_instruction:
655 mov [opcode_prefix],0F3h
656 avx_cvtps2pd_instruction:
657 mov [base_code],0Fh
658 mov [extended_code],al
659 or [vex_required],1
660 call take_avx_register
661 mov [postbyte_register],al
662 lods byte [esi]
663 cmp al,','
664 jne invalid_operand
665 xor cl,cl
666 xchg cl,[operand_size]
667 lods byte [esi]
668 call get_size_operator
669 cmp al,10h
670 jne avx_cvtdq2pd_reg_mem
671 lods byte [esi]
672 call convert_xmm_register
673 mov bl,al
674 mov [operand_size],cl
675 jmp nomem_instruction_ready
676 avx_cvtdq2pd_reg_mem:
677 cmp al,'['
678 jne invalid_operand
679 mov [mmx_size],cl
680 call get_address
681 mov al,[mmx_size]
682 mov ah,al
683 xchg al,[operand_size]
684 or al,al
685 jz instruction_ready
686 shl al,1
687 cmp al,ah
688 jne invalid_operand_size
689 jmp instruction_ready
690 avx_cvtpd2dq_instruction:
691 mov [opcode_prefix],0F2h
692 jmp avx_cvtpd_instruction
693 avx_cvtpd2ps_instruction:
694 mov [opcode_prefix],66h
695 avx_cvtpd_instruction:
696 mov [base_code],0Fh
697 mov [extended_code],al
698 or [vex_required],1
699 call take_avx_register
700 mov [postbyte_register],al
701 cmp ah,16
702 jne invalid_operand
703 lods byte [esi]
704 cmp al,','
705 jne invalid_operand
706 mov [operand_size],0
707 lods byte [esi]
708 call get_size_operator
709 cmp al,10h
710 jne avx_cvtpd2dq_reg_mem
711 lods byte [esi]
712 call convert_avx_register
713 mov bl,al
714 jmp nomem_instruction_ready
715 avx_cvtpd2dq_reg_mem:
716 cmp al,'['
717 jne invalid_operand
718 call get_address
719 mov al,[operand_size]
720 or al,al
721 jz operand_size_not_specified
722 cmp al,16
723 je instruction_ready
724 cmp al,32
725 jne invalid_operand_size
726 jmp instruction_ready
727 avx_cvttps2dq_instruction:
728 or [vex_required],2
729 mov [opcode_prefix],0F3h
730 mov [mmx_size],0
731 jmp avx_instruction
732 avx_cvtsd2si_instruction:
733 or [vex_required],1
734 jmp cvtsd2si_instruction
735 avx_cvtss2si_instruction:
736 or [vex_required],1
737 jmp cvtss2si_instruction
738 avx_cvtsi2ss_instruction:
739 mov [opcode_prefix],0F3h
740 jmp avx_cvtsi_instruction
741 avx_cvtsi2sd_instruction:
742 mov [opcode_prefix],0F2h
743 avx_cvtsi_instruction:
744 mov [base_code],0Fh
745 mov [extended_code],al
746 or [vex_required],1
747 call take_avx_register
748 cmp ah,16
749 jne invalid_operand_size
750 mov [postbyte_register],al
751 lods byte [esi]
752 cmp al,','
753 jne invalid_operand
754 call take_avx_register
755 mov [vex_register],al
756 jmp cvtsi_xmmreg
757
758 avx_extractf128_instruction:
759 or [vex_required],1
760 call setup_66_0f_3a
761 lods byte [esi]
762 call get_size_operator
763 cmp al,10h
764 je avx_extractf128_reg
765 cmp al,'['
766 jne invalid_operand
767 call get_address
768 xor al,al
769 xchg al,[operand_size]
770 or al,al
771 jz avx_extractf128_mem_size_ok
772 cmp al,16
773 jne invalid_operand_size
774 avx_extractf128_mem_size_ok:
775 lods byte [esi]
776 cmp al,','
777 jne invalid_operand
778 call take_avx_register
779 cmp ah,32
780 jne invalid_operand_size
781 mov [postbyte_register],al
782 jmp mmx_imm8
783 avx_extractf128_reg:
784 lods byte [esi]
785 call convert_xmm_register
786 mov [operand_size],0
787 push eax
788 lods byte [esi]
789 cmp al,','
790 jne invalid_operand
791 call take_avx_register
792 cmp ah,32
793 jne invalid_operand_size
794 mov [postbyte_register],al
795 pop ebx
796 jmp mmx_nomem_imm8
797 setup_66_0f_3a:
798 mov [extended_code],3Ah
799 mov [supplemental_code],al
800 mov [base_code],0Fh
801 mov [opcode_prefix],66h
802 ret
803 avx_insertf128_instruction:
804 or [vex_required],1
805 call setup_66_0f_3a
806 call take_avx_register
807 cmp ah,32
808 jne invalid_operand
809 mov [postbyte_register],al
810 lods byte [esi]
811 cmp al,','
812 jne invalid_operand
813 call take_avx_register
814 mov [vex_register],al
815 mov [operand_size],0
816 mov [mmx_size],16
817 lods byte [esi]
818 cmp al,','
819 jne invalid_operand
820 call take_avx_rm
821 mov [operand_size],32
822 jnc mmx_imm8
823 mov bl,al
824 jmp mmx_nomem_imm8
825 avx_extractps_instruction:
826 or [vex_required],1
827 jmp extractps_instruction
828 avx_insertps_instruction:
829 or [vex_required],1
830 call take_avx_register
831 cmp ah,16
832 jne invalid_operand_size
833 mov [postbyte_register],al
834 lods byte [esi]
835 cmp al,','
836 jne invalid_operand
837 call take_avx_register
838 mov [vex_register],al
839 jmp insertps_xmmreg
840 avx_pextrb_instruction:
841 or [vex_required],1
842 jmp pextrb_instruction
843 avx_pextrw_instruction:
844 or [vex_required],1
845 jmp pextrw_instruction
846 avx_pextrd_instruction:
847 or [vex_required],1
848 jmp pextrd_instruction
849 avx_pextrq_instruction:
850 or [vex_required],1
851 jmp pextrq_instruction
852 avx_pinsrb_instruction:
853 mov [mmx_size],1
854 or [vex_required],1
855 jmp avx_pinsr_instruction_3a
856 avx_pinsrw_instruction:
857 mov [mmx_size],2
858 or [vex_required],1
859 jmp avx_pinsr_instruction
860 avx_pinsrd_instruction:
861 mov [mmx_size],4
862 or [vex_required],1
863 jmp avx_pinsr_instruction_3a
864 avx_pinsrq_instruction:
865 mov [mmx_size],8
866 or [vex_required],1
867 call operand_64bit
868 avx_pinsr_instruction_3a:
869 mov [supplemental_code],al
870 mov al,3Ah
871 avx_pinsr_instruction:
872 mov [opcode_prefix],66h
873 mov [base_code],0Fh
874 mov [extended_code],al
875 call take_avx_register
876 cmp ah,16
877 jne invalid_operand_size
878 mov [postbyte_register],al
879 lods byte [esi]
880 cmp al,','
881 jne invalid_operand
882 call take_avx_register
883 mov [vex_register],al
884 jmp pinsr_xmmreg
885 avx_maskmovdqu_instruction:
886 or [vex_required],1
887 jmp maskmovdqu_instruction
888 avx_pmovmskb_instruction:
889 or [vex_required],1
890 mov [opcode_prefix],66h
891 mov [base_code],0Fh
892 mov [extended_code],al
893 lods byte [esi]
894 call get_size_operator
895 cmp al,10h
896 jne invalid_operand
897 lods byte [esi]
898 call convert_register
899 cmp ah,4
900 je avx_pmovmskb_reg_size_ok
901 cmp [code_type],64
902 jne invalid_operand_size
903 cmp ah,8
904 jnz invalid_operand_size
905 avx_pmovmskb_reg_size_ok:
906 mov [postbyte_register],al
907 mov [operand_size],0
908 lods byte [esi]
909 cmp al,','
910 jne invalid_operand
911 call take_avx_register
912 mov bl,al
913 jmp nomem_instruction_ready
914 avx_pshufd_instruction:
915 or [vex_required],1
916 mov [mmx_size],0
917 mov [opcode_prefix],al
918 mov [base_code],0Fh
919 mov [extended_code],70h
920 call take_avx_register
921 mov [postbyte_register],al
922 lods byte [esi]
923 cmp al,','
924 jne invalid_operand
925 call take_avx_rm
926 jnc mmx_imm8
927 mov bl,al
928 jmp mmx_nomem_imm8
929
930 avx_pmovsxbw_instruction:
931 mov [mmx_size],8
932 jmp avx_pmovsx_instruction
933 avx_pmovsxbd_instruction:
934 mov [mmx_size],4
935 jmp avx_pmovsx_instruction
936 avx_pmovsxbq_instruction:
937 mov [mmx_size],2
938 jmp avx_pmovsx_instruction
939 avx_pmovsxwd_instruction:
940 mov [mmx_size],8
941 jmp avx_pmovsx_instruction
942 avx_pmovsxwq_instruction:
943 mov [mmx_size],4
944 jmp avx_pmovsx_instruction
945 avx_pmovsxdq_instruction:
946 mov [mmx_size],8
947 avx_pmovsx_instruction:
948 or [vex_required],1
949 call setup_66_0f_38
950 call take_avx_register
951 mov [postbyte_register],al
952 lods byte [esi]
953 cmp al,','
954 jne invalid_operand
955 xor al,al
956 xchg al,[operand_size]
957 push eax
958 lods byte [esi]
959 call get_size_operator
960 cmp al,10h
961 je avx_pmovsx_xmmreg_reg
962 cmp al,'['
963 jne invalid_operand
964 call get_address
965 pop eax
966 cmp al,32
967 jb avx_pmovsx_size_check
968 shl [mmx_size],1
969 avx_pmovsx_size_check:
970 xchg al,[operand_size]
971 test al,al
972 jz instruction_ready
973 cmp al,[mmx_size]
974 jne invalid_operand_size
975 jmp instruction_ready
976 avx_pmovsx_xmmreg_reg:
977 lods byte [esi]
978 call convert_xmm_register
979 mov bl,al
980 pop eax
981 mov [operand_size],al
982 jmp nomem_instruction_ready
983 avx_permil_instruction:
984 call setup_66_0f_3a
985 or [vex_required],1
986 call take_avx_register
987 mov [postbyte_register],al
988 lods byte [esi]
989 cmp al,','
990 jne invalid_operand
991 lods byte [esi]
992 call get_size_operator
993 cmp al,'['
994 je avx_permil_reg_mem
995 cmp al,10h
996 jne invalid_operand
997 lods byte [esi]
998 call convert_avx_register
999 mov [vex_register],al
1000 lods byte [esi]
1001 cmp al,','
1002 jne invalid_operand
1003 push esi
1004 xor cl,cl
1005 xchg cl,[operand_size]
1006 lods byte [esi]
1007 call get_size_operator
1008 xchg cl,[operand_size]
1009 pop esi
1010 cmp al,'['
1011 je avx_permil_reg_reg_mem
1012 cmp al,10h
1013 jne avx_permil_reg_reg_imm8
1014 call take_avx_register
1015 mov bl,al
1016 mov [extended_code],38h
1017 add [supplemental_code],8
1018 jmp nomem_instruction_ready
1019 avx_permil_reg_reg_mem:
1020 lods byte [esi]
1021 call get_size_operator
1022 call get_address
1023 mov [extended_code],38h
1024 add [supplemental_code],8
1025 jmp instruction_ready
1026 avx_permil_reg_reg_imm8:
1027 dec esi
1028 xor bl,bl
1029 xchg bl,[vex_register]
1030 jmp mmx_nomem_imm8
1031 avx_permil_reg_mem:
1032 call get_address
1033 jmp mmx_imm8
1034 avx_bit_shift_instruction:
1035 mov [opcode_prefix],66h
1036 mov [base_code],0Fh
1037 mov [extended_code],al
1038 or [vex_required],1
1039 call take_avx_register
1040 mov [postbyte_register],al
1041 lods byte [esi]
1042 cmp al,','
1043 jne invalid_operand
1044 call take_avx_register
1045 mov [vex_register],al
1046 lods byte [esi]
1047 cmp al,','
1048 jne invalid_operand
1049 push esi
1050 xor cl,cl
1051 xchg cl,[operand_size]
1052 lods byte [esi]
1053 call get_size_operator
1054 cmp al,10h
1055 je avx_bit_shift_regs_reg
1056 pop esi
1057 cmp al,'['
1058 je avx_bit_shift_regs_mem
1059 xchg cl,[operand_size]
1060 dec esi
1061 mov bl,[extended_code]
1062 mov al,bl
1063 shr bl,4
1064 and al,1111b
1065 add al,70h
1066 mov [extended_code],al
1067 sub bl,0Ch
1068 shl bl,1
1069 xchg bl,[postbyte_register]
1070 xchg bl,[vex_register]
1071 jmp mmx_nomem_imm8
1072 avx_bit_shift_regs_reg:
1073 pop eax
1074 lods byte [esi]
1075 call convert_xmm_register
1076 xchg cl,[operand_size]
1077 mov bl,al
1078 jmp nomem_instruction_ready
1079 avx_bit_shift_regs_mem:
1080 push ecx
1081 lods byte [esi]
1082 call get_size_operator
1083 call get_address
1084 pop eax
1085 xchg al,[operand_size]
1086 test al,al
1087 jz instruction_ready
1088 cmp al,16
1089 jne invalid_operand_size
1090 jmp instruction_ready
1091 avx_pslldq_instruction:
1092 mov [postbyte_register],al
1093 mov [opcode_prefix],66h
1094 mov [base_code],0Fh
1095 mov [extended_code],73h
1096 or [vex_required],1
1097 call take_avx_register
1098 mov [vex_register],al
1099 lods byte [esi]
1100 cmp al,','
1101 jne invalid_operand
1102 call take_avx_register
1103 mov bl,al
1104 jmp mmx_nomem_imm8
1105
1106 vzeroall_instruction:
1107 mov [operand_size],32
1108 vzeroupper_instruction:
1109 mov [base_code],0Fh
1110 mov [extended_code],al
1111 or [vex_required],1
1112 call store_instruction_code
1113 jmp instruction_assembled
1114 vldmxcsr_instruction:
1115 or [vex_required],1
1116 jmp fxsave_instruction
1117 vcvtph2ps_instruction:
1118 mov [opcode_prefix],66h
1119 mov [supplemental_code],al
1120 mov al,38h
1121 jmp avx_cvtps2pd_instruction
1122 vcvtps2ph_instruction:
1123 call setup_66_0f_3a
1124 or [vex_required],1
1125 lods byte [esi]
1126 call get_size_operator
1127 cmp al,10h
1128 je vcvtps2ph_reg
1129 cmp al,'['
1130 jne invalid_operand
1131 call get_address
1132 lods byte [esi]
1133 cmp al,','
1134 jne invalid_operand
1135 shl [operand_size],1
1136 call take_avx_register
1137 mov [postbyte_register],al
1138 jmp mmx_imm8
1139 vcvtps2ph_reg:
1140 lods byte [esi]
1141 call convert_xmm_register
1142 mov bl,al
1143 mov [operand_size],0
1144 lods byte [esi]
1145 cmp al,','
1146 jne invalid_operand
1147 call take_avx_register
1148 mov [postbyte_register],al
1149 jmp mmx_nomem_imm8
1150
1151 bmi_instruction:
1152 mov [base_code],0Fh
1153 mov [extended_code],38h
1154 mov [supplemental_code],0F3h
1155 mov [postbyte_register],al
1156 bmi_reg:
1157 or [vex_required],1
1158 lods byte [esi]
1159 call get_size_operator
1160 cmp al,10h
1161 jne invalid_operand
1162 lods byte [esi]
1163 call convert_register
1164 mov [vex_register],al
1165 lods byte [esi]
1166 cmp al,','
1167 jne invalid_operand
1168 lods byte [esi]
1169 call get_size_operator
1170 cmp al,10h
1171 je bmi_reg_reg
1172 cmp al,'['
1173 jne invalid_argument
1174 call get_address
1175 call operand_32or64
1176 jmp instruction_ready
1177 bmi_reg_reg:
1178 lods byte [esi]
1179 call convert_register
1180 mov bl,al
1181 call operand_32or64
1182 jmp nomem_instruction_ready
1183 operand_32or64:
1184 mov al,[operand_size]
1185 cmp al,4
1186 je operand_32or64_ok
1187 cmp al,8
1188 jne invalid_operand_size
1189 cmp [code_type],64
1190 jne invalid_operand
1191 or [rex_prefix],8
1192 operand_32or64_ok:
1193 ret
1194 pdep_instruction:
1195 mov [opcode_prefix],0F2h
1196 jmp andn_instruction
1197 pext_instruction:
1198 mov [opcode_prefix],0F3h
1199 andn_instruction:
1200 mov [base_code],0Fh
1201 mov [extended_code],38h
1202 mov [supplemental_code],al
1203 or [vex_required],1
1204 lods byte [esi]
1205 call get_size_operator
1206 cmp al,10h
1207 jne invalid_operand
1208 lods byte [esi]
1209 call convert_register
1210 mov [postbyte_register],al
1211 lods byte [esi]
1212 cmp al,','
1213 jne invalid_operand
1214 jmp bmi_reg
1215 sarx_instruction:
1216 mov [opcode_prefix],0F3h
1217 jmp bzhi_instruction
1218 shrx_instruction:
1219 mov [opcode_prefix],0F2h
1220 jmp bzhi_instruction
1221 shlx_instruction:
1222 mov [opcode_prefix],66h
1223 bzhi_instruction:
1224 mov [base_code],0Fh
1225 mov [extended_code],38h
1226 mov [supplemental_code],al
1227 or [vex_required],1
1228 call get_reg_mem
1229 jc bzhi_reg_reg
1230 call get_vex_source_register
1231 jc invalid_operand
1232 call operand_32or64
1233 jmp instruction_ready
1234 bzhi_reg_reg:
1235 call get_vex_source_register
1236 jc invalid_operand
1237 call operand_32or64
1238 jmp nomem_instruction_ready
1239 get_vex_source_register:
1240 lods byte [esi]
1241 cmp al,','
1242 jne invalid_operand
1243 lods byte [esi]
1244 call get_size_operator
1245 cmp al,10h
1246 jne no_vex_source_register
1247 lods byte [esi]
1248 call convert_register
1249 mov [vex_register],al
1250 clc
1251 ret
1252 no_vex_source_register:
1253 stc
1254 ret
1255 bextr_instruction:
1256 mov [base_code],0Fh
1257 mov [extended_code],38h
1258 mov [supplemental_code],al
1259 or [vex_required],1
1260 call get_reg_mem
1261 jc bextr_reg_reg
1262 call get_vex_source_register
1263 jc bextr_reg_mem_imm32
1264 call operand_32or64
1265 jmp instruction_ready
1266 bextr_reg_reg:
1267 call get_vex_source_register
1268 jc bextr_reg_reg_imm32
1269 call operand_32or64
1270 jmp nomem_instruction_ready
1271 setup_bextr_imm_opcode:
1272 mov [xop_opcode_map],0Ah
1273 mov [base_code],10h
1274 call operand_32or64
1275 ret
1276 bextr_reg_mem_imm32:
1277 call get_imm32
1278 call setup_bextr_imm_opcode
1279 jmp store_instruction_with_imm32
1280 bextr_reg_reg_imm32:
1281 call get_imm32
1282 call setup_bextr_imm_opcode
1283 store_nomem_instruction_with_imm32:
1284 call store_nomem_instruction
1285 mov eax,dword [value]
1286 call mark_relocation
1287 stos dword [edi]
1288 jmp instruction_assembled
1289 get_imm32:
1290 cmp al,'('
1291 jne invalid_operand
1292 push edx ebx ecx
1293 call get_dword_value
1294 mov dword [value],eax
1295 pop ecx ebx edx
1296 ret
1297 rorx_instruction:
1298 mov [opcode_prefix],0F2h
1299 mov [base_code],0Fh
1300 mov [extended_code],3Ah
1301 mov [supplemental_code],al
1302 or [vex_required],1
1303 call get_reg_mem
1304 jc rorx_reg_reg
1305 call operand_32or64
1306 jmp mmx_imm8
1307 rorx_reg_reg:
1308 call operand_32or64
1309 jmp mmx_nomem_imm8
1310
1311 fma_instruction_pd:
1312 or [rex_prefix],8
1313 fma_instruction_ps:
1314 mov [mmx_size],0
1315 jmp avx_instruction_38_setup
1316 fma_instruction_sd:
1317 or [rex_prefix],8
1318 mov [mmx_size],8
1319 jmp avx_instruction_38_setup
1320 fma_instruction_ss:
1321 mov [mmx_size],4
1322 jmp avx_instruction_38_setup
1323
1324 fma4_instruction_p:
1325 mov [mmx_size],0
1326 jmp fma4_instruction_setup
1327 fma4_instruction_sd:
1328 mov [mmx_size],8
1329 jmp fma4_instruction_setup
1330 fma4_instruction_ss:
1331 mov [mmx_size],4
1332 fma4_instruction_setup:
1333 mov [immediate_size],-2
1334 mov byte [value],0
1335 jmp avx_instruction_3a_setup
1336
1337 xop_single_source_sd_instruction:
1338 or [vex_required],2
1339 mov [mmx_size],8
1340 jmp xop_instruction_9
1341 xop_single_source_ss_instruction:
1342 or [vex_required],2
1343 mov [mmx_size],4
1344 jmp xop_instruction_9
1345 xop_single_source_instruction:
1346 or [vex_required],2
1347 mov [mmx_size],0
1348 xop_instruction_9:
1349 mov [base_code],al
1350 mov [xop_opcode_map],9
1351 jmp avx_common
1352 xop_single_source_128bit_instruction:
1353 or [vex_required],2
1354 mov [mmx_size],16
1355 jmp xop_instruction_9
1356 xop_triple_source_128bit_instruction:
1357 mov [immediate_size],-1
1358 mov byte [value],0
1359 mov [mmx_size],16
1360 jmp xop_instruction_8
1361 xop_128bit_instruction:
1362 mov [immediate_size],-2
1363 mov byte [value],0
1364 mov [mmx_size],16
1365 xop_instruction_8:
1366 mov [base_code],al
1367 mov [xop_opcode_map],8
1368 jmp avx_common
1369 xop_pcom_b_instruction:
1370 mov ah,0CCh
1371 jmp xop_pcom_instruction
1372 xop_pcom_d_instruction:
1373 mov ah,0CEh
1374 jmp xop_pcom_instruction
1375 xop_pcom_q_instruction:
1376 mov ah,0CFh
1377 jmp xop_pcom_instruction
1378 xop_pcom_w_instruction:
1379 mov ah,0CDh
1380 jmp xop_pcom_instruction
1381 xop_pcom_ub_instruction:
1382 mov ah,0ECh
1383 jmp xop_pcom_instruction
1384 xop_pcom_ud_instruction:
1385 mov ah,0EEh
1386 jmp xop_pcom_instruction
1387 xop_pcom_uq_instruction:
1388 mov ah,0EFh
1389 jmp xop_pcom_instruction
1390 xop_pcom_uw_instruction:
1391 mov ah,0EDh
1392 xop_pcom_instruction:
1393 mov byte [value],al
1394 mov [mmx_size],16
1395 mov [base_code],ah
1396 mov [xop_opcode_map],8
1397 jmp avx_common
1398 vpcmov_instruction:
1399 or [vex_required],1
1400 mov [immediate_size],-2
1401 mov byte [value],0
1402 mov [mmx_size],0
1403 mov [base_code],al
1404 mov [xop_opcode_map],8
1405 jmp avx_common
1406 xop_shift_instruction:
1407 mov [base_code],al
1408 or [vex_required],1
1409 mov [xop_opcode_map],9
1410 call take_avx_register
1411 cmp ah,16
1412 jne invalid_operand
1413 mov [postbyte_register],al
1414 lods byte [esi]
1415 cmp al,','
1416 jne invalid_operand
1417 lods byte [esi]
1418 call get_size_operator
1419 cmp al,'['
1420 je xop_shift_reg_mem
1421 cmp al,10h
1422 jne invalid_operand
1423 lods byte [esi]
1424 call convert_xmm_register
1425 mov [vex_register],al
1426 lods byte [esi]
1427 cmp al,','
1428 jne invalid_operand
1429 push esi
1430 xor cl,cl
1431 xchg cl,[operand_size]
1432 lods byte [esi]
1433 call get_size_operator
1434 pop esi
1435 xchg cl,[operand_size]
1436 cmp al,'['
1437 je xop_shift_reg_reg_mem
1438 cmp al,10h
1439 jne xop_shift_reg_reg_imm
1440 call take_avx_register
1441 mov bl,al
1442 xchg bl,[vex_register]
1443 jmp nomem_instruction_ready
1444 xop_shift_reg_reg_mem:
1445 or [rex_prefix],8
1446 lods byte [esi]
1447 call get_size_operator
1448 call get_address
1449 jmp instruction_ready
1450 xop_shift_reg_reg_imm:
1451 xor bl,bl
1452 xchg bl,[vex_register]
1453 cmp [base_code],94h
1454 jae invalid_operand
1455 add [base_code],30h
1456 mov [xop_opcode_map],8
1457 dec esi
1458 jmp mmx_nomem_imm8
1459 xop_shift_reg_mem:
1460 call get_address
1461 lods byte [esi]
1462 cmp al,','
1463 jne invalid_operand
1464 push esi
1465 xor cl,cl
1466 xchg cl,[operand_size]
1467 lods byte [esi]
1468 call get_size_operator
1469 pop esi
1470 xchg cl,[operand_size]
1471 cmp al,10h
1472 jne xop_shift_reg_mem_imm
1473 call take_avx_register
1474 mov [vex_register],al
1475 jmp instruction_ready
1476 xop_shift_reg_mem_imm:
1477 cmp [base_code],94h
1478 jae invalid_operand
1479 add [base_code],30h
1480 mov [xop_opcode_map],8
1481 dec esi
1482 jmp mmx_imm8
1483
1484 vpermil_2pd_instruction:
1485 mov [immediate_size],-2
1486 mov byte [value],al
1487 mov al,49h
1488 jmp vpermil2_instruction_setup
1489 vpermil_2ps_instruction:
1490 mov [immediate_size],-2
1491 mov byte [value],al
1492 mov al,48h
1493 jmp vpermil2_instruction_setup
1494 vpermil2_instruction:
1495 mov [immediate_size],-3
1496 mov byte [value],0
1497 vpermil2_instruction_setup:
1498 mov [base_code],0Fh
1499 mov [supplemental_code],al
1500 mov al,3Ah
1501 mov [mmx_size],0
1502 jmp avx_instruction
1503
1504 tbm_instruction:
1505 mov [xop_opcode_map],9
1506 mov ah,al
1507 shr ah,4
1508 and al,111b
1509 mov [base_code],ah
1510 mov [postbyte_register],al
1511 jmp bmi_reg
1512
1513 llwpcb_instruction:
1514 or [vex_required],1
1515 mov [xop_opcode_map],9
1516 mov [base_code],12h
1517 mov [postbyte_register],al
1518 lods byte [esi]
1519 call get_size_operator
1520 cmp al,10h
1521 jne invalid_operand
1522 lods byte [esi]
1523 call convert_register
1524 mov bl,al
1525 call operand_32or64
1526 jmp nomem_instruction_ready
1527 lwpins_instruction:
1528 or [vex_required],1
1529 mov [xop_opcode_map],0Ah
1530 mov [base_code],12h
1531 mov [vex_register],al
1532 lods byte [esi]
1533 call get_size_operator
1534 cmp al,10h
1535 jne invalid_operand
1536 lods byte [esi]
1537 call convert_register
1538 mov [postbyte_register],al
1539 lods byte [esi]
1540 cmp al,','
1541 jne invalid_operand
1542 xor cl,cl
1543 xchg cl,[operand_size]
1544 lods byte [esi]
1545 call get_size_operator
1546 cmp al,10h
1547 je lwpins_reg_reg
1548 cmp al,'['
1549 jne invalid_argument
1550 push ecx
1551 call get_address
1552 pop eax
1553 xchg al,[operand_size]
1554 test al,al
1555 jz lwpins_reg_mem_size_ok
1556 cmp al,4
1557 jne invalid_operand_size
1558 lwpins_reg_mem_size_ok:
1559 call prepare_lwpins
1560 jmp store_instruction_with_imm32
1561 lwpins_reg_reg:
1562 lods byte [esi]
1563 call convert_register
1564 cmp ah,4
1565 jne invalid_operand_size
1566 mov [operand_size],cl
1567 mov bl,al
1568 call prepare_lwpins
1569 jmp store_nomem_instruction_with_imm32
1570 prepare_lwpins:
1571 lods byte [esi]
1572 cmp al,','
1573 jne invalid_operand
1574 lods byte [esi]
1575 call get_imm32
1576 call operand_32or64
1577 mov al,[vex_register]
1578 xchg al,[postbyte_register]
1579 mov [vex_register],al
1580 ret
1581
1582 gather_instruction_pd:
1583 or [rex_prefix],8
1584 gather_instruction_ps:
1585 call setup_66_0f_38
1586 or [vex_required],4
1587 call take_avx_register
1588 mov [postbyte_register],al
1589 lods byte [esi]
1590 cmp al,','
1591 jne invalid_operand
1592 xor cl,cl
1593 xchg cl,[operand_size]
1594 push ecx
1595 lods byte [esi]
1596 call get_size_operator
1597 cmp al,'['
1598 jne invalid_argument
1599 call get_address
1600 pop eax
1601 xchg al,[operand_size]
1602 test al,al
1603 jz gather_elements_size_ok
1604 test [rex_prefix],8
1605 jnz gather_elements_64bit
1606 cmp al,4
1607 jne invalid_operand_size
1608 jmp gather_elements_size_ok
1609 gather_elements_64bit:
1610 cmp al,8
1611 jne invalid_operand_size
1612 gather_elements_size_ok:
1613 lods byte [esi]
1614 cmp al,','
1615 jne invalid_operand
1616 call take_avx_register
1617 mov [vex_register],al
1618 cmp al,[postbyte_register]
1619 je disallowed_combination_of_registers
1620 mov al,bl
1621 and al,1111b
1622 cmp al,[postbyte_register]
1623 je disallowed_combination_of_registers
1624 cmp al,[vex_register]
1625 je disallowed_combination_of_registers
1626 mov al,bl
1627 shr al,4
1628 cmp al,0Ch
1629 je gather_vr_128bit
1630 mov al,[rex_prefix]
1631 shr al,3
1632 xor al,[supplemental_code]
1633 test al,1
1634 jz gather_256bit
1635 test [supplemental_code],1
1636 jz invalid_operand_size
1637 mov al,32
1638 xchg al,[operand_size]
1639 cmp al,16
1640 jne invalid_operand_size
1641 jmp instruction_ready
1642 gather_256bit:
1643 cmp ah,32
1644 jne invalid_operand_size
1645 jmp instruction_ready
1646 gather_vr_128bit:
1647 cmp ah,16
1648 je instruction_ready
1649 test [supplemental_code],1
1650 jnz invalid_operand_size
1651 test [rex_prefix],8
1652 jz invalid_operand_size
1653 jmp instruction_ready
1654
1655 take_avx_register:
1656 lods byte [esi]
1657 call get_size_operator
1658 cmp al,10h
1659 jne invalid_operand
1660 lods byte [esi]
1661 convert_avx_register:
1662 mov ah,al
1663 and al,0Fh
1664 and ah,0F0h
1665 sub ah,0B0h
1666 jbe invalid_operand
1667 cmp ah,32
1668 ja invalid_operand
1669 cmp al,8
1670 jb match_register_size
1671 cmp [code_type],64
1672 jne invalid_operand
1673 jmp match_register_size
1674 store_vex_instruction_code:
1675 mov al,[base_code]
1676 cmp al,0Fh
1677 jne store_xop_instruction_code
1678 mov ah,[extended_code]
1679 cmp ah,38h
1680 je store_vex_0f38_instruction_code
1681 cmp ah,3Ah
1682 je store_vex_0f3a_instruction_code
1683 test [rex_prefix],1011b
1684 jnz store_vex_0f_instruction_code
1685 mov [edi+2],ah
1686 mov byte [edi],0C5h
1687 mov al,[vex_register]
1688 not al
1689 shl al,3
1690 mov ah,[rex_prefix]
1691 shl ah,5
1692 and ah,80h
1693 xor al,ah
1694 call get_vex_lpp_bits
1695 mov [edi+1],al
1696 call check_vex
1697 add edi,3
1698 ret
1699 get_vex_lpp_bits:
1700 cmp [operand_size],32
1701 jne vex_l_bit_ok
1702 or al,100b
1703 vex_l_bit_ok:
1704 mov ah,[opcode_prefix]
1705 cmp ah,66h
1706 je vex_66
1707 cmp ah,0F3h
1708 je vex_f3
1709 cmp ah,0F2h
1710 je vex_f2
1711 test ah,ah
1712 jnz disallowed_combination_of_registers
1713 ret
1714 vex_f2:
1715 or al,11b
1716 ret
1717 vex_f3:
1718 or al,10b
1719 ret
1720 vex_66:
1721 or al,1
1722 ret
1723 store_vex_0f38_instruction_code:
1724 mov al,11100010b
1725 mov ah,[supplemental_code]
1726 jmp make_c4_vex
1727 store_vex_0f3a_instruction_code:
1728 mov al,11100011b
1729 mov ah,[supplemental_code]
1730 jmp make_c4_vex
1731 store_vex_0f_instruction_code:
1732 mov al,11100001b
1733 make_c4_vex:
1734 mov [edi+3],ah
1735 mov byte [edi],0C4h
1736 mov ah,[rex_prefix]
1737 shl ah,5
1738 xor al,ah
1739 mov [edi+1],al
1740 call check_vex
1741 mov al,[vex_register]
1742 xor al,1111b
1743 shl al,3
1744 mov ah,[rex_prefix]
1745 shl ah,4
1746 and ah,80h
1747 or al,ah
1748 call get_vex_lpp_bits
1749 mov [edi+2],al
1750 add edi,4
1751 ret
1752 check_vex:
1753 cmp [code_type],64
1754 je vex_ok
1755 not al
1756 test al,11000000b
1757 jnz invalid_operand
1758 test [rex_prefix],40h
1759 jnz invalid_operand
1760 vex_ok:
1761 ret
1762 store_xop_instruction_code:
1763 mov [edi+3],al
1764 mov byte [edi],8Fh
1765 mov al,[xop_opcode_map]
1766 mov ah,[rex_prefix]
1767 test ah,40h
1768 jz xop_ok
1769 cmp [code_type],64
1770 jne invalid_operand
1771 xop_ok:
1772 not ah
1773 shl ah,5
1774 xor al,ah
1775 mov [edi+1],al
1776 mov al,[vex_register]
1777 xor al,1111b
1778 shl al,3
1779 mov ah,[rex_prefix]
1780 shl ah,4
1781 and ah,80h
1782 or al,ah
1783 call get_vex_lpp_bits
1784 mov [edi+2],al
1785 add edi,4
1786 ret
0
1 ; flat assembler core
2 ; Copyright (c) 1999-2014, Tomasz Grysztar.
3 ; All rights reserved.
4
5 out_of_memory:
6 push _out_of_memory
7 jmp fatal_error
8 stack_overflow:
9 push _stack_overflow
10 jmp fatal_error
11 main_file_not_found:
12 push _main_file_not_found
13 jmp fatal_error
14 write_failed:
15 push _write_failed
16 jmp fatal_error
17
18 unexpected_end_of_file:
19 push _unexpected_end_of_file
20 jmp general_error
21 code_cannot_be_generated:
22 push _code_cannot_be_generated
23 jmp general_error
24 format_limitations_exceeded:
25 push _format_limitations_exceeded
26 general_error:
27 cmp [symbols_file],0
28 je fatal_error
29 call dump_preprocessed_source
30 jmp fatal_error
31
32 file_not_found:
33 push _file_not_found
34 jmp error_with_source
35 error_reading_file:
36 push _error_reading_file
37 jmp error_with_source
38 invalid_file_format:
39 push _invalid_file_format
40 jmp error_with_source
41 invalid_macro_arguments:
42 push _invalid_macro_arguments
43 jmp error_with_source
44 incomplete_macro:
45 push _incomplete_macro
46 jmp error_with_source
47 unexpected_characters:
48 push _unexpected_characters
49 jmp error_with_source
50 invalid_argument:
51 push _invalid_argument
52 jmp error_with_source
53 illegal_instruction:
54 push _illegal_instruction
55 jmp error_with_source
56 invalid_operand:
57 push _invalid_operand
58 jmp error_with_source
59 invalid_operand_size:
60 push _invalid_operand_size
61 jmp error_with_source
62 operand_size_not_specified:
63 push _operand_size_not_specified
64 jmp error_with_source
65 operand_sizes_do_not_match:
66 push _operand_sizes_do_not_match
67 jmp error_with_source
68 invalid_address_size:
69 push _invalid_address_size
70 jmp error_with_source
71 address_sizes_do_not_agree:
72 push _address_sizes_do_not_agree
73 jmp error_with_source
74 disallowed_combination_of_registers:
75 push _disallowed_combination_of_registers
76 jmp error_with_source
77 long_immediate_not_encodable:
78 push _long_immediate_not_encodable
79 jmp error_with_source
80 relative_jump_out_of_range:
81 push _relative_jump_out_of_range
82 jmp error_with_source
83 invalid_expression:
84 push _invalid_expression
85 jmp error_with_source
86 invalid_address:
87 push _invalid_address
88 jmp error_with_source
89 invalid_value:
90 push _invalid_value
91 jmp error_with_source
92 value_out_of_range:
93 push _value_out_of_range
94 jmp error_with_source
95 undefined_symbol:
96 mov edi,message
97 mov esi,_undefined_symbol
98 call copy_asciiz
99 push message
100 cmp [error_info],0
101 je error_with_source
102 mov esi,[error_info]
103 mov esi,[esi+24]
104 or esi,esi
105 jz error_with_source
106 mov byte [edi-1],20h
107 call write_quoted_symbol_name
108 jmp error_with_source
109 copy_asciiz:
110 lods byte [esi]
111 stos byte [edi]
112 test al,al
113 jnz copy_asciiz
114 ret
115 write_quoted_symbol_name:
116 mov al,27h
117 stosb
118 movzx ecx,byte [esi-1]
119 rep movs byte [edi],[esi]
120 mov ax,27h
121 stosw
122 ret
123 symbol_out_of_scope:
124 mov edi,message
125 mov esi,_symbol_out_of_scope_1
126 call copy_asciiz
127 cmp [error_info],0
128 je finish_symbol_out_of_scope_message
129 mov esi,[error_info]
130 mov esi,[esi+24]
131 or esi,esi
132 jz finish_symbol_out_of_scope_message
133 mov byte [edi-1],20h
134 call write_quoted_symbol_name
135 finish_symbol_out_of_scope_message:
136 mov byte [edi-1],20h
137 mov esi,_symbol_out_of_scope_2
138 call copy_asciiz
139 push message
140 jmp error_with_source
141 invalid_use_of_symbol:
142 push _invalid_use_of_symbol
143 jmp error_with_source
144 name_too_long:
145 push _name_too_long
146 jmp error_with_source
147 invalid_name:
148 push _invalid_name
149 jmp error_with_source
150 reserved_word_used_as_symbol:
151 push _reserved_word_used_as_symbol
152 jmp error_with_source
153 symbol_already_defined:
154 push _symbol_already_defined
155 jmp error_with_source
156 missing_end_quote:
157 push _missing_end_quote
158 jmp error_with_source
159 missing_end_directive:
160 push _missing_end_directive
161 jmp error_with_source
162 unexpected_instruction:
163 push _unexpected_instruction
164 jmp error_with_source
165 extra_characters_on_line:
166 push _extra_characters_on_line
167 jmp error_with_source
168 section_not_aligned_enough:
169 push _section_not_aligned_enough
170 jmp error_with_source
171 setting_already_specified:
172 push _setting_already_specified
173 jmp error_with_source
174 data_already_defined:
175 push _data_already_defined
176 jmp error_with_source
177 too_many_repeats:
178 push _too_many_repeats
179 jmp error_with_source
180 assertion_failed:
181 push _assertion_failed
182 jmp error_with_source
183 invoked_error:
184 push _invoked_error
185 error_with_source:
186 cmp [symbols_file],0
187 je assembler_error
188 call dump_preprocessed_source
189 call restore_preprocessed_source
190 jmp assembler_error
0
1 ; flat assembler core
2 ; Copyright (c) 1999-2014, Tomasz Grysztar.
3 ; All rights reserved.
4
5 calculate_expression:
6 mov [current_offset],edi
7 mov [value_undefined],0
8 cmp byte [esi],0
9 je get_string_value
10 cmp byte [esi],'.'
11 je convert_fp
12 calculation_loop:
13 lods byte [esi]
14 cmp al,1
15 je get_byte_number
16 cmp al,2
17 je get_word_number
18 cmp al,4
19 je get_dword_number
20 cmp al,8
21 je get_qword_number
22 cmp al,0Fh
23 je value_out_of_range
24 cmp al,10h
25 je get_register
26 cmp al,11h
27 je get_label
28 cmp al,')'
29 je expression_calculated
30 cmp al,']'
31 je expression_calculated
32 cmp al,'!'
33 je invalid_expression
34 sub edi,14h
35 mov ebx,edi
36 sub ebx,14h
37 cmp al,0E0h
38 je calculate_rva
39 cmp al,0E1h
40 je calculate_plt
41 cmp al,0D0h
42 je calculate_not
43 cmp al,083h
44 je calculate_neg
45 mov dx,[ebx+8]
46 or dx,[edi+8]
47 cmp al,80h
48 je calculate_add
49 cmp al,81h
50 je calculate_sub
51 mov ah,[ebx+12]
52 or ah,[edi+12]
53 jz absolute_values_calculation
54 call recoverable_misuse
55 absolute_values_calculation:
56 cmp al,90h
57 je calculate_mul
58 cmp al,91h
59 je calculate_div
60 or dx,dx
61 jnz invalid_expression
62 cmp al,0A0h
63 je calculate_mod
64 cmp al,0B0h
65 je calculate_and
66 cmp al,0B1h
67 je calculate_or
68 cmp al,0B2h
69 je calculate_xor
70 cmp al,0C0h
71 je calculate_shl
72 cmp al,0C1h
73 je calculate_shr
74 jmp invalid_expression
75 expression_calculated:
76 sub edi,14h
77 cmp [value_undefined],0
78 je expression_value_ok
79 xor eax,eax
80 mov [edi],eax
81 mov [edi+4],eax
82 mov [edi+12],eax
83 expression_value_ok:
84 ret
85 get_byte_number:
86 xor eax,eax
87 lods byte [esi]
88 stos dword [edi]
89 xor al,al
90 stos dword [edi]
91 got_number:
92 and word [edi-8+8],0
93 and word [edi-8+12],0
94 and dword [edi-8+16],0
95 add edi,0Ch
96 jmp calculation_loop
97 get_word_number:
98 xor eax,eax
99 lods word [esi]
100 stos dword [edi]
101 xor ax,ax
102 stos dword [edi]
103 jmp got_number
104 get_dword_number:
105 movs dword [edi],[esi]
106 xor eax,eax
107 stos dword [edi]
108 jmp got_number
109 get_qword_number:
110 movs dword [edi],[esi]
111 movs dword [edi],[esi]
112 jmp got_number
113 get_register:
114 mov byte [edi+9],0
115 and word [edi+12],0
116 lods byte [esi]
117 mov [edi+8],al
118 mov byte [edi+10],1
119 xor eax,eax
120 mov [edi+16],eax
121 stos dword [edi]
122 stos dword [edi]
123 add edi,0Ch
124 jmp calculation_loop
125 get_label:
126 xor eax,eax
127 mov [edi+8],eax
128 mov [edi+12],eax
129 mov [edi+20],eax
130 lods dword [esi]
131 cmp eax,0Fh
132 jb predefined_label
133 je reserved_word_used_as_symbol
134 mov ebx,eax
135 mov ax,[current_pass]
136 mov [ebx+18],ax
137 mov cl,[ebx+9]
138 shr cl,1
139 and cl,1
140 neg cl
141 or byte [ebx+8],8
142 test byte [ebx+8],1
143 jz label_undefined
144 cmp ax,[ebx+16]
145 je unadjusted_label
146 test byte [ebx+8],4
147 jnz label_out_of_scope
148 test byte [ebx+9],1
149 jz unadjusted_label
150 mov eax,[ebx]
151 sub eax,dword [adjustment]
152 stos dword [edi]
153 mov eax,[ebx+4]
154 sbb eax,dword [adjustment+4]
155 stos dword [edi]
156 sbb cl,[adjustment_sign]
157 mov [edi-8+13],cl
158 mov eax,dword [adjustment]
159 or al,[adjustment_sign]
160 or eax,dword [adjustment+4]
161 jz got_label
162 or [next_pass_needed],-1
163 jmp got_label
164 unadjusted_label:
165 mov eax,[ebx]
166 stos dword [edi]
167 mov eax,[ebx+4]
168 stos dword [edi]
169 mov [edi-8+13],cl
170 got_label:
171 test byte [ebx+9],4
172 jnz invalid_use_of_symbol
173 cmp [symbols_file],0
174 je label_reference_ok
175 cmp [next_pass_needed],0
176 jne label_reference_ok
177 call store_label_reference
178 label_reference_ok:
179 mov al,[ebx+11]
180 mov [edi-8+12],al
181 mov eax,[ebx+12]
182 mov [edi-8+8],eax
183 cmp al,ah
184 jne labeled_registers_ok
185 shr eax,16
186 add al,ah
187 jo labeled_registers_ok
188 xor ah,ah
189 mov [edi-8+10],ax
190 mov [edi-8+9],ah
191 labeled_registers_ok:
192 mov eax,[ebx+20]
193 mov [edi-8+16],eax
194 add edi,0Ch
195 mov al,[ebx+10]
196 or al,al
197 jz calculation_loop
198 cmp [size_override],-1
199 je calculation_loop
200 cmp [size_override],0
201 je check_size
202 cmp [operand_size],0
203 jne calculation_loop
204 mov [operand_size],al
205 jmp calculation_loop
206 check_size:
207 xchg [operand_size],al
208 or al,al
209 jz calculation_loop
210 cmp al,[operand_size]
211 jne operand_sizes_do_not_match
212 jmp calculation_loop
213 current_offset_label:
214 mov eax,[current_offset]
215 make_current_offset_label:
216 xor edx,edx
217 xor ch,ch
218 mov ebp,[addressing_space]
219 sub eax,[ds:ebp]
220 sbb edx,[ds:ebp+4]
221 sbb ch,[ds:ebp+8]
222 jp current_offset_label_ok
223 call recoverable_overflow
224 current_offset_label_ok:
225 stos dword [edi]
226 mov eax,edx
227 stos dword [edi]
228 mov eax,[ds:ebp+10h]
229 stos dword [edi]
230 mov cl,[ds:ebp+9]
231 mov [edi-12+12],cx
232 mov eax,[ds:ebp+14h]
233 mov [edi-12+16],eax
234 add edi,8
235 jmp calculation_loop
236 org_origin_label:
237 mov eax,[addressing_space]
238 mov eax,[eax+18h]
239 jmp make_current_offset_label
240 counter_label:
241 mov eax,[counter]
242 make_dword_label_value:
243 stos dword [edi]
244 xor eax,eax
245 stos dword [edi]
246 add edi,0Ch
247 jmp calculation_loop
248 timestamp_label:
249 call make_timestamp
250 make_qword_label_value:
251 stos dword [edi]
252 mov eax,edx
253 stos dword [edi]
254 add edi,0Ch
255 jmp calculation_loop
256 predefined_label:
257 or eax,eax
258 jz current_offset_label
259 cmp eax,1
260 je counter_label
261 cmp eax,2
262 je timestamp_label
263 cmp eax,3
264 je org_origin_label
265 mov edx,invalid_value
266 jmp error_undefined
267 label_out_of_scope:
268 mov edx,symbol_out_of_scope
269 jmp error_undefined
270 label_undefined:
271 mov edx,undefined_symbol
272 error_undefined:
273 cmp [current_pass],1
274 ja undefined_value
275 force_next_pass:
276 or [next_pass_needed],-1
277 undefined_value:
278 or [value_undefined],-1
279 and word [edi+12],0
280 xor eax,eax
281 stos dword [edi]
282 stos dword [edi]
283 add edi,0Ch
284 cmp [error_line],0
285 jne calculation_loop
286 mov eax,[current_line]
287 mov [error_line],eax
288 mov [error],edx
289 mov [error_info],ebx
290 jmp calculation_loop
291 calculate_add:
292 xor ah,ah
293 mov ah,[ebx+12]
294 mov al,[edi+12]
295 or al,al
296 jz add_values
297 or ah,ah
298 jz add_relocatable
299 add ah,al
300 jnz invalid_add
301 mov ecx,[edi+16]
302 cmp ecx,[ebx+16]
303 je add_values
304 invalid_add:
305 call recoverable_misuse
306 jmp add_values
307 add_relocatable:
308 mov ah,al
309 mov ecx,[edi+16]
310 mov [ebx+16],ecx
311 add_values:
312 mov [ebx+12],ah
313 mov eax,[edi]
314 add [ebx],eax
315 mov eax,[edi+4]
316 adc [ebx+4],eax
317 mov al,[edi+13]
318 adc [ebx+13],al
319 jp add_sign_ok
320 call recoverable_overflow
321 add_sign_ok:
322 or dx,dx
323 jz calculation_loop
324 push esi
325 mov esi,ebx
326 mov cl,[edi+10]
327 mov al,[edi+8]
328 call add_register
329 mov cl,[edi+11]
330 mov al,[edi+9]
331 call add_register
332 pop esi
333 jmp calculation_loop
334 add_register:
335 or al,al
336 jz add_register_done
337 add_register_start:
338 cmp [esi+8],al
339 jne add_in_second_slot
340 add [esi+10],cl
341 jo value_out_of_range
342 jnz add_register_done
343 mov byte [esi+8],0
344 ret
345 add_in_second_slot:
346 cmp [esi+9],al
347 jne create_in_first_slot
348 add [esi+11],cl
349 jo value_out_of_range
350 jnz add_register_done
351 mov byte [esi+9],0
352 ret
353 create_in_first_slot:
354 cmp byte [esi+8],0
355 jne create_in_second_slot
356 mov [esi+8],al
357 mov [esi+10],cl
358 ret
359 create_in_second_slot:
360 cmp byte [esi+9],0
361 jne invalid_expression
362 mov [esi+9],al
363 mov [esi+11],cl
364 add_register_done:
365 ret
366 out_of_range:
367 jmp calculation_loop
368 calculate_sub:
369 xor ah,ah
370 mov ah,[ebx+12]
371 mov al,[edi+12]
372 or al,al
373 jz sub_values
374 or ah,ah
375 jz negate_relocatable
376 cmp al,ah
377 jne invalid_sub
378 xor ah,ah
379 mov ecx,[edi+16]
380 cmp ecx,[ebx+16]
381 je sub_values
382 invalid_sub:
383 call recoverable_misuse
384 jmp sub_values
385 negate_relocatable:
386 neg al
387 mov ah,al
388 mov ecx,[edi+16]
389 mov [ebx+16],ecx
390 sub_values:
391 mov [ebx+12],ah
392 mov eax,[edi]
393 sub [ebx],eax
394 mov eax,[edi+4]
395 sbb [ebx+4],eax
396 mov al,[edi+13]
397 sbb [ebx+13],al
398 jp sub_sign_ok
399 cmp [error_line],0
400 jne sub_sign_ok
401 call recoverable_overflow
402 sub_sign_ok:
403 or dx,dx
404 jz calculation_loop
405 push esi
406 mov esi,ebx
407 mov cl,[edi+10]
408 mov al,[edi+8]
409 call sub_register
410 mov cl,[edi+11]
411 mov al,[edi+9]
412 call sub_register
413 pop esi
414 jmp calculation_loop
415 sub_register:
416 or al,al
417 jz add_register_done
418 neg cl
419 jo value_out_of_range
420 jmp add_register_start
421 calculate_mul:
422 or dx,dx
423 jz mul_start
424 cmp word [ebx+8],0
425 jne mul_start
426 xor ecx,ecx
427 swap_values:
428 mov eax,[ebx+ecx]
429 xchg eax,[edi+ecx]
430 mov [ebx+ecx],eax
431 add ecx,4
432 cmp ecx,16
433 jb swap_values
434 mul_start:
435 push esi edx
436 mov esi,ebx
437 xor bl,bl
438 cmp byte [esi+13],0
439 je mul_first_sign_ok
440 xor bl,-1
441 mov eax,[esi]
442 mov edx,[esi+4]
443 not eax
444 not edx
445 add eax,1
446 adc edx,0
447 mov [esi],eax
448 mov [esi+4],edx
449 or eax,edx
450 jz mul_overflow
451 mul_first_sign_ok:
452 cmp byte [edi+13],0
453 je mul_second_sign_ok
454 xor bl,-1
455 cmp byte [esi+8],0
456 je mul_first_register_sign_ok
457 neg byte [esi+10]
458 jo invalid_expression
459 mul_first_register_sign_ok:
460 cmp byte [esi+9],0
461 je mul_second_register_sign_ok
462 neg byte [esi+11]
463 jo invalid_expression
464 mul_second_register_sign_ok:
465 mov eax,[edi]
466 mov edx,[edi+4]
467 not eax
468 not edx
469 add eax,1
470 adc edx,0
471 mov [edi],eax
472 mov [edi+4],edx
473 or eax,edx
474 jz mul_overflow
475 mul_second_sign_ok:
476 cmp dword [esi+4],0
477 jz mul_numbers
478 cmp dword [edi+4],0
479 jz mul_numbers
480 jnz mul_overflow
481 mul_numbers:
482 mov eax,[esi+4]
483 mul dword [edi]
484 or edx,edx
485 jnz mul_overflow
486 mov ecx,eax
487 mov eax,[esi]
488 mul dword [edi+4]
489 or edx,edx
490 jnz mul_overflow
491 add ecx,eax
492 jc mul_overflow
493 mov eax,[esi]
494 mul dword [edi]
495 add edx,ecx
496 jc mul_overflow
497 mov [esi],eax
498 mov [esi+4],edx
499 or bl,bl
500 jz mul_ok
501 not eax
502 not edx
503 add eax,1
504 adc edx,0
505 mov [esi],eax
506 mov [esi+4],edx
507 or eax,edx
508 jnz mul_ok
509 not bl
510 mul_ok:
511 mov [esi+13],bl
512 pop edx
513 or dx,dx
514 jz mul_calculated
515 cmp word [edi+8],0
516 jne invalid_value
517 cmp byte [esi+8],0
518 je mul_first_register_ok
519 call get_byte_scale
520 imul byte [esi+10]
521 mov dl,ah
522 cbw
523 cmp ah,dl
524 jne value_out_of_range
525 mov [esi+10],al
526 or al,al
527 jnz mul_first_register_ok
528 mov [esi+8],al
529 mul_first_register_ok:
530 cmp byte [esi+9],0
531 je mul_calculated
532 call get_byte_scale
533 imul byte [esi+11]
534 mov dl,ah
535 cbw
536 cmp ah,dl
537 jne value_out_of_range
538 mov [esi+11],al
539 or al,al
540 jnz mul_calculated
541 mov [esi+9],al
542 mul_calculated:
543 pop esi
544 jmp calculation_loop
545 mul_overflow:
546 pop edx esi
547 call recoverable_overflow
548 jmp calculation_loop
549 get_byte_scale:
550 mov al,[edi]
551 cbw
552 cwde
553 cdq
554 cmp edx,[edi+4]
555 jne value_out_of_range
556 cmp eax,[edi]
557 jne value_out_of_range
558 ret
559 calculate_div:
560 push esi edx
561 mov esi,ebx
562 call div_64
563 pop edx
564 or dx,dx
565 jz div_calculated
566 cmp byte [esi+8],0
567 je div_first_register_ok
568 call get_byte_scale
569 or al,al
570 jz value_out_of_range
571 mov al,[esi+10]
572 cbw
573 idiv byte [edi]
574 or ah,ah
575 jnz invalid_use_of_symbol
576 mov [esi+10],al
577 div_first_register_ok:
578 cmp byte [esi+9],0
579 je div_calculated
580 call get_byte_scale
581 or al,al
582 jz value_out_of_range
583 mov al,[esi+11]
584 cbw
585 idiv byte [edi]
586 or ah,ah
587 jnz invalid_use_of_symbol
588 mov [esi+11],al
589 div_calculated:
590 pop esi
591 jmp calculation_loop
592 calculate_mod:
593 push esi
594 mov esi,ebx
595 call div_64
596 mov [esi],eax
597 mov [esi+4],edx
598 mov [esi+13],bh
599 pop esi
600 jmp calculation_loop
601 calculate_and:
602 mov eax,[edi]
603 mov edx,[edi+4]
604 mov cl,[edi+13]
605 and [ebx],eax
606 and [ebx+4],edx
607 and [ebx+13],cl
608 jmp calculation_loop
609 calculate_or:
610 mov eax,[edi]
611 mov edx,[edi+4]
612 mov cl,[edi+13]
613 or [ebx],eax
614 or [ebx+4],edx
615 or [ebx+13],cl
616 jmp calculation_loop
617 calculate_xor:
618 mov eax,[edi]
619 mov edx,[edi+4]
620 mov cl,[edi+13]
621 xor [ebx],eax
622 xor [ebx+4],edx
623 xor [ebx+13],cl
624 jz calculation_loop
625 or cl,cl
626 jz xor_size_check
627 xor eax,[ebx]
628 xor edx,[ebx+4]
629 xor_size_check:
630 mov cl,[value_size]
631 cmp cl,1
632 je xor_byte_result
633 cmp cl,2
634 je xor_word_result
635 cmp cl,4
636 je xor_dword_result
637 cmp cl,6
638 je xor_pword_result
639 cmp cl,8
640 jne calculation_loop
641 xor edx,[ebx+4]
642 js xor_result_truncated
643 jmp calculation_loop
644 xor_pword_result:
645 test edx,0FFFF0000h
646 jnz calculation_loop
647 cmp word [ebx+6],-1
648 jne calculation_loop
649 xor dx,[ebx+4]
650 jns calculation_loop
651 not word [ebx+6]
652 jmp xor_result_truncated
653 xor_dword_result:
654 test edx,edx
655 jnz calculation_loop
656 cmp dword [ebx+4],-1
657 jne calculation_loop
658 xor eax,[ebx]
659 jns calculation_loop
660 not dword [ebx+4]
661 jmp xor_result_truncated
662 xor_word_result:
663 test edx,edx
664 jnz calculation_loop
665 test eax,0FFFF0000h
666 jnz calculation_loop
667 cmp dword [ebx+4],-1
668 jne calculation_loop
669 cmp word [ebx+2],-1
670 jne calculation_loop
671 xor ax,[ebx]
672 jns calculation_loop
673 not dword [ebx+4]
674 not word [ebx+2]
675 jmp xor_result_truncated
676 xor_byte_result:
677 test edx,edx
678 jnz calculation_loop
679 test eax,0FFFFFF00h
680 jnz calculation_loop
681 cmp dword [ebx+4],-1
682 jne calculation_loop
683 cmp word [ebx+2],-1
684 jne calculation_loop
685 cmp byte [ebx+1],-1
686 jne calculation_loop
687 xor al,[ebx]
688 jns calculation_loop
689 not dword [ebx+4]
690 not word [ebx+2]
691 not byte [ebx+1]
692 xor_result_truncated:
693 mov byte [ebx+13],0
694 jmp calculation_loop
695 shr_negative:
696 mov byte [edi+13],0
697 not dword [edi]
698 not dword [edi+4]
699 add dword [edi],1
700 adc dword [edi+4],0
701 jc shl_over
702 calculate_shl:
703 cmp byte [edi+13],0
704 jne shl_negative
705 mov edx,[ebx+4]
706 mov eax,[ebx]
707 cmp dword [edi+4],0
708 jne shl_over
709 movsx ecx,byte [ebx+13]
710 xchg ecx,[edi]
711 cmp ecx,64
712 je shl_max
713 ja shl_over
714 cmp ecx,32
715 jae shl_high
716 shld [edi],edx,cl
717 shld edx,eax,cl
718 shl eax,cl
719 mov [ebx],eax
720 mov [ebx+4],edx
721 jmp shl_done
722 shl_over:
723 cmp byte [ebx+13],0
724 jne shl_overflow
725 shl_max:
726 movsx ecx,byte [ebx+13]
727 cmp eax,ecx
728 jne shl_overflow
729 cmp edx,ecx
730 jne shl_overflow
731 xor eax,eax
732 mov [ebx],eax
733 mov [ebx+4],eax
734 jmp calculation_loop
735 shl_high:
736 sub cl,32
737 shld [edi],edx,cl
738 shld edx,eax,cl
739 shl eax,cl
740 mov [ebx+4],eax
741 and dword [ebx],0
742 cmp edx,[edi]
743 jne shl_overflow
744 shl_done:
745 movsx eax,byte [ebx+13]
746 cmp eax,[edi]
747 je calculation_loop
748 shl_overflow:
749 call recoverable_overflow
750 jmp calculation_loop
751 shl_negative:
752 mov byte [edi+13],0
753 not dword [edi]
754 not dword [edi+4]
755 add dword [edi],1
756 adc dword [edi+4],0
757 jnc calculate_shr
758 dec dword [edi+4]
759 calculate_shr:
760 cmp byte [edi+13],0
761 jne shr_negative
762 cmp byte [ebx+13],0
763 je do_shr
764 mov al,[value_size]
765 cmp al,1
766 je shr_negative_byte
767 cmp al,2
768 je shr_negative_word
769 cmp al,4
770 je shr_negative_dword
771 cmp al,6
772 je shr_negative_pword
773 cmp al,8
774 jne do_shr
775 shr_negative_qword:
776 test byte [ebx+7],80h
777 jz do_shr
778 shr_truncated:
779 mov byte [ebx+13],0
780 do_shr:
781 mov edx,[ebx+4]
782 mov eax,[ebx]
783 cmp dword [edi+4],0
784 jne shr_over
785 mov ecx,[edi]
786 cmp ecx,64
787 jae shr_over
788 push esi
789 movsx esi,byte [ebx+13]
790 cmp ecx,32
791 jae shr_high
792 shrd eax,edx,cl
793 shrd edx,esi,cl
794 mov [ebx],eax
795 mov [ebx+4],edx
796 pop esi
797 jmp calculation_loop
798 shr_high:
799 sub cl,32
800 shrd edx,esi,cl
801 mov [ebx],edx
802 mov [ebx+4],esi
803 pop esi
804 jmp calculation_loop
805 shr_over:
806 movsx eax,byte [ebx+13]
807 mov dword [ebx],eax
808 mov dword [ebx+4],eax
809 jmp calculation_loop
810 shr_negative_byte:
811 cmp dword [ebx+4],-1
812 jne do_shr
813 cmp word [ebx+2],-1
814 jne do_shr
815 cmp byte [ebx+1],-1
816 jne do_shr
817 test byte [ebx],80h
818 jz do_shr
819 not dword [ebx+4]
820 not word [ebx+2]
821 not byte [ebx+1]
822 jmp shr_truncated
823 shr_negative_word:
824 cmp dword [ebx+4],-1
825 jne do_shr
826 cmp word [ebx+2],-1
827 jne do_shr
828 test byte [ebx+1],80h
829 jz do_shr
830 not dword [ebx+4]
831 not word [ebx+2]
832 jmp shr_truncated
833 shr_negative_dword:
834 cmp dword [ebx+4],-1
835 jne do_shr
836 test byte [ebx+3],80h
837 jz do_shr
838 not dword [ebx+4]
839 jmp shr_truncated
840 shr_negative_pword:
841 cmp word [ebx+6],-1
842 jne do_shr
843 test byte [ebx+5],80h
844 jz do_shr
845 not word [ebx+6]
846 jmp shr_truncated
847 calculate_not:
848 cmp word [edi+8],0
849 jne invalid_expression
850 cmp byte [edi+12],0
851 je not_ok
852 call recoverable_misuse
853 not_ok:
854 mov al,[value_size]
855 cmp al,1
856 je not_byte
857 cmp al,2
858 je not_word
859 cmp al,4
860 je not_dword
861 cmp al,6
862 je not_pword
863 cmp al,8
864 je not_qword
865 not dword [edi]
866 not dword [edi+4]
867 not byte [edi+13]
868 add edi,14h
869 jmp calculation_loop
870 not_qword:
871 not dword [edi]
872 not dword [edi+4]
873 finish_not:
874 mov byte [edi+13],0
875 add edi,14h
876 jmp calculation_loop
877 not_byte:
878 cmp dword [edi+4],0
879 jne not_qword
880 cmp word [edi+2],0
881 jne not_qword
882 cmp byte [edi+1],0
883 jne not_qword
884 not byte [edi]
885 jmp finish_not
886 not_word:
887 cmp dword [edi+4],0
888 jne not_qword
889 cmp word [edi+2],0
890 jne not_qword
891 not word [edi]
892 jmp finish_not
893 not_dword:
894 cmp dword [edi+4],0
895 jne not_qword
896 not dword [edi]
897 jmp finish_not
898 not_pword:
899 cmp word [edi+6],0
900 jne not_qword
901 not word [edi+4]
902 not dword [edi]
903 jmp finish_not
904 calculate_neg:
905 cmp byte [edi+8],0
906 je neg_first_register_ok
907 neg byte [edi+10]
908 jo invalid_expression
909 neg_first_register_ok:
910 cmp byte [edi+9],0
911 je neg_second_register_ok
912 neg byte [edi+11]
913 jo invalid_expression
914 neg_second_register_ok:
915 neg byte [edi+12]
916 xor eax,eax
917 xor edx,edx
918 xor cl,cl
919 xchg eax,[edi]
920 xchg edx,[edi+4]
921 xchg cl,[edi+13]
922 sub [edi],eax
923 sbb [edi+4],edx
924 sbb [edi+13],cl
925 jp neg_sign_ok
926 call recoverable_overflow
927 neg_sign_ok:
928 add edi,14h
929 jmp calculation_loop
930 calculate_rva:
931 cmp word [edi+8],0
932 jne invalid_expression
933 mov al,[output_format]
934 cmp al,5
935 je calculate_gotoff
936 cmp al,4
937 je calculate_coff_rva
938 cmp al,3
939 jne invalid_expression
940 test [format_flags],8
941 jnz pe64_rva
942 mov al,2
943 bt [resolver_flags],0
944 jc rva_type_ok
945 xor al,al
946 rva_type_ok:
947 cmp byte [edi+12],al
948 je rva_ok
949 call recoverable_misuse
950 rva_ok:
951 mov byte [edi+12],0
952 mov eax,[code_start]
953 mov eax,[eax+34h]
954 xor edx,edx
955 finish_rva:
956 sub [edi],eax
957 sbb [edi+4],edx
958 sbb byte [edi+13],0
959 jp rva_finished
960 call recoverable_overflow
961 rva_finished:
962 add edi,14h
963 jmp calculation_loop
964 pe64_rva:
965 mov al,4
966 bt [resolver_flags],0
967 jc pe64_rva_type_ok
968 xor al,al
969 pe64_rva_type_ok:
970 cmp byte [edi+12],al
971 je pe64_rva_ok
972 call recoverable_misuse
973 pe64_rva_ok:
974 mov byte [edi+12],0
975 mov eax,[code_start]
976 mov edx,[eax+34h]
977 mov eax,[eax+30h]
978 jmp finish_rva
979 calculate_gotoff:
980 test [format_flags],8+1
981 jnz invalid_expression
982 calculate_coff_rva:
983 mov dl,5
984 cmp byte [edi+12],2
985 je change_value_type
986 incorrect_change_of_value_type:
987 call recoverable_misuse
988 change_value_type:
989 mov byte [edi+12],dl
990 add edi,14h
991 jmp calculation_loop
992 calculate_plt:
993 cmp word [edi+8],0
994 jne invalid_expression
995 cmp [output_format],5
996 jne invalid_expression
997 test [format_flags],1
998 jnz invalid_expression
999 mov dl,6
1000 mov dh,2
1001 test [format_flags],8
1002 jz check_value_for_plt
1003 mov dh,4
1004 check_value_for_plt:
1005 mov eax,[edi]
1006 or eax,[edi+4]
1007 jnz incorrect_change_of_value_type
1008 cmp byte [edi+12],dh
1009 jne incorrect_change_of_value_type
1010 mov eax,[edi+16]
1011 cmp byte [eax],80h
1012 jne incorrect_change_of_value_type
1013 jmp change_value_type
1014 div_64:
1015 xor ebx,ebx
1016 cmp dword [edi],0
1017 jne divider_ok
1018 cmp dword [edi+4],0
1019 jne divider_ok
1020 cmp [next_pass_needed],0
1021 je value_out_of_range
1022 jmp div_done
1023 divider_ok:
1024 cmp byte [esi+13],0
1025 je div_first_sign_ok
1026 mov eax,[esi]
1027 mov edx,[esi+4]
1028 not eax
1029 not edx
1030 add eax,1
1031 adc edx,0
1032 mov [esi],eax
1033 mov [esi+4],edx
1034 or eax,edx
1035 jz value_out_of_range
1036 xor bx,-1
1037 div_first_sign_ok:
1038 cmp byte [edi+13],0
1039 je div_second_sign_ok
1040 mov eax,[edi]
1041 mov edx,[edi+4]
1042 not eax
1043 not edx
1044 add eax,1
1045 adc edx,0
1046 mov [edi],eax
1047 mov [edi+4],edx
1048 or eax,edx
1049 jz value_out_of_range
1050 xor bl,-1
1051 div_second_sign_ok:
1052 cmp dword [edi+4],0
1053 jne div_high
1054 mov ecx,[edi]
1055 mov eax,[esi+4]
1056 xor edx,edx
1057 div ecx
1058 mov [esi+4],eax
1059 mov eax,[esi]
1060 div ecx
1061 mov [esi],eax
1062 mov eax,edx
1063 xor edx,edx
1064 jmp div_done
1065 div_high:
1066 push ebx
1067 mov eax,[esi+4]
1068 xor edx,edx
1069 div dword [edi+4]
1070 mov ebx,[esi]
1071 mov [esi],eax
1072 and dword [esi+4],0
1073 mov ecx,edx
1074 mul dword [edi]
1075 div_high_loop:
1076 cmp ecx,edx
1077 ja div_high_done
1078 jb div_high_large_correction
1079 cmp ebx,eax
1080 jae div_high_done
1081 div_high_correction:
1082 dec dword [esi]
1083 sub eax,[edi]
1084 sbb edx,[edi+4]
1085 jnc div_high_loop
1086 div_high_done:
1087 sub ebx,eax
1088 sbb ecx,edx
1089 mov edx,ecx
1090 mov eax,ebx
1091 pop ebx
1092 jmp div_done
1093 div_high_large_correction:
1094 push eax edx
1095 mov eax,edx
1096 sub eax,ecx
1097 xor edx,edx
1098 div dword [edi+4]
1099 shr eax,1
1100 jz div_high_small_correction
1101 sub [esi],eax
1102 push eax
1103 mul dword [edi+4]
1104 sub dword [esp+4],eax
1105 pop eax
1106 mul dword [edi]
1107 sub dword [esp+4],eax
1108 sbb dword [esp],edx
1109 pop edx eax
1110 jmp div_high_loop
1111 div_high_small_correction:
1112 pop edx eax
1113 jmp div_high_correction
1114 div_done:
1115 or bh,bh
1116 jz remainder_ok
1117 not eax
1118 not edx
1119 add eax,1
1120 adc edx,0
1121 mov ecx,eax
1122 or ecx,edx
1123 jnz remainder_ok
1124 not bh
1125 remainder_ok:
1126 or bl,bl
1127 jz div_ok
1128 not dword [esi]
1129 not dword [esi+4]
1130 add dword [esi],1
1131 adc dword [esi+4],0
1132 mov ecx,[esi]
1133 or ecx,[esi+4]
1134 jnz div_ok
1135 not bl
1136 div_ok:
1137 mov [esi+13],bl
1138 ret
1139 store_label_reference:
1140 mov eax,[tagged_blocks]
1141 mov dword [eax-4],2
1142 mov dword [eax-8],4
1143 sub eax,8+4
1144 cmp eax,edi
1145 jbe out_of_memory
1146 mov [tagged_blocks],eax
1147 mov [eax],ebx
1148 ret
1149 convert_fp:
1150 inc esi
1151 and word [edi+8],0
1152 and word [edi+12],0
1153 mov al,[value_size]
1154 cmp al,2
1155 je convert_fp_word
1156 cmp al,4
1157 je convert_fp_dword
1158 test al,not 8
1159 jnz invalid_value
1160 convert_fp_qword:
1161 xor eax,eax
1162 xor edx,edx
1163 cmp word [esi+8],8000h
1164 je fp_qword_store
1165 mov bx,[esi+8]
1166 mov eax,[esi]
1167 mov edx,[esi+4]
1168 add eax,eax
1169 adc edx,edx
1170 mov ecx,edx
1171 shr edx,12
1172 shrd eax,ecx,12
1173 jnc fp_qword_ok
1174 add eax,1
1175 adc edx,0
1176 bt edx,20
1177 jnc fp_qword_ok
1178 and edx,1 shl 20 - 1
1179 inc bx
1180 shr edx,1
1181 rcr eax,1
1182 fp_qword_ok:
1183 add bx,3FFh
1184 cmp bx,7FFh
1185 jge value_out_of_range
1186 cmp bx,0
1187 jg fp_qword_exp_ok
1188 or edx,1 shl 20
1189 mov cx,bx
1190 neg cx
1191 inc cx
1192 cmp cx,52
1193 ja value_out_of_range
1194 cmp cx,32
1195 jb fp_qword_small_shift
1196 sub cx,32
1197 mov eax,edx
1198 xor edx,edx
1199 shr eax,cl
1200 jmp fp_qword_shift_done
1201 fp_qword_small_shift:
1202 mov ebx,edx
1203 shr edx,cl
1204 shrd eax,ebx,cl
1205 fp_qword_shift_done:
1206 mov bx,0
1207 jnc fp_qword_exp_ok
1208 add eax,1
1209 adc edx,0
1210 test edx,1 shl 20
1211 jz fp_qword_exp_ok
1212 and edx,1 shl 20 - 1
1213 inc bx
1214 fp_qword_exp_ok:
1215 shl ebx,20
1216 or edx,ebx
1217 fp_qword_store:
1218 mov bl,[esi+11]
1219 shl ebx,31
1220 or edx,ebx
1221 mov [edi],eax
1222 mov [edi+4],edx
1223 add esi,13
1224 ret
1225 convert_fp_word:
1226 xor eax,eax
1227 cmp word [esi+8],8000h
1228 je fp_word_store
1229 mov bx,[esi+8]
1230 mov ax,[esi+6]
1231 shl ax,1
1232 shr ax,6
1233 jnc fp_word_ok
1234 inc ax
1235 bt ax,10
1236 jnc fp_word_ok
1237 and ax,1 shl 10 - 1
1238 inc bx
1239 shr ax,1
1240 fp_word_ok:
1241 add bx,0Fh
1242 cmp bx,01Fh
1243 jge value_out_of_range
1244 cmp bx,0
1245 jg fp_word_exp_ok
1246 or ax,1 shl 10
1247 mov cx,bx
1248 neg cx
1249 inc cx
1250 cmp cx,10
1251 ja value_out_of_range
1252 xor bx,bx
1253 shr ax,cl
1254 jnc fp_word_exp_ok
1255 inc ax
1256 test ax,1 shl 10
1257 jz fp_word_exp_ok
1258 and ax,1 shl 10 - 1
1259 inc bx
1260 fp_word_exp_ok:
1261 shl bx,10
1262 or ax,bx
1263 fp_word_store:
1264 mov bl,[esi+11]
1265 shl bx,15
1266 or ax,bx
1267 mov [edi],eax
1268 xor eax,eax
1269 mov [edi+4],eax
1270 add esi,13
1271 ret
1272 convert_fp_dword:
1273 xor eax,eax
1274 cmp word [esi+8],8000h
1275 je fp_dword_store
1276 mov bx,[esi+8]
1277 mov eax,[esi+4]
1278 shl eax,1
1279 shr eax,9
1280 jnc fp_dword_ok
1281 inc eax
1282 bt eax,23
1283 jnc fp_dword_ok
1284 and eax,1 shl 23 - 1
1285 inc bx
1286 shr eax,1
1287 fp_dword_ok:
1288 add bx,7Fh
1289 cmp bx,0FFh
1290 jge value_out_of_range
1291 cmp bx,0
1292 jg fp_dword_exp_ok
1293 or eax,1 shl 23
1294 mov cx,bx
1295 neg cx
1296 inc cx
1297 cmp cx,23
1298 ja value_out_of_range
1299 xor bx,bx
1300 shr eax,cl
1301 jnc fp_dword_exp_ok
1302 inc eax
1303 test eax,1 shl 23
1304 jz fp_dword_exp_ok
1305 and eax,1 shl 23 - 1
1306 inc bx
1307 fp_dword_exp_ok:
1308 shl ebx,23
1309 or eax,ebx
1310 fp_dword_store:
1311 mov bl,[esi+11]
1312 shl ebx,31
1313 or eax,ebx
1314 mov [edi],eax
1315 xor eax,eax
1316 mov [edi+4],eax
1317 add esi,13
1318 ret
1319 get_string_value:
1320 inc esi
1321 lods dword [esi]
1322 mov ecx,eax
1323 cmp ecx,8
1324 ja value_out_of_range
1325 mov edx,edi
1326 xor eax,eax
1327 stos dword [edi]
1328 stos dword [edi]
1329 mov edi,edx
1330 rep movs byte [edi],[esi]
1331 mov edi,edx
1332 inc esi
1333 and word [edi+8],0
1334 and word [edi+12],0
1335 ret
1336
1337 get_byte_value:
1338 mov [value_size],1
1339 mov [size_override],-1
1340 call calculate_value
1341 or al,al
1342 jz check_byte_value
1343 call recoverable_misuse
1344 check_byte_value:
1345 mov eax,[edi]
1346 mov edx,[edi+4]
1347 cmp byte [edi+13],0
1348 je byte_positive
1349 cmp edx,-1
1350 jne range_exceeded
1351 cmp eax,-80h
1352 jb range_exceeded
1353 ret
1354 byte_positive:
1355 test edx,edx
1356 jnz range_exceeded
1357 cmp eax,100h
1358 jae range_exceeded
1359 return_byte_value:
1360 ret
1361 range_exceeded:
1362 xor eax,eax
1363 xor edx,edx
1364 recoverable_overflow:
1365 cmp [error_line],0
1366 jne ignore_overflow
1367 push [current_line]
1368 pop [error_line]
1369 mov [error],value_out_of_range
1370 or [value_undefined],-1
1371 ignore_overflow:
1372 ret
1373 recoverable_misuse:
1374 cmp [error_line],0
1375 jne ignore_misuse
1376 push [current_line]
1377 pop [error_line]
1378 mov [error],invalid_use_of_symbol
1379 ignore_misuse:
1380 ret
1381 get_word_value:
1382 mov [value_size],2
1383 mov [size_override],-1
1384 call calculate_value
1385 cmp al,2
1386 jb check_word_value
1387 call recoverable_misuse
1388 check_word_value:
1389 mov eax,[edi]
1390 mov edx,[edi+4]
1391 cmp byte [edi+13],0
1392 je word_positive
1393 cmp edx,-1
1394 jne range_exceeded
1395 cmp eax,-8000h
1396 jb range_exceeded
1397 ret
1398 word_positive:
1399 test edx,edx
1400 jnz range_exceeded
1401 cmp eax,10000h
1402 jae range_exceeded
1403 ret
1404 get_dword_value:
1405 mov [value_size],4
1406 mov [size_override],-1
1407 call calculate_value
1408 cmp al,4
1409 jne check_dword_value
1410 mov [value_type],2
1411 mov eax,[edi]
1412 cdq
1413 cmp edx,[edi+4]
1414 jne range_exceeded
1415 mov ecx,edx
1416 shr ecx,31
1417 cmp cl,[value_sign]
1418 jne range_exceeded
1419 ret
1420 check_dword_value:
1421 mov eax,[edi]
1422 mov edx,[edi+4]
1423 cmp byte [edi+13],0
1424 je dword_positive
1425 cmp edx,-1
1426 jne range_exceeded
1427 bt eax,31
1428 jnc range_exceeded
1429 ret
1430 dword_positive:
1431 test edx,edx
1432 jne range_exceeded
1433 ret
1434 get_pword_value:
1435 mov [value_size],6
1436 mov [size_override],-1
1437 call calculate_value
1438 cmp al,4
1439 jne check_pword_value
1440 call recoverable_misuse
1441 check_pword_value:
1442 mov eax,[edi]
1443 mov edx,[edi+4]
1444 cmp byte [edi+13],0
1445 je pword_positive
1446 cmp edx,-8000h
1447 jb range_exceeded
1448 ret
1449 pword_positive:
1450 cmp edx,10000h
1451 jae range_exceeded
1452 ret
1453 get_qword_value:
1454 mov [value_size],8
1455 mov [size_override],-1
1456 call calculate_value
1457 check_qword_value:
1458 mov eax,[edi]
1459 mov edx,[edi+4]
1460 cmp byte [edi+13],0
1461 je qword_positive
1462 cmp edx,-80000000h
1463 jb range_exceeded
1464 qword_positive:
1465 ret
1466 get_count_value:
1467 mov [value_size],8
1468 mov [size_override],-1
1469 call calculate_expression
1470 cmp word [edi+8],0
1471 jne invalid_value
1472 mov [value_sign],0
1473 mov al,[edi+12]
1474 or al,al
1475 jz check_count_value
1476 call recoverable_misuse
1477 check_count_value:
1478 cmp byte [edi+13],0
1479 jne invalid_count_value
1480 mov eax,[edi]
1481 mov edx,[edi+4]
1482 or edx,edx
1483 jnz invalid_count_value
1484 ret
1485 invalid_count_value:
1486 cmp [error_line],0
1487 jne zero_count
1488 mov eax,[current_line]
1489 mov [error_line],eax
1490 mov [error],invalid_value
1491 zero_count:
1492 xor eax,eax
1493 ret
1494 get_value:
1495 mov [operand_size],0
1496 lods byte [esi]
1497 call get_size_operator
1498 cmp al,'('
1499 jne invalid_value
1500 mov al,[operand_size]
1501 cmp al,1
1502 je value_byte
1503 cmp al,2
1504 je value_word
1505 cmp al,4
1506 je value_dword
1507 cmp al,6
1508 je value_pword
1509 cmp al,8
1510 je value_qword
1511 or al,al
1512 jnz invalid_value
1513 mov [value_size],al
1514 call calculate_value
1515 mov eax,[edi]
1516 mov edx,[edi+4]
1517 ret
1518 calculate_value:
1519 call calculate_expression
1520 cmp word [edi+8],0
1521 jne invalid_value
1522 mov eax,[edi+16]
1523 mov [symbol_identifier],eax
1524 mov al,[edi+13]
1525 mov [value_sign],al
1526 mov al,[edi+12]
1527 mov [value_type],al
1528 ret
1529 value_qword:
1530 call get_qword_value
1531 truncated_value:
1532 mov [value_sign],0
1533 ret
1534 value_pword:
1535 call get_pword_value
1536 movzx edx,dx
1537 jmp truncated_value
1538 value_dword:
1539 call get_dword_value
1540 xor edx,edx
1541 jmp truncated_value
1542 value_word:
1543 call get_word_value
1544 xor edx,edx
1545 movzx eax,ax
1546 jmp truncated_value
1547 value_byte:
1548 call get_byte_value
1549 xor edx,edx
1550 movzx eax,al
1551 jmp truncated_value
1552 get_address_word_value:
1553 mov [address_size],2
1554 mov [value_size],2
1555 mov [free_address_range],0
1556 jmp calculate_address
1557 get_address_dword_value:
1558 mov [address_size],4
1559 mov [value_size],4
1560 mov [free_address_range],0
1561 jmp calculate_address
1562 get_address_qword_value:
1563 mov [address_size],8
1564 mov [value_size],8
1565 mov [free_address_range],0
1566 jmp calculate_address
1567 get_address_value:
1568 mov [address_size],0
1569 mov [value_size],8
1570 or [free_address_range],-1
1571 calculate_address:
1572 cmp byte [esi],'.'
1573 je invalid_address
1574 call calculate_expression
1575 mov eax,[edi+16]
1576 mov [address_symbol],eax
1577 mov al,[edi+13]
1578 mov [address_sign],al
1579 mov al,[edi+12]
1580 mov [value_type],al
1581 cmp al,0
1582 je address_size_ok
1583 jg get_address_symbol_size
1584 neg al
1585 get_address_symbol_size:
1586 cmp al,6
1587 je special_address_type_32bit
1588 cmp al,5
1589 je special_address_type_32bit
1590 ja invalid_address_type
1591 test al,1
1592 jnz invalid_address_type
1593 shl al,5
1594 jmp address_symbol_ok
1595 invalid_address_type:
1596 call recoverable_misuse
1597 special_address_type_32bit:
1598 mov al,40h
1599 address_symbol_ok:
1600 mov ah,[address_size]
1601 or [address_size],al
1602 shr al,4
1603 or ah,ah
1604 jz address_size_ok
1605 cmp al,ah
1606 je address_size_ok
1607 cmp ax,0408h
1608 je address_sizes_mixed
1609 cmp ax,0804h
1610 jne address_sizes_do_not_agree
1611 address_sizes_mixed:
1612 mov [value_type],2
1613 mov eax,[edi]
1614 cdq
1615 cmp edx,[edi+4]
1616 je address_size_ok
1617 cmp [error_line],0
1618 jne address_size_ok
1619 call recoverable_overflow
1620 address_size_ok:
1621 xor ebx,ebx
1622 xor ecx,ecx
1623 mov cl,[value_type]
1624 shl ecx,16
1625 mov ch,[address_size]
1626 cmp word [edi+8],0
1627 je check_immediate_address
1628 mov al,[edi+8]
1629 mov dl,[edi+10]
1630 call get_address_register
1631 mov al,[edi+9]
1632 mov dl,[edi+11]
1633 call get_address_register
1634 mov ax,bx
1635 shr ah,4
1636 shr al,4
1637 cmp ah,0Ch
1638 je check_vsib_address
1639 cmp ah,0Dh
1640 je check_vsib_address
1641 cmp al,0Ch
1642 je check_vsib_address
1643 cmp al,0Dh
1644 je check_vsib_address
1645 or bh,bh
1646 jz check_address_registers
1647 or bl,bl
1648 jz check_address_registers
1649 cmp al,ah
1650 jne invalid_address
1651 check_address_registers:
1652 or al,ah
1653 mov ah,[address_size]
1654 and ah,0Fh
1655 jz address_registers_sizes_ok
1656 cmp al,ah
1657 jne address_sizes_do_not_match
1658 address_registers_sizes_ok:
1659 cmp al,4
1660 je sib_allowed
1661 cmp al,8
1662 je sib_allowed
1663 cmp al,0Fh
1664 je check_ip_relative_address
1665 cmp cl,1
1666 ja invalid_address
1667 cmp [free_address_range],0
1668 jne check_qword_value
1669 jmp check_word_value
1670 address_sizes_do_not_match:
1671 cmp al,0Fh
1672 jne invalid_address
1673 mov al,bh
1674 and al,0Fh
1675 cmp al,ah
1676 jne invalid_address
1677 check_ip_relative_address:
1678 or bl,bl
1679 jnz invalid_address
1680 cmp bh,0F8h
1681 je check_rip_relative_address
1682 cmp bh,0F4h
1683 jne invalid_address
1684 cmp [free_address_range],0
1685 jne check_qword_value
1686 jmp check_dword_value
1687 check_rip_relative_address:
1688 mov eax,[edi]
1689 cdq
1690 cmp edx,[edi+4]
1691 jne range_exceeded
1692 cmp dl,[edi+13]
1693 jne range_exceeded
1694 ret
1695 get_address_register:
1696 or al,al
1697 jz address_register_ok
1698 cmp dl,1
1699 jne scaled_register
1700 or bh,bh
1701 jnz scaled_register
1702 mov bh,al
1703 address_register_ok:
1704 ret
1705 scaled_register:
1706 or bl,bl
1707 jnz invalid_address
1708 mov bl,al
1709 mov cl,dl
1710 jmp address_register_ok
1711 sib_allowed:
1712 or bh,bh
1713 jnz check_index_with_base
1714 cmp cl,3
1715 je special_index_scale
1716 cmp cl,5
1717 je special_index_scale
1718 cmp cl,9
1719 je special_index_scale
1720 cmp cl,2
1721 jne check_index_scale
1722 cmp bl,45h
1723 jne special_index_scale
1724 cmp [code_type],64
1725 je special_index_scale
1726 cmp [segment_register],4
1727 jne special_index_scale
1728 cmp [value_type],0
1729 jne check_index_scale
1730 mov al,[edi]
1731 cbw
1732 cwde
1733 cmp eax,[edi]
1734 jne check_index_scale
1735 cdq
1736 cmp edx,[edi+4]
1737 jne check_immediate_address
1738 special_index_scale:
1739 mov bh,bl
1740 dec cl
1741 check_immediate_address:
1742 cmp [free_address_range],0
1743 jne check_qword_value
1744 mov al,[address_size]
1745 and al,0Fh
1746 cmp al,2
1747 je check_word_value
1748 cmp al,4
1749 je check_dword_value
1750 cmp al,8
1751 je check_qword_value
1752 or al,al
1753 jnz invalid_value
1754 cmp [code_type],64
1755 jne check_dword_value
1756 jmp check_qword_value
1757 check_index_with_base:
1758 cmp cl,1
1759 jne check_index_scale
1760 cmp bl,44h
1761 je swap_base_with_index
1762 cmp bl,84h
1763 je swap_base_with_index
1764 cmp [code_type],64
1765 je check_for_rbp_base
1766 cmp bl,45h
1767 jne check_for_ebp_base
1768 cmp [segment_register],3
1769 je swap_base_with_index
1770 jmp check_immediate_address
1771 check_for_ebp_base:
1772 cmp bh,45h
1773 jne check_immediate_address
1774 cmp [segment_register],4
1775 jne check_immediate_address
1776 swap_base_with_index:
1777 xchg bl,bh
1778 jmp check_immediate_address
1779 check_for_rbp_base:
1780 cmp bh,45h
1781 je swap_base_with_index
1782 cmp bh,85h
1783 je swap_base_with_index
1784 jmp check_immediate_address
1785 check_index_scale:
1786 test cl,not 1111b
1787 jnz invalid_address
1788 mov al,cl
1789 dec al
1790 and al,cl
1791 jz check_immediate_address
1792 jmp invalid_address
1793 check_vsib_address:
1794 cmp ah,0Ch
1795 je swap_vsib_registers
1796 cmp ah,0Dh
1797 jne check_vsib_base
1798 swap_vsib_registers:
1799 cmp cl,1
1800 ja invalid_address
1801 xchg bl,bh
1802 mov cl,1
1803 check_vsib_base:
1804 test bh,bh
1805 jz vsib_base_ok
1806 mov al,bh
1807 shr al,4
1808 cmp al,4
1809 je vsib_base_ok
1810 cmp [code_type],64
1811 jne invalid_address
1812 cmp al,8
1813 jne invalid_address
1814 vsib_base_ok:
1815 mov al,bl
1816 shr al,4
1817 cmp al,0Ch
1818 je check_index_scale
1819 cmp al,0Dh
1820 je check_index_scale
1821 jmp invalid_address
1822
1823 calculate_relative_offset:
1824 cmp [value_undefined],0
1825 jne relative_offset_ok
1826 test bh,bh
1827 setne ch
1828 cmp bx,[ds:ebp+10h]
1829 je origin_registers_ok
1830 xchg bh,bl
1831 xchg ch,cl
1832 cmp bx,[ds:ebp+10h]
1833 jne invalid_value
1834 origin_registers_ok:
1835 cmp cx,[ds:ebp+10h+2]
1836 jne invalid_value
1837 mov bl,[address_sign]
1838 add eax,[ds:ebp]
1839 adc edx,[ds:ebp+4]
1840 adc bl,[ds:ebp+8]
1841 sub eax,edi
1842 sbb edx,0
1843 sbb bl,0
1844 mov [value_sign],bl
1845 mov bl,[value_type]
1846 mov ecx,[address_symbol]
1847 mov [symbol_identifier],ecx
1848 test bl,1
1849 jnz relative_offset_unallowed
1850 cmp bl,6
1851 je plt_relative_offset
1852 mov bh,[ds:ebp+9]
1853 cmp bl,bh
1854 je set_relative_offset_type
1855 cmp bx,0402h
1856 je set_relative_offset_type
1857 relative_offset_unallowed:
1858 call recoverable_misuse
1859 set_relative_offset_type:
1860 cmp [value_type],0
1861 je relative_offset_ok
1862 mov [value_type],0
1863 cmp ecx,[ds:ebp+14h]
1864 je relative_offset_ok
1865 mov [value_type],3
1866 relative_offset_ok:
1867 ret
1868 plt_relative_offset:
1869 mov [value_type],7
1870 cmp byte [ds:ebp+9],2
1871 je relative_offset_ok
1872 cmp byte [ds:ebp+9],4
1873 jne recoverable_misuse
1874 ret
1875
1876 calculate_logical_expression:
1877 xor al,al
1878 calculate_embedded_logical_expression:
1879 mov [logical_value_wrapping],al
1880 call get_logical_value
1881 logical_loop:
1882 cmp byte [esi],'|'
1883 je logical_or
1884 cmp byte [esi],'&'
1885 je logical_and
1886 ret
1887 logical_or:
1888 inc esi
1889 or al,al
1890 jnz logical_value_already_determined
1891 push eax
1892 call get_logical_value
1893 pop ebx
1894 or al,bl
1895 jmp logical_loop
1896 logical_and:
1897 inc esi
1898 or al,al
1899 jz logical_value_already_determined
1900 push eax
1901 call get_logical_value
1902 pop ebx
1903 and al,bl
1904 jmp logical_loop
1905 logical_value_already_determined:
1906 push eax
1907 call skip_logical_value
1908 jc invalid_expression
1909 pop eax
1910 jmp logical_loop
1911 get_value_for_comparison:
1912 mov [value_size],8
1913 mov [size_override],-1
1914 lods byte [esi]
1915 call calculate_expression
1916 cmp byte [edi+8],0
1917 jne first_register_size_ok
1918 mov byte [edi+10],0
1919 first_register_size_ok:
1920 cmp byte [edi+9],0
1921 jne second_register_size_ok
1922 mov byte [edi+11],0
1923 second_register_size_ok:
1924 mov eax,[edi+16]
1925 mov [symbol_identifier],eax
1926 mov al,[edi+13]
1927 mov [value_sign],al
1928 mov bl,[edi+12]
1929 mov eax,[edi]
1930 mov edx,[edi+4]
1931 mov ecx,[edi+8]
1932 ret
1933 get_logical_value:
1934 xor al,al
1935 check_for_negation:
1936 cmp byte [esi],'~'
1937 jne negation_ok
1938 inc esi
1939 xor al,-1
1940 jmp check_for_negation
1941 negation_ok:
1942 push eax
1943 mov al,[esi]
1944 cmp al,'{'
1945 je logical_expression
1946 cmp al,0FFh
1947 je invalid_expression
1948 cmp al,88h
1949 je check_for_defined
1950 cmp al,89h
1951 je check_for_used
1952 cmp al,'0'
1953 je given_false
1954 cmp al,'1'
1955 je given_true
1956 cmp al,'('
1957 jne invalid_value
1958 call get_value_for_comparison
1959 mov bh,[value_sign]
1960 push eax edx [symbol_identifier] ebx ecx
1961 mov al,[esi]
1962 or al,al
1963 jz logical_number
1964 cmp al,0Fh
1965 je logical_number
1966 cmp al,'}'
1967 je logical_number
1968 cmp al,'&'
1969 je logical_number
1970 cmp al,'|'
1971 je logical_number
1972 inc esi
1973 mov [compare_type],al
1974 cmp byte [esi],'('
1975 jne invalid_value
1976 call get_value_for_comparison
1977 cmp bl,[esp+4]
1978 jne values_not_relative
1979 or bl,bl
1980 jz check_values_registers
1981 mov ebx,[symbol_identifier]
1982 cmp ebx,[esp+8]
1983 jne values_not_relative
1984 check_values_registers:
1985 cmp ecx,[esp]
1986 je values_relative
1987 ror ecx,16
1988 xchg ch,cl
1989 ror ecx,16
1990 xchg ch,cl
1991 cmp ecx,[esp]
1992 je values_relative
1993 values_not_relative:
1994 cmp [compare_type],0F8h
1995 jne invalid_comparison
1996 add esp,12+8
1997 jmp return_false
1998 invalid_comparison:
1999 call recoverable_misuse
2000 values_relative:
2001 pop ebx
2002 shl ebx,16
2003 mov bx,[esp]
2004 add esp,8
2005 pop ecx ebp
2006 cmp [compare_type],'='
2007 je check_equal
2008 cmp [compare_type],0F1h
2009 je check_not_equal
2010 cmp [compare_type],0F8h
2011 je return_true
2012 test ebx,0FFFF0000h
2013 jz check_less_or_greater
2014 call recoverable_misuse
2015 check_less_or_greater:
2016 cmp [compare_type],'>'
2017 je check_greater
2018 cmp [compare_type],'<'
2019 je check_less
2020 cmp [compare_type],0F2h
2021 je check_not_less
2022 cmp [compare_type],0F3h
2023 je check_not_greater
2024 jmp invalid_expression
2025 check_equal:
2026 cmp bh,[value_sign]
2027 jne return_false
2028 cmp eax,ebp
2029 jne return_false
2030 cmp edx,ecx
2031 jne return_false
2032 jmp return_true
2033 check_greater:
2034 cmp bh,[value_sign]
2035 jg return_true
2036 jl return_false
2037 cmp edx,ecx
2038 jb return_true
2039 ja return_false
2040 cmp eax,ebp
2041 jb return_true
2042 jae return_false
2043 check_less:
2044 cmp bh,[value_sign]
2045 jg return_false
2046 jl return_true
2047 cmp edx,ecx
2048 jb return_false
2049 ja return_true
2050 cmp eax,ebp
2051 jbe return_false
2052 ja return_true
2053 check_not_less:
2054 cmp bh,[value_sign]
2055 jg return_true
2056 jl return_false
2057 cmp edx,ecx
2058 jb return_true
2059 ja return_false
2060 cmp eax,ebp
2061 jbe return_true
2062 ja return_false
2063 check_not_greater:
2064 cmp bh,[value_sign]
2065 jg return_false
2066 jl return_true
2067 cmp edx,ecx
2068 jb return_false
2069 ja return_true
2070 cmp eax,ebp
2071 jb return_false
2072 jae return_true
2073 check_not_equal:
2074 cmp bh,[value_sign]
2075 jne return_true
2076 cmp eax,ebp
2077 jne return_true
2078 cmp edx,ecx
2079 jne return_true
2080 jmp return_false
2081 logical_number:
2082 pop ecx ebx eax edx eax
2083 or bl,bl
2084 jnz invalid_logical_number
2085 or cx,cx
2086 jz logical_number_ok
2087 invalid_logical_number:
2088 call recoverable_misuse
2089 logical_number_ok:
2090 test bh,bh
2091 jnz return_true
2092 or eax,edx
2093 jnz return_true
2094 jmp return_false
2095 check_for_defined:
2096 or bl,-1
2097 lods word [esi]
2098 cmp ah,'('
2099 jne invalid_expression
2100 check_expression:
2101 lods byte [esi]
2102 or al,al
2103 jz defined_string
2104 cmp al,'.'
2105 je defined_fp_value
2106 cmp al,')'
2107 je expression_checked
2108 cmp al,'!'
2109 je invalid_expression
2110 cmp al,0Fh
2111 je check_expression
2112 cmp al,10h
2113 je defined_register
2114 cmp al,11h
2115 je check_if_symbol_defined
2116 cmp al,80h
2117 jae check_expression
2118 movzx eax,al
2119 add esi,eax
2120 jmp check_expression
2121 defined_register:
2122 inc esi
2123 jmp check_expression
2124 defined_fp_value:
2125 add esi,12
2126 jmp expression_checked
2127 defined_string:
2128 lods dword [esi]
2129 add esi,eax
2130 inc esi
2131 jmp expression_checked
2132 check_if_symbol_defined:
2133 lods dword [esi]
2134 cmp eax,-1
2135 je invalid_expression
2136 cmp eax,0Fh
2137 jb check_expression
2138 je reserved_word_used_as_symbol
2139 test byte [eax+8],4
2140 jnz no_prediction
2141 test byte [eax+8],1
2142 jz symbol_predicted_undefined
2143 mov cx,[current_pass]
2144 sub cx,[eax+16]
2145 jz check_expression
2146 cmp cx,1
2147 ja symbol_predicted_undefined
2148 or byte [eax+8],40h+80h
2149 jmp check_expression
2150 no_prediction:
2151 test byte [eax+8],1
2152 jz symbol_undefined
2153 mov cx,[current_pass]
2154 sub cx,[eax+16]
2155 jz check_expression
2156 jmp symbol_undefined
2157 symbol_predicted_undefined:
2158 or byte [eax+8],40h
2159 and byte [eax+8],not 80h
2160 symbol_undefined:
2161 xor bl,bl
2162 jmp check_expression
2163 expression_checked:
2164 mov al,bl
2165 jmp logical_value_ok
2166 check_for_used:
2167 lods word [esi]
2168 cmp ah,2
2169 jne invalid_expression
2170 lods dword [esi]
2171 cmp eax,0Fh
2172 jb invalid_use_of_symbol
2173 je reserved_word_used_as_symbol
2174 inc esi
2175 test byte [eax+8],8
2176 jz not_used
2177 mov cx,[current_pass]
2178 sub cx,[eax+18]
2179 jz return_true
2180 cmp cx,1
2181 ja not_used
2182 or byte [eax+8],10h+20h
2183 jmp return_true
2184 not_used:
2185 or byte [eax+8],10h
2186 and byte [eax+8],not 20h
2187 jmp return_false
2188 given_false:
2189 inc esi
2190 return_false:
2191 xor al,al
2192 jmp logical_value_ok
2193 given_true:
2194 inc esi
2195 return_true:
2196 or al,-1
2197 jmp logical_value_ok
2198 logical_expression:
2199 lods byte [esi]
2200 mov dl,[logical_value_wrapping]
2201 push edx
2202 call calculate_embedded_logical_expression
2203 pop edx
2204 mov [logical_value_wrapping],dl
2205 push eax
2206 lods byte [esi]
2207 cmp al,'}'
2208 jne invalid_expression
2209 pop eax
2210 logical_value_ok:
2211 pop ebx
2212 xor al,bl
2213 ret
2214
2215 skip_symbol:
2216 lods byte [esi]
2217 or al,al
2218 jz nothing_to_skip
2219 cmp al,0Fh
2220 je nothing_to_skip
2221 cmp al,1
2222 je skip_instruction
2223 cmp al,2
2224 je skip_label
2225 cmp al,3
2226 je skip_label
2227 cmp al,4
2228 je skip_special_label
2229 cmp al,20h
2230 jb skip_assembler_symbol
2231 cmp al,'('
2232 je skip_expression
2233 cmp al,'['
2234 je skip_address
2235 skip_done:
2236 clc
2237 ret
2238 skip_label:
2239 add esi,2
2240 skip_instruction:
2241 add esi,2
2242 skip_assembler_symbol:
2243 inc esi
2244 jmp skip_done
2245 skip_special_label:
2246 add esi,4
2247 jmp skip_done
2248 skip_address:
2249 mov al,[esi]
2250 and al,11110000b
2251 cmp al,60h
2252 jb skip_expression
2253 cmp al,70h
2254 ja skip_expression
2255 inc esi
2256 jmp skip_address
2257 skip_expression:
2258 lods byte [esi]
2259 or al,al
2260 jz skip_string
2261 cmp al,'.'
2262 je skip_fp_value
2263 cmp al,')'
2264 je skip_done
2265 cmp al,']'
2266 je skip_done
2267 cmp al,'!'
2268 je skip_expression
2269 cmp al,0Fh
2270 je skip_expression
2271 cmp al,10h
2272 je skip_register
2273 cmp al,11h
2274 je skip_label_value
2275 cmp al,80h
2276 jae skip_expression
2277 movzx eax,al
2278 add esi,eax
2279 jmp skip_expression
2280 skip_label_value:
2281 add esi,3
2282 skip_register:
2283 inc esi
2284 jmp skip_expression
2285 skip_fp_value:
2286 add esi,12
2287 jmp skip_done
2288 skip_string:
2289 lods dword [esi]
2290 add esi,eax
2291 inc esi
2292 jmp skip_done
2293 nothing_to_skip:
2294 dec esi
2295 stc
2296 ret
2297
2298 expand_path:
2299 lods byte [esi]
2300 cmp al,'%'
2301 je environment_variable
2302 stos byte [edi]
2303 or al,al
2304 jnz expand_path
2305 cmp edi,[memory_end]
2306 ja out_of_memory
2307 ret
2308 environment_variable:
2309 mov ebx,esi
2310 find_variable_end:
2311 lods byte [esi]
2312 or al,al
2313 jz not_environment_variable
2314 cmp al,'%'
2315 jne find_variable_end
2316 mov byte [esi-1],0
2317 push esi
2318 mov esi,ebx
2319 call get_environment_variable
2320 pop esi
2321 mov byte [esi-1],'%'
2322 jmp expand_path
2323 not_environment_variable:
2324 mov al,'%'
2325 stos byte [edi]
2326 mov esi,ebx
2327 jmp expand_path
2328 get_include_directory:
2329 lods byte [esi]
2330 cmp al,';'
2331 je include_directory_ok
2332 stos byte [edi]
2333 or al,al
2334 jnz get_include_directory
2335 dec esi
2336 dec edi
2337 include_directory_ok:
2338 cmp byte [edi-1],'/'
2339 je path_separator_ok
2340 cmp byte [edi-1],'\'
2341 je path_separator_ok
2342 mov al,'/'
2343 stos byte [edi]
2344 path_separator_ok:
2345 ret
0
1 ; flat assembler core
2 ; Copyright (c) 1999-2014, Tomasz Grysztar.
3 ; All rights reserved.
4
5 convert_expression:
6 push ebp
7 call get_fp_value
8 jnc fp_expression
9 mov [current_offset],esp
10 expression_loop:
11 push edi
12 mov edi,single_operand_operators
13 call get_operator
14 pop edi
15 or al,al
16 jz expression_element
17 cmp al,82h
18 je expression_loop
19 push eax
20 jmp expression_loop
21 expression_element:
22 mov al,[esi]
23 cmp al,1Ah
24 je expression_number
25 cmp al,22h
26 je expression_number
27 cmp al,'('
28 je expression_number
29 mov al,'!'
30 stos byte [edi]
31 jmp expression_operator
32 expression_number:
33 call convert_number
34 expression_operator:
35 push edi
36 mov edi,operators
37 call get_operator
38 pop edi
39 or al,al
40 jz expression_end
41 operators_loop:
42 cmp esp,[current_offset]
43 je push_operator
44 mov bl,al
45 and bl,0F0h
46 mov bh,byte [esp]
47 and bh,0F0h
48 cmp bl,bh
49 ja push_operator
50 pop ebx
51 mov byte [edi],bl
52 inc edi
53 jmp operators_loop
54 push_operator:
55 push eax
56 jmp expression_loop
57 expression_end:
58 cmp esp,[current_offset]
59 je expression_converted
60 pop eax
61 stos byte [edi]
62 jmp expression_end
63 expression_converted:
64 pop ebp
65 ret
66 fp_expression:
67 mov al,'.'
68 stos byte [edi]
69 mov eax,[fp_value]
70 stos dword [edi]
71 mov eax,[fp_value+4]
72 stos dword [edi]
73 mov eax,[fp_value+8]
74 stos dword [edi]
75 pop ebp
76 ret
77
78 convert_number:
79 lea eax,[edi-10h]
80 mov edx,[memory_end]
81 cmp [source_start],0
82 je check_memory_for_number
83 mov edx,[labels_list]
84 check_memory_for_number:
85 cmp eax,edx
86 jae out_of_memory
87 mov eax,esp
88 sub eax,100h
89 jc stack_overflow
90 cmp eax,[stack_limit]
91 jb stack_overflow
92 cmp byte [esi],'('
93 je expression_value
94 inc edi
95 call get_number
96 jc symbol_value
97 or ebp,ebp
98 jz valid_number
99 mov byte [edi-1],0Fh
100 ret
101 valid_number:
102 cmp dword [edi+4],0
103 jne qword_number
104 cmp word [edi+2],0
105 jne dword_number
106 cmp byte [edi+1],0
107 jne word_number
108 byte_number:
109 mov byte [edi-1],1
110 inc edi
111 ret
112 qword_number:
113 mov byte [edi-1],8
114 add edi,8
115 ret
116 dword_number:
117 mov byte [edi-1],4
118 scas dword [edi]
119 ret
120 word_number:
121 mov byte [edi-1],2
122 scas word [edi]
123 ret
124 expression_value:
125 inc esi
126 push [current_offset]
127 call convert_expression
128 pop [current_offset]
129 lods byte [esi]
130 cmp al,')'
131 jne invalid_expression
132 ret
133 symbol_value:
134 cmp [source_start],0
135 je preprocessor_value
136 push edi esi
137 lods word [esi]
138 cmp al,1Ah
139 jne no_address_register
140 movzx ecx,ah
141 call get_symbol
142 jc no_address_register
143 cmp al,10h
144 jne no_address_register
145 mov al,ah
146 shr ah,4
147 cmp ah,4
148 je register_value
149 cmp ah,8
150 je register_value
151 cmp ah,0Ch
152 je register_value
153 cmp ah,0Dh
154 je register_value
155 cmp ah,0Fh
156 je register_value
157 cmp ah,2
158 jne no_address_register
159 cmp al,23h
160 je register_value
161 cmp al,25h
162 je register_value
163 cmp al,26h
164 je register_value
165 cmp al,27h
166 je register_value
167 no_address_register:
168 pop esi
169 mov edi,directive_operators
170 call get_operator
171 pop edi
172 or al,al
173 jnz broken_value
174 lods byte [esi]
175 cmp al,1Ah
176 jne invalid_value
177 lods byte [esi]
178 movzx ecx,al
179 call get_label_id
180 store_label_value:
181 mov byte [edi-1],11h
182 stos dword [edi]
183 ret
184 broken_value:
185 mov eax,0Fh
186 jmp store_label_value
187 register_value:
188 pop edx edi
189 mov byte [edi-1],10h
190 stos byte [edi]
191 ret
192 preprocessor_value:
193 dec edi
194 cmp [hash_tree],0
195 je invalid_value
196 lods byte [esi]
197 cmp al,1Ah
198 jne invalid_value
199 lods byte [esi]
200 mov cl,al
201 mov ch,10b
202 call get_preprocessor_symbol
203 jc invalid_value
204 push esi
205 mov esi,[edx+8]
206 push [current_offset]
207 call convert_expression
208 pop [current_offset]
209 pop esi
210 ret
211
212 get_number:
213 xor ebp,ebp
214 lods byte [esi]
215 cmp al,22h
216 je get_text_number
217 cmp al,1Ah
218 jne not_number
219 lods byte [esi]
220 movzx ecx,al
221 mov [number_start],esi
222 mov al,[esi]
223 cmp al,'$'
224 je number_begin
225 sub al,30h
226 cmp al,9
227 ja invalid_number
228 number_begin:
229 mov ebx,esi
230 add esi,ecx
231 push esi
232 dec esi
233 mov dword [edi],0
234 mov dword [edi+4],0
235 cmp byte [ebx],'$'
236 je pascal_hex_number
237 cmp word [ebx],'0x'
238 je get_hex_number
239 mov al,[esi]
240 dec esi
241 cmp al,'h'
242 je get_hex_number
243 cmp al,'b'
244 je get_bin_number
245 cmp al,'d'
246 je get_dec_number
247 cmp al,'o'
248 je get_oct_number
249 cmp al,'H'
250 je get_hex_number
251 cmp al,'B'
252 je get_bin_number
253 cmp al,'D'
254 je get_dec_number
255 cmp al,'O'
256 je get_oct_number
257 inc esi
258 get_dec_number:
259 mov ebx,esi
260 mov esi,[number_start]
261 get_dec_digit:
262 cmp esi,ebx
263 ja number_ok
264 cmp byte [esi],27h
265 je next_dec_digit
266 xor edx,edx
267 mov eax,[edi]
268 shld edx,eax,2
269 shl eax,2
270 add eax,[edi]
271 adc edx,0
272 add eax,eax
273 adc edx,edx
274 mov [edi],eax
275 mov eax,[edi+4]
276 add eax,eax
277 jc dec_out_of_range
278 add eax,eax
279 jc dec_out_of_range
280 add eax,[edi+4]
281 jc dec_out_of_range
282 add eax,eax
283 jc dec_out_of_range
284 add eax,edx
285 jc dec_out_of_range
286 mov [edi+4],eax
287 movzx eax,byte [esi]
288 sub al,30h
289 jc bad_number
290 cmp al,9
291 ja bad_number
292 add [edi],eax
293 adc dword [edi+4],0
294 jc dec_out_of_range
295 next_dec_digit:
296 inc esi
297 jmp get_dec_digit
298 dec_out_of_range:
299 cmp esi,ebx
300 ja dec_out_of_range_finished
301 lods byte [esi]
302 cmp al,27h
303 je bad_number
304 sub al,30h
305 jc bad_number
306 cmp al,9
307 ja bad_number
308 jmp dec_out_of_range
309 dec_out_of_range_finished:
310 or ebp,-1
311 jmp number_ok
312 bad_number:
313 pop eax
314 invalid_number:
315 mov esi,[number_start]
316 dec esi
317 not_number:
318 dec esi
319 stc
320 ret
321 get_bin_number:
322 xor bl,bl
323 get_bin_digit:
324 cmp esi,[number_start]
325 jb number_ok
326 movzx eax,byte [esi]
327 cmp al,27h
328 je bin_digit_skip
329 sub al,30h
330 cmp al,1
331 ja bad_number
332 xor edx,edx
333 mov cl,bl
334 dec esi
335 cmp bl,64
336 je bin_out_of_range
337 inc bl
338 cmp cl,32
339 jae bin_digit_high
340 shl eax,cl
341 or dword [edi],eax
342 jmp get_bin_digit
343 bin_digit_high:
344 sub cl,32
345 shl eax,cl
346 or dword [edi+4],eax
347 jmp get_bin_digit
348 bin_out_of_range:
349 or al,al
350 jz get_bin_digit
351 or ebp,-1
352 jmp get_bin_digit
353 bin_digit_skip:
354 dec esi
355 jmp get_bin_digit
356 pascal_hex_number:
357 cmp cl,1
358 je bad_number
359 get_hex_number:
360 xor bl,bl
361 get_hex_digit:
362 cmp esi,[number_start]
363 jb number_ok
364 movzx eax,byte [esi]
365 cmp al,27h
366 je hex_digit_skip
367 cmp al,'x'
368 je hex_number_ok
369 cmp al,'$'
370 je pascal_hex_ok
371 sub al,30h
372 cmp al,9
373 jbe hex_digit_ok
374 sub al,7
375 cmp al,15
376 jbe hex_letter_digit_ok
377 sub al,20h
378 cmp al,15
379 ja bad_number
380 hex_letter_digit_ok:
381 cmp al,10
382 jb bad_number
383 hex_digit_ok:
384 xor edx,edx
385 mov cl,bl
386 dec esi
387 cmp bl,64
388 je hex_out_of_range
389 add bl,4
390 cmp cl,32
391 jae hex_digit_high
392 shl eax,cl
393 or dword [edi],eax
394 jmp get_hex_digit
395 hex_digit_high:
396 sub cl,32
397 shl eax,cl
398 or dword [edi+4],eax
399 jmp get_hex_digit
400 hex_out_of_range:
401 or al,al
402 jz get_hex_digit
403 or ebp,-1
404 jmp get_hex_digit
405 hex_digit_skip:
406 dec esi
407 jmp get_hex_digit
408 get_oct_number:
409 xor bl,bl
410 get_oct_digit:
411 cmp esi,[number_start]
412 jb number_ok
413 movzx eax,byte [esi]
414 cmp al,27h
415 je oct_digit_skip
416 sub al,30h
417 cmp al,7
418 ja bad_number
419 oct_digit_ok:
420 xor edx,edx
421 mov cl,bl
422 dec esi
423 cmp bl,63
424 ja oct_out_of_range
425 jne oct_range_ok
426 cmp al,1
427 ja oct_out_of_range
428 oct_range_ok:
429 add bl,3
430 cmp cl,30
431 je oct_digit_wrap
432 ja oct_digit_high
433 shl eax,cl
434 or dword [edi],eax
435 jmp get_oct_digit
436 oct_digit_wrap:
437 shl eax,cl
438 adc dword [edi+4],0
439 or dword [edi],eax
440 jmp get_oct_digit
441 oct_digit_high:
442 sub cl,32
443 shl eax,cl
444 or dword [edi+4],eax
445 jmp get_oct_digit
446 oct_digit_skip:
447 dec esi
448 jmp get_oct_digit
449 oct_out_of_range:
450 or al,al
451 jz get_oct_digit
452 or ebp,-1
453 jmp get_oct_digit
454 hex_number_ok:
455 dec esi
456 pascal_hex_ok:
457 cmp esi,[number_start]
458 jne bad_number
459 number_ok:
460 pop esi
461 number_done:
462 clc
463 ret
464 get_text_number:
465 lods dword [esi]
466 mov edx,eax
467 xor bl,bl
468 mov dword [edi],0
469 mov dword [edi+4],0
470 get_text_character:
471 sub edx,1
472 jc number_done
473 movzx eax,byte [esi]
474 inc esi
475 mov cl,bl
476 cmp bl,64
477 je text_out_of_range
478 add bl,8
479 cmp cl,32
480 jae text_character_high
481 shl eax,cl
482 or dword [edi],eax
483 jmp get_text_character
484 text_character_high:
485 sub cl,32
486 shl eax,cl
487 or dword [edi+4],eax
488 jmp get_text_character
489 text_out_of_range:
490 or ebp,-1
491 jmp get_text_character
492
493 get_fp_value:
494 push edi esi
495 lods byte [esi]
496 cmp al,1Ah
497 je fp_value_start
498 cmp al,'-'
499 je fp_sign_ok
500 cmp al,'+'
501 jne not_fp_value
502 fp_sign_ok:
503 lods byte [esi]
504 cmp al,1Ah
505 jne not_fp_value
506 fp_value_start:
507 lods byte [esi]
508 movzx ecx,al
509 cmp cl,1
510 jbe not_fp_value
511 lea edx,[esi+1]
512 xor ah,ah
513 check_fp_value:
514 lods byte [esi]
515 cmp al,'.'
516 je fp_character_dot
517 cmp al,'E'
518 je fp_character_exp
519 cmp al,'e'
520 je fp_character_exp
521 cmp al,'F'
522 je fp_last_character
523 cmp al,'f'
524 je fp_last_character
525 digit_expected:
526 cmp al,'0'
527 jb not_fp_value
528 cmp al,'9'
529 ja not_fp_value
530 jmp fp_character_ok
531 fp_character_dot:
532 cmp esi,edx
533 je not_fp_value
534 or ah,ah
535 jnz not_fp_value
536 or ah,1
537 lods byte [esi]
538 loop digit_expected
539 not_fp_value:
540 pop esi edi
541 stc
542 ret
543 fp_last_character:
544 cmp cl,1
545 jne not_fp_value
546 or ah,4
547 jmp fp_character_ok
548 fp_character_exp:
549 cmp esi,edx
550 je not_fp_value
551 cmp ah,1
552 ja not_fp_value
553 or ah,2
554 cmp ecx,1
555 jne fp_character_ok
556 cmp byte [esi],'+'
557 je fp_exp_sign
558 cmp byte [esi],'-'
559 jne fp_character_ok
560 fp_exp_sign:
561 inc esi
562 cmp byte [esi],1Ah
563 jne not_fp_value
564 inc esi
565 lods byte [esi]
566 movzx ecx,al
567 inc ecx
568 fp_character_ok:
569 dec ecx
570 jnz check_fp_value
571 or ah,ah
572 jz not_fp_value
573 pop esi
574 lods byte [esi]
575 mov [fp_sign],0
576 cmp al,1Ah
577 je fp_get
578 inc esi
579 cmp al,'+'
580 je fp_get
581 mov [fp_sign],1
582 fp_get:
583 lods byte [esi]
584 movzx ecx,al
585 xor edx,edx
586 mov edi,fp_value
587 mov [edi],edx
588 mov [edi+4],edx
589 mov [edi+12],edx
590 call fp_optimize
591 mov [fp_format],0
592 mov al,[esi]
593 fp_before_dot:
594 lods byte [esi]
595 cmp al,'.'
596 je fp_dot
597 cmp al,'E'
598 je fp_exponent
599 cmp al,'e'
600 je fp_exponent
601 cmp al,'F'
602 je fp_done
603 cmp al,'f'
604 je fp_done
605 sub al,30h
606 mov edi,fp_value+16
607 xor edx,edx
608 mov dword [edi+12],edx
609 mov dword [edi],edx
610 mov dword [edi+4],edx
611 mov [edi+7],al
612 mov dl,7
613 mov dword [edi+8],edx
614 call fp_optimize
615 mov edi,fp_value
616 push ecx
617 mov ecx,10
618 call fp_mul
619 pop ecx
620 mov ebx,fp_value+16
621 call fp_add
622 loop fp_before_dot
623 fp_dot:
624 mov edi,fp_value+16
625 xor edx,edx
626 mov [edi],edx
627 mov [edi+4],edx
628 mov byte [edi+7],80h
629 mov [edi+8],edx
630 mov dword [edi+12],edx
631 dec ecx
632 jz fp_done
633 fp_after_dot:
634 lods byte [esi]
635 cmp al,'E'
636 je fp_exponent
637 cmp al,'e'
638 je fp_exponent
639 cmp al,'F'
640 je fp_done
641 cmp al,'f'
642 je fp_done
643 inc [fp_format]
644 cmp [fp_format],80h
645 jne fp_counter_ok
646 mov [fp_format],7Fh
647 fp_counter_ok:
648 dec esi
649 mov edi,fp_value+16
650 push ecx
651 mov ecx,10
652 call fp_div
653 push dword [edi]
654 push dword [edi+4]
655 push dword [edi+8]
656 push dword [edi+12]
657 lods byte [esi]
658 sub al,30h
659 movzx ecx,al
660 call fp_mul
661 mov ebx,edi
662 mov edi,fp_value
663 call fp_add
664 mov edi,fp_value+16
665 pop dword [edi+12]
666 pop dword [edi+8]
667 pop dword [edi+4]
668 pop dword [edi]
669 pop ecx
670 dec ecx
671 jnz fp_after_dot
672 jmp fp_done
673 fp_exponent:
674 or [fp_format],80h
675 xor edx,edx
676 xor ebp,ebp
677 dec ecx
678 jnz get_exponent
679 cmp byte [esi],'+'
680 je fp_exponent_sign
681 cmp byte [esi],'-'
682 jne fp_done
683 not ebp
684 fp_exponent_sign:
685 add esi,2
686 lods byte [esi]
687 movzx ecx,al
688 get_exponent:
689 movzx eax,byte [esi]
690 inc esi
691 sub al,30h
692 cmp al,10
693 jae exponent_ok
694 imul edx,10
695 cmp edx,8000h
696 jae value_out_of_range
697 add edx,eax
698 loop get_exponent
699 exponent_ok:
700 mov edi,fp_value
701 or edx,edx
702 jz fp_done
703 mov ecx,edx
704 or ebp,ebp
705 jnz fp_negative_power
706 fp_power:
707 push ecx
708 mov ecx,10
709 call fp_mul
710 pop ecx
711 loop fp_power
712 jmp fp_done
713 fp_negative_power:
714 push ecx
715 mov ecx,10
716 call fp_div
717 pop ecx
718 loop fp_negative_power
719 fp_done:
720 mov edi,fp_value
721 mov al,[fp_format]
722 mov [edi+10],al
723 mov al,[fp_sign]
724 mov [edi+11],al
725 test byte [edi+15],80h
726 jz fp_ok
727 add dword [edi],1
728 adc dword [edi+4],0
729 jnc fp_ok
730 mov eax,[edi+4]
731 shrd [edi],eax,1
732 shr eax,1
733 or eax,80000000h
734 mov [edi+4],eax
735 inc word [edi+8]
736 fp_ok:
737 pop edi
738 clc
739 ret
740 fp_mul:
741 or ecx,ecx
742 jz fp_zero
743 mov eax,[edi+12]
744 mul ecx
745 mov [edi+12],eax
746 mov ebx,edx
747 mov eax,[edi]
748 mul ecx
749 add eax,ebx
750 adc edx,0
751 mov [edi],eax
752 mov ebx,edx
753 mov eax,[edi+4]
754 mul ecx
755 add eax,ebx
756 adc edx,0
757 mov [edi+4],eax
758 .loop:
759 or edx,edx
760 jz .done
761 mov eax,[edi]
762 shrd [edi+12],eax,1
763 mov eax,[edi+4]
764 shrd [edi],eax,1
765 shrd eax,edx,1
766 mov [edi+4],eax
767 shr edx,1
768 inc dword [edi+8]
769 cmp dword [edi+8],8000h
770 jge value_out_of_range
771 jmp .loop
772 .done:
773 ret
774 fp_div:
775 mov eax,[edi+4]
776 xor edx,edx
777 div ecx
778 mov [edi+4],eax
779 mov eax,[edi]
780 div ecx
781 mov [edi],eax
782 mov eax,[edi+12]
783 div ecx
784 mov [edi+12],eax
785 mov ebx,eax
786 or ebx,[edi]
787 or ebx,[edi+4]
788 jz fp_zero
789 .loop:
790 test byte [edi+7],80h
791 jnz .exp_ok
792 mov eax,[edi]
793 shld [edi+4],eax,1
794 mov eax,[edi+12]
795 shld [edi],eax,1
796 add eax,eax
797 mov [edi+12],eax
798 dec dword [edi+8]
799 add edx,edx
800 jmp .loop
801 .exp_ok:
802 mov eax,edx
803 xor edx,edx
804 div ecx
805 add [edi+12],eax
806 adc dword [edi],0
807 adc dword [edi+4],0
808 jnc .done
809 mov eax,[edi+4]
810 mov ebx,[edi]
811 shrd [edi],eax,1
812 shrd [edi+12],ebx,1
813 shr eax,1
814 or eax,80000000h
815 mov [edi+4],eax
816 inc dword [edi+8]
817 .done:
818 ret
819 fp_add:
820 cmp dword [ebx+8],8000h
821 je .done
822 cmp dword [edi+8],8000h
823 je .copy
824 mov eax,[ebx+8]
825 cmp eax,[edi+8]
826 jge .exp_ok
827 mov eax,[edi+8]
828 .exp_ok:
829 call .change_exp
830 xchg ebx,edi
831 call .change_exp
832 xchg ebx,edi
833 mov edx,[ebx+12]
834 mov eax,[ebx]
835 mov ebx,[ebx+4]
836 add [edi+12],edx
837 adc [edi],eax
838 adc [edi+4],ebx
839 jnc .done
840 mov eax,[edi]
841 shrd [edi+12],eax,1
842 mov eax,[edi+4]
843 shrd [edi],eax,1
844 shr eax,1
845 or eax,80000000h
846 mov [edi+4],eax
847 inc dword [edi+8]
848 .done:
849 ret
850 .copy:
851 mov eax,[ebx]
852 mov [edi],eax
853 mov eax,[ebx+4]
854 mov [edi+4],eax
855 mov eax,[ebx+8]
856 mov [edi+8],eax
857 mov eax,[ebx+12]
858 mov [edi+12],eax
859 ret
860 .change_exp:
861 push ecx
862 mov ecx,eax
863 sub ecx,[ebx+8]
864 mov edx,[ebx+4]
865 jecxz .exp_done
866 .exp_loop:
867 mov ebp,[ebx]
868 shrd [ebx+12],ebp,1
869 shrd [ebx],edx,1
870 shr edx,1
871 inc dword [ebx+8]
872 loop .exp_loop
873 .exp_done:
874 mov [ebx+4],edx
875 pop ecx
876 ret
877 fp_optimize:
878 mov eax,[edi]
879 mov ebp,[edi+4]
880 or ebp,[edi]
881 or ebp,[edi+12]
882 jz fp_zero
883 .loop:
884 test byte [edi+7],80h
885 jnz .done
886 shld [edi+4],eax,1
887 mov ebp,[edi+12]
888 shld eax,ebp,1
889 mov [edi],eax
890 shl dword [edi+12],1
891 dec dword [edi+8]
892 jmp .loop
893 .done:
894 ret
895 fp_zero:
896 mov dword [edi+8],8000h
897 ret
898
899 preevaluate_logical_expression:
900 xor al,al
901 preevaluate_embedded_logical_expression:
902 mov [logical_value_wrapping],al
903 push edi
904 call preevaluate_logical_value
905 preevaluation_loop:
906 cmp al,0FFh
907 je invalid_logical_expression
908 mov dl,[esi]
909 inc esi
910 cmp dl,'|'
911 je preevaluate_or
912 cmp dl,'&'
913 je preevaluate_and
914 cmp dl,'}'
915 je preevaluation_done
916 or dl,dl
917 jnz invalid_logical_expression
918 preevaluation_done:
919 pop edx
920 dec esi
921 ret
922 preevaluate_or:
923 cmp al,'1'
924 je quick_true
925 cmp al,'0'
926 je leave_only_following
927 push edi
928 mov al,dl
929 stos byte [edi]
930 call preevaluate_logical_value
931 pop ebx
932 cmp al,'0'
933 je leave_only_preceding
934 cmp al,'1'
935 jne preevaluation_loop
936 stos byte [edi]
937 xor al,al
938 jmp preevaluation_loop
939 preevaluate_and:
940 cmp al,'0'
941 je quick_false
942 cmp al,'1'
943 je leave_only_following
944 push edi
945 mov al,dl
946 stos byte [edi]
947 call preevaluate_logical_value
948 pop ebx
949 cmp al,'1'
950 je leave_only_preceding
951 cmp al,'0'
952 jne preevaluation_loop
953 stos byte [edi]
954 xor al,al
955 jmp preevaluation_loop
956 leave_only_following:
957 mov edi,[esp]
958 call preevaluate_logical_value
959 jmp preevaluation_loop
960 leave_only_preceding:
961 mov edi,ebx
962 xor al,al
963 jmp preevaluation_loop
964 quick_true:
965 call skip_logical_value
966 jc invalid_logical_expression
967 mov edi,[esp]
968 mov al,'1'
969 jmp preevaluation_loop
970 quick_false:
971 call skip_logical_value
972 jc invalid_logical_expression
973 mov edi,[esp]
974 mov al,'0'
975 jmp preevaluation_loop
976 invalid_logical_expression:
977 pop edi
978 mov esi,edi
979 mov al,0FFh
980 stos byte [edi]
981 ret
982 skip_logical_value:
983 cmp byte [esi],'~'
984 jne negation_skipped
985 inc esi
986 jmp skip_logical_value
987 negation_skipped:
988 mov al,[esi]
989 cmp al,'{'
990 jne skip_simple_logical_value
991 inc esi
992 xchg al,[logical_value_wrapping]
993 push eax
994 skip_logical_expression:
995 call skip_logical_value
996 lods byte [esi]
997 or al,al
998 jz wrongly_structured_logical_expression
999 cmp al,0Fh
1000 je wrongly_structured_logical_expression
1001 cmp al,'|'
1002 je skip_logical_expression
1003 cmp al,'&'
1004 je skip_logical_expression
1005 cmp al,'}'
1006 jne wrongly_structured_logical_expression
1007 pop eax
1008 mov [logical_value_wrapping],al
1009 logical_value_skipped:
1010 clc
1011 ret
1012 wrongly_structured_logical_expression:
1013 pop eax
1014 stc
1015 ret
1016 skip_simple_logical_value:
1017 mov [logical_value_parentheses],0
1018 find_simple_logical_value_end:
1019 mov al,[esi]
1020 or al,al
1021 jz logical_value_skipped
1022 cmp al,0Fh
1023 je logical_value_skipped
1024 cmp al,'|'
1025 je logical_value_skipped
1026 cmp al,'&'
1027 je logical_value_skipped
1028 cmp al,'{'
1029 je skip_logical_value_internal_parenthesis
1030 cmp al,'}'
1031 jne skip_logical_value_symbol
1032 sub [logical_value_parentheses],1
1033 jnc skip_logical_value_symbol
1034 cmp [logical_value_wrapping],'{'
1035 jne skip_logical_value_symbol
1036 jmp logical_value_skipped
1037 skip_logical_value_internal_parenthesis:
1038 inc [logical_value_parentheses]
1039 skip_logical_value_symbol:
1040 call skip_symbol
1041 jmp find_simple_logical_value_end
1042 preevaluate_logical_value:
1043 mov ebp,edi
1044 preevaluate_negation:
1045 cmp byte [esi],'~'
1046 jne preevaluate_negation_ok
1047 movs byte [edi],[esi]
1048 jmp preevaluate_negation
1049 preevaluate_negation_ok:
1050 mov ebx,esi
1051 cmp byte [esi],'{'
1052 jne preevaluate_simple_logical_value
1053 lods byte [esi]
1054 stos byte [edi]
1055 push ebp
1056 mov dl,[logical_value_wrapping]
1057 push edx
1058 call preevaluate_embedded_logical_expression
1059 pop edx
1060 mov [logical_value_wrapping],dl
1061 pop ebp
1062 cmp al,0FFh
1063 je invalid_logical_value
1064 cmp byte [esi],'}'
1065 jne invalid_logical_value
1066 or al,al
1067 jnz preevaluated_expression_value
1068 movs byte [edi],[esi]
1069 ret
1070 preevaluated_expression_value:
1071 inc esi
1072 lea edx,[edi-1]
1073 sub edx,ebp
1074 test edx,1
1075 jz expression_negation_ok
1076 xor al,1
1077 expression_negation_ok:
1078 mov edi,ebp
1079 ret
1080 invalid_logical_value:
1081 mov edi,ebp
1082 mov al,0FFh
1083 ret
1084 preevaluate_simple_logical_value:
1085 xor edx,edx
1086 mov [logical_value_parentheses],edx
1087 find_logical_value_boundaries:
1088 mov al,[esi]
1089 or al,al
1090 jz logical_value_boundaries_found
1091 cmp al,'{'
1092 je logical_value_internal_parentheses
1093 cmp al,'}'
1094 je logical_value_boundaries_parenthesis_close
1095 cmp al,'|'
1096 je logical_value_boundaries_found
1097 cmp al,'&'
1098 je logical_value_boundaries_found
1099 or edx,edx
1100 jnz next_symbol_in_logical_value
1101 cmp al,0F0h
1102 je preevaluable_logical_operator
1103 cmp al,0F7h
1104 je preevaluable_logical_operator
1105 cmp al,0F6h
1106 jne next_symbol_in_logical_value
1107 preevaluable_logical_operator:
1108 mov edx,esi
1109 next_symbol_in_logical_value:
1110 call skip_symbol
1111 jmp find_logical_value_boundaries
1112 logical_value_internal_parentheses:
1113 inc [logical_value_parentheses]
1114 jmp next_symbol_in_logical_value
1115 logical_value_boundaries_parenthesis_close:
1116 sub [logical_value_parentheses],1
1117 jnc next_symbol_in_logical_value
1118 cmp [logical_value_wrapping],'{'
1119 jne next_symbol_in_logical_value
1120 logical_value_boundaries_found:
1121 or edx,edx
1122 jz non_preevaluable_logical_value
1123 mov al,[edx]
1124 cmp al,0F0h
1125 je compare_symbols
1126 cmp al,0F7h
1127 je compare_symbol_types
1128 cmp al,0F6h
1129 je scan_symbols_list
1130 non_preevaluable_logical_value:
1131 mov ecx,esi
1132 mov esi,ebx
1133 sub ecx,esi
1134 jz invalid_logical_value
1135 cmp esi,edi
1136 je leave_logical_value_intact
1137 rep movs byte [edi],[esi]
1138 xor al,al
1139 ret
1140 leave_logical_value_intact:
1141 add edi,ecx
1142 add esi,ecx
1143 xor al,al
1144 ret
1145 compare_symbols:
1146 lea ecx,[esi-1]
1147 sub ecx,edx
1148 mov eax,edx
1149 sub eax,ebx
1150 cmp ecx,eax
1151 jne preevaluated_false
1152 push esi edi
1153 mov esi,ebx
1154 lea edi,[edx+1]
1155 repe cmps byte [esi],[edi]
1156 pop edi esi
1157 je preevaluated_true
1158 preevaluated_false:
1159 mov eax,edi
1160 sub eax,ebp
1161 test eax,1
1162 jnz store_true
1163 store_false:
1164 mov edi,ebp
1165 mov al,'0'
1166 ret
1167 preevaluated_true:
1168 mov eax,edi
1169 sub eax,ebp
1170 test eax,1
1171 jnz store_false
1172 store_true:
1173 mov edi,ebp
1174 mov al,'1'
1175 ret
1176 compare_symbol_types:
1177 push esi
1178 lea esi,[edx+1]
1179 type_comparison:
1180 cmp esi,[esp]
1181 je types_compared
1182 mov al,[esi]
1183 cmp al,[ebx]
1184 jne different_type
1185 cmp al,'('
1186 jne equal_type
1187 mov al,[esi+1]
1188 mov ah,[ebx+1]
1189 cmp al,ah
1190 je equal_type
1191 or al,al
1192 jz different_type
1193 or ah,ah
1194 jz different_type
1195 cmp al,'.'
1196 je different_type
1197 cmp ah,'.'
1198 je different_type
1199 equal_type:
1200 call skip_symbol
1201 xchg esi,ebx
1202 call skip_symbol
1203 xchg esi,ebx
1204 jmp type_comparison
1205 types_compared:
1206 pop esi
1207 cmp byte [ebx],0F7h
1208 jne preevaluated_false
1209 jmp preevaluated_true
1210 different_type:
1211 pop esi
1212 jmp preevaluated_false
1213 scan_symbols_list:
1214 push edi esi
1215 lea esi,[edx+1]
1216 sub edx,ebx
1217 lods byte [esi]
1218 cmp al,'<'
1219 jne invalid_symbols_list
1220 get_next_from_list:
1221 mov edi,esi
1222 get_from_list:
1223 cmp byte [esi],','
1224 je compare_in_list
1225 cmp byte [esi],'>'
1226 je compare_in_list
1227 cmp esi,[esp]
1228 jae invalid_symbols_list
1229 call skip_symbol
1230 jmp get_from_list
1231 compare_in_list:
1232 mov ecx,esi
1233 sub ecx,edi
1234 cmp ecx,edx
1235 jne not_equal_length_in_list
1236 mov esi,ebx
1237 repe cmps byte [esi],[edi]
1238 mov esi,edi
1239 jne not_equal_in_list
1240 skip_rest_of_list:
1241 cmp byte [esi],'>'
1242 je check_list_end
1243 cmp esi,[esp]
1244 jae invalid_symbols_list
1245 call skip_symbol
1246 jmp skip_rest_of_list
1247 check_list_end:
1248 inc esi
1249 cmp esi,[esp]
1250 jne invalid_symbols_list
1251 pop esi edi
1252 jmp preevaluated_true
1253 not_equal_in_list:
1254 add esi,ecx
1255 not_equal_length_in_list:
1256 lods byte [esi]
1257 cmp al,','
1258 je get_next_from_list
1259 cmp esi,[esp]
1260 jne invalid_symbols_list
1261 pop esi edi
1262 jmp preevaluated_false
1263 invalid_symbols_list:
1264 pop esi edi
1265 jmp invalid_logical_value
0
1 ; flat assembler core
2 ; Copyright (c) 1999-2014, Tomasz Grysztar.
3 ; All rights reserved.
4
5 formatter:
6 mov [current_offset],edi
7 cmp [output_file],0
8 jne output_path_ok
9 mov esi,[input_file]
10 mov edi,[free_additional_memory]
11 copy_output_path:
12 lods byte [esi]
13 cmp edi,[structures_buffer]
14 jae out_of_memory
15 stos byte [edi]
16 or al,al
17 jnz copy_output_path
18 dec edi
19 mov eax,edi
20 find_extension:
21 dec eax
22 cmp eax,[free_additional_memory]
23 jb extension_found
24 cmp byte [eax],'\'
25 je extension_found
26 cmp byte [eax],'/'
27 je extension_found
28 cmp byte [eax],'.'
29 jne find_extension
30 mov edi,eax
31 extension_found:
32 lea eax,[edi+9]
33 cmp eax,[structures_buffer]
34 jae out_of_memory
35 cmp [file_extension],0
36 jne extension_specified
37 mov al,[output_format]
38 cmp al,2
39 je exe_extension
40 jb bin_extension
41 cmp al,4
42 je obj_extension
43 cmp al,5
44 je o_extension
45 cmp al,3
46 jne no_extension
47 cmp [subsystem],1
48 je sys_extension
49 cmp [subsystem],10
50 jae efi_extension
51 bt [format_flags],8
52 jnc exe_extension
53 mov eax,'.dll'
54 jmp make_extension
55 sys_extension:
56 mov eax,'.sys'
57 jmp make_extension
58 efi_extension:
59 mov eax,'.efi'
60 jmp make_extension
61 bin_extension:
62 mov eax,'.bin'
63 bt [format_flags],0
64 jnc make_extension
65 mov eax,'.com'
66 jmp make_extension
67 obj_extension:
68 mov eax,'.obj'
69 jmp make_extension
70 o_extension:
71 mov eax,'.o'
72 bt [format_flags],0
73 jnc make_extension
74 no_extension:
75 xor eax,eax
76 jmp make_extension
77 exe_extension:
78 mov eax,'.exe'
79 make_extension:
80 xchg eax,[edi]
81 scas dword [edi]
82 mov byte [edi],0
83 scas byte [edi]
84 mov esi,edi
85 stos dword [edi]
86 sub edi,9
87 xor eax,eax
88 mov ebx,characters
89 adapt_case:
90 mov al,[esi]
91 or al,al
92 jz adapt_next
93 xlat byte [ebx]
94 cmp al,[esi]
95 je adapt_ok
96 sub byte [edi],20h
97 adapt_ok:
98 inc esi
99 adapt_next:
100 inc edi
101 cmp byte [edi],0
102 jne adapt_case
103 jmp extension_ok
104 extension_specified:
105 mov al,'.'
106 stos byte [edi]
107 mov esi,[file_extension]
108 copy_extension:
109 lods byte [esi]
110 stos byte [edi]
111 test al,al
112 jnz copy_extension
113 dec edi
114 extension_ok:
115 mov esi,edi
116 lea ecx,[esi+1]
117 sub ecx,[free_additional_memory]
118 mov edi,[structures_buffer]
119 dec edi
120 std
121 rep movs byte [edi],[esi]
122 cld
123 inc edi
124 mov [structures_buffer],edi
125 mov [output_file],edi
126 output_path_ok:
127 cmp [symbols_file],0
128 je labels_table_ok
129 mov ecx,[memory_end]
130 sub ecx,[labels_list]
131 mov edi,[tagged_blocks]
132 sub edi,8
133 mov [edi],ecx
134 or dword [edi+4],-1
135 sub edi,ecx
136 cmp edi,[current_offset]
137 jbe out_of_memory
138 mov [tagged_blocks],edi
139 mov esi,[memory_end]
140 copy_labels:
141 sub esi,32
142 cmp esi,[labels_list]
143 jb labels_table_ok
144 mov ecx,32 shr 2
145 rep movs dword [edi],[esi]
146 sub esi,32
147 jmp copy_labels
148 labels_table_ok:
149 mov edi,[current_offset]
150 cmp [output_format],4
151 je coff_formatter
152 cmp [output_format],5
153 jne common_formatter
154 bt [format_flags],0
155 jnc elf_formatter
156 common_formatter:
157 mov eax,edi
158 sub eax,[code_start]
159 mov [real_code_size],eax
160 cmp edi,[undefined_data_end]
161 jne calculate_code_size
162 mov edi,[undefined_data_start]
163 calculate_code_size:
164 mov [current_offset],edi
165 sub edi,[code_start]
166 mov [code_size],edi
167 and [written_size],0
168 mov edx,[output_file]
169 call create
170 jc write_failed
171 cmp [output_format],3
172 jne stub_written
173 mov edx,[code_start]
174 mov ecx,[stub_size]
175 sub edx,ecx
176 add [written_size],ecx
177 call write
178 stub_written:
179 cmp [output_format],2
180 jne write_output
181 call write_mz_header
182 write_output:
183 call write_code
184 output_written:
185 call close
186 cmp [symbols_file],0
187 jne dump_symbols
188 ret
189 write_code:
190 mov eax,[written_size]
191 mov [headers_size],eax
192 mov edx,[code_start]
193 mov ecx,[code_size]
194 add [written_size],ecx
195 lea eax,[edx+ecx]
196 call write
197 jc write_failed
198 ret
199 format_directive:
200 cmp edi,[code_start]
201 jne unexpected_instruction
202 mov ebp,[addressing_space]
203 test byte [ds:ebp+0Ah],1
204 jnz unexpected_instruction
205 cmp [output_format],0
206 jne unexpected_instruction
207 lods byte [esi]
208 cmp al,1Ch
209 je format_prefix
210 cmp al,18h
211 jne invalid_argument
212 lods byte [esi]
213 select_format:
214 mov dl,al
215 shr al,4
216 mov [output_format],al
217 and edx,0Fh
218 or [format_flags],edx
219 cmp al,2
220 je format_mz
221 cmp al,3
222 je format_pe
223 cmp al,4
224 je format_coff
225 cmp al,5
226 je format_elf
227 format_defined:
228 cmp byte [esi],86h
229 jne instruction_assembled
230 cmp word [esi+1],'('
231 jne invalid_argument
232 mov eax,[esi+3]
233 add esi,3+4
234 mov [file_extension],esi
235 lea esi,[esi+eax+1]
236 jmp instruction_assembled
237 format_prefix:
238 lods byte [esi]
239 mov ah,al
240 lods byte [esi]
241 cmp al,18h
242 jne invalid_argument
243 lods byte [esi]
244 mov edx,eax
245 shr dl,4
246 shr dh,4
247 cmp dl,dh
248 jne invalid_argument
249 or al,ah
250 jmp select_format
251 entry_directive:
252 bts [format_flags],10h
253 jc setting_already_specified
254 mov al,[output_format]
255 cmp al,2
256 je mz_entry
257 cmp al,3
258 je pe_entry
259 cmp al,5
260 jne illegal_instruction
261 bt [format_flags],0
262 jc elf_entry
263 jmp illegal_instruction
264 stack_directive:
265 bts [format_flags],11h
266 jc setting_already_specified
267 mov al,[output_format]
268 cmp al,2
269 je mz_stack
270 cmp al,3
271 je pe_stack
272 jmp illegal_instruction
273 heap_directive:
274 bts [format_flags],12h
275 jc setting_already_specified
276 mov al,[output_format]
277 cmp al,2
278 je mz_heap
279 cmp al,3
280 je pe_heap
281 jmp illegal_instruction
282 segment_directive:
283 mov al,[output_format]
284 cmp al,2
285 je mz_segment
286 cmp al,5
287 je elf_segment
288 jmp illegal_instruction
289 section_directive:
290 mov al,[output_format]
291 cmp al,3
292 je pe_section
293 cmp al,4
294 je coff_section
295 cmp al,5
296 je elf_section
297 jmp illegal_instruction
298 public_directive:
299 mov al,[output_format]
300 cmp al,4
301 je public_allowed
302 cmp al,5
303 jne illegal_instruction
304 bt [format_flags],0
305 jc illegal_instruction
306 public_allowed:
307 mov [base_code],0C0h
308 lods byte [esi]
309 cmp al,2
310 je public_label
311 cmp al,1Dh
312 jne invalid_argument
313 lods byte [esi]
314 and al,7
315 add [base_code],al
316 lods byte [esi]
317 cmp al,2
318 jne invalid_argument
319 public_label:
320 lods dword [esi]
321 cmp eax,0Fh
322 jb invalid_use_of_symbol
323 je reserved_word_used_as_symbol
324 inc esi
325 mov dx,[current_pass]
326 mov [eax+18],dx
327 or byte [eax+8],8
328 cmp [symbols_file],0
329 je public_reference_ok
330 cmp [next_pass_needed],0
331 jne public_reference_ok
332 mov ebx,eax
333 call store_label_reference
334 mov eax,ebx
335 public_reference_ok:
336 mov ebx,[free_additional_memory]
337 lea edx,[ebx+10h]
338 cmp edx,[structures_buffer]
339 jae out_of_memory
340 mov [free_additional_memory],edx
341 mov [ebx+8],eax
342 mov eax,[current_line]
343 mov [ebx+0Ch],eax
344 lods byte [esi]
345 cmp al,86h
346 jne invalid_argument
347 lods word [esi]
348 cmp ax,'('
349 jne invalid_argument
350 mov [ebx+4],esi
351 lods dword [esi]
352 lea esi,[esi+eax+1]
353 mov al,[base_code]
354 mov [ebx],al
355 jmp instruction_assembled
356 extrn_directive:
357 mov al,[output_format]
358 cmp al,4
359 je extrn_allowed
360 cmp al,5
361 jne illegal_instruction
362 bt [format_flags],0
363 jc illegal_instruction
364 extrn_allowed:
365 lods word [esi]
366 cmp ax,'('
367 jne invalid_argument
368 mov ebx,esi
369 lods dword [esi]
370 lea esi,[esi+eax+1]
371 mov edx,[free_additional_memory]
372 lea eax,[edx+0Ch]
373 cmp eax,[structures_buffer]
374 jae out_of_memory
375 mov [free_additional_memory],eax
376 mov byte [edx],80h
377 mov [edx+4],ebx
378 lods byte [esi]
379 cmp al,86h
380 jne invalid_argument
381 lods byte [esi]
382 cmp al,2
383 jne invalid_argument
384 lods dword [esi]
385 cmp eax,0Fh
386 jb invalid_use_of_symbol
387 je reserved_word_used_as_symbol
388 inc esi
389 mov ebx,eax
390 xor ah,ah
391 lods byte [esi]
392 cmp al,':'
393 je get_extrn_size
394 dec esi
395 cmp al,11h
396 jne extrn_size_ok
397 get_extrn_size:
398 lods word [esi]
399 cmp al,11h
400 jne invalid_argument
401 extrn_size_ok:
402 mov [address_symbol],edx
403 mov [label_size],ah
404 movzx ecx,ah
405 mov [edx+8],ecx
406 xor eax,eax
407 xor edx,edx
408 xor ebp,ebp
409 mov [address_sign],0
410 mov ch,2
411 test [format_flags],8
412 jz make_free_label
413 mov ch,4
414 jmp make_free_label
415 mark_relocation:
416 cmp [value_type],0
417 je relocation_ok
418 mov ebp,[addressing_space]
419 test byte [ds:ebp+0Ah],1
420 jnz relocation_ok
421 cmp [output_format],2
422 je mark_mz_relocation
423 cmp [output_format],3
424 je mark_pe_relocation
425 cmp [output_format],4
426 je mark_coff_relocation
427 cmp [output_format],5
428 je mark_elf_relocation
429 relocation_ok:
430 ret
431 close_pass:
432 mov al,[output_format]
433 cmp al,3
434 je close_pe
435 cmp al,4
436 je close_coff
437 cmp al,5
438 je close_elf
439 ret
440
441 format_mz:
442 mov edx,[additional_memory]
443 push edi
444 mov edi,edx
445 mov ecx,1Ch shr 2
446 xor eax,eax
447 rep stos dword [edi]
448 mov [free_additional_memory],edi
449 pop edi
450 mov word [edx+0Ch],0FFFFh
451 mov word [edx+10h],1000h
452 mov [code_type],16
453 jmp format_defined
454 mark_mz_relocation:
455 push eax ebx
456 inc word [number_of_relocations]
457 jz format_limitations_exceeded
458 mov ebx,[free_additional_memory]
459 mov eax,edi
460 sub eax,[code_start]
461 mov [ebx],ax
462 shr eax,16
463 shl ax,12
464 mov [ebx+2],ax
465 cmp word [ebx],0FFFFh
466 jne mz_relocation_ok
467 inc word [ebx+2]
468 sub word [ebx],10h
469 mz_relocation_ok:
470 add ebx,4
471 cmp ebx,[structures_buffer]
472 jae out_of_memory
473 mov [free_additional_memory],ebx
474 pop ebx eax
475 ret
476 mz_segment:
477 lods byte [esi]
478 cmp al,2
479 jne invalid_argument
480 lods dword [esi]
481 cmp eax,0Fh
482 jb invalid_use_of_symbol
483 je reserved_word_used_as_symbol
484 inc esi
485 mov ebx,eax
486 mov eax,edi
487 sub eax,[code_start]
488 mov ecx,0Fh
489 add eax,0Fh
490 and eax,1111b
491 sub ecx,eax
492 mov edx,edi
493 xor eax,eax
494 rep stos byte [edi]
495 mov eax,edx
496 call undefined_data
497 push ebx
498 call create_addressing_space
499 pop ebx
500 mov eax,edi
501 sub eax,[code_start]
502 shr eax,4
503 cmp eax,10000h
504 jae value_out_of_range
505 mov edx,eax
506 mov al,16
507 cmp byte [esi],13h
508 jne segment_type_ok
509 inc esi
510 lods byte [esi]
511 segment_type_ok:
512 mov [code_type],al
513 mov eax,edx
514 mov ch,1
515 mov [address_sign],0
516 xor edx,edx
517 xor ebp,ebp
518 mov [label_size],0
519 mov [address_symbol],edx
520 jmp make_free_label
521 mz_entry:
522 lods byte [esi]
523 cmp al,'('
524 jne invalid_argument
525 call get_word_value
526 cmp [value_type],1
527 je initial_cs_ok
528 call recoverable_invalid_address
529 initial_cs_ok:
530 mov edx,[additional_memory]
531 mov [edx+16h],ax
532 lods byte [esi]
533 cmp al,':'
534 jne invalid_argument
535 lods byte [esi]
536 cmp al,'('
537 jne invalid_argument
538 ja invalid_address
539 call get_word_value
540 cmp [value_type],0
541 jne invalid_use_of_symbol
542 mov edx,[additional_memory]
543 mov [edx+14h],ax
544 jmp instruction_assembled
545 recoverable_invalid_address:
546 cmp [error_line],0
547 jne ignore_invalid_address
548 push [current_line]
549 pop [error_line]
550 mov [error],invalid_address
551 ignore_invalid_address:
552 ret
553 mz_stack:
554 lods byte [esi]
555 cmp al,'('
556 jne invalid_argument
557 call get_word_value
558 cmp byte [esi],':'
559 je stack_pointer
560 cmp ax,10h
561 jb invalid_value
562 cmp [value_type],0
563 jne invalid_use_of_symbol
564 mov edx,[additional_memory]
565 mov [edx+10h],ax
566 jmp instruction_assembled
567 stack_pointer:
568 cmp [value_type],1
569 je initial_ss_ok
570 call recoverable_invalid_address
571 initial_ss_ok:
572 mov edx,[additional_memory]
573 mov [edx+0Eh],ax
574 lods byte [esi]
575 cmp al,':'
576 jne invalid_argument
577 lods byte [esi]
578 cmp al,'('
579 jne invalid_argument
580 call get_word_value
581 cmp [value_type],0
582 jne invalid_use_of_symbol
583 mov edx,[additional_memory]
584 mov [edx+10h],ax
585 bts [format_flags],4
586 jmp instruction_assembled
587 mz_heap:
588 cmp [output_format],2
589 jne illegal_instruction
590 lods byte [esi]
591 call get_size_operator
592 cmp ah,1
593 je invalid_value
594 cmp ah,2
595 ja invalid_value
596 cmp al,'('
597 jne invalid_argument
598 call get_word_value
599 cmp [value_type],0
600 jne invalid_use_of_symbol
601 mov edx,[additional_memory]
602 mov [edx+0Ch],ax
603 jmp instruction_assembled
604 write_mz_header:
605 mov edx,[additional_memory]
606 bt [format_flags],4
607 jc mz_stack_ok
608 mov eax,[real_code_size]
609 dec eax
610 shr eax,4
611 inc eax
612 mov [edx+0Eh],ax
613 shl eax,4
614 movzx ecx,word [edx+10h]
615 add eax,ecx
616 mov [real_code_size],eax
617 mz_stack_ok:
618 mov edi,[free_additional_memory]
619 mov eax,[number_of_relocations]
620 shl eax,2
621 add eax,1Ch
622 sub edi,eax
623 xchg edi,[free_additional_memory]
624 mov ecx,0Fh
625 add eax,0Fh
626 and eax,1111b
627 sub ecx,eax
628 xor al,al
629 rep stos byte [edi]
630 sub edi,[free_additional_memory]
631 mov ecx,edi
632 shr edi,4
633 mov word [edx],'MZ' ; signature
634 mov [edx+8],di ; header size in paragraphs
635 mov eax,[number_of_relocations]
636 mov [edx+6],ax ; number of relocation entries
637 mov eax,[code_size]
638 add eax,ecx
639 mov esi,eax
640 shr esi,9
641 and eax,1FFh
642 inc si
643 or ax,ax
644 jnz mz_size_ok
645 dec si
646 mz_size_ok:
647 mov [edx+2],ax ; number of bytes in last page
648 mov [edx+4],si ; number of pages
649 mov eax,[real_code_size]
650 dec eax
651 shr eax,4
652 inc eax
653 mov esi,[code_size]
654 dec esi
655 shr esi,4
656 inc esi
657 sub eax,esi
658 mov [edx+0Ah],ax ; minimum memory in addition to code
659 add [edx+0Ch],ax ; maximum memory in addition to code
660 salc
661 mov ah,al
662 or [edx+0Ch],ax
663 mov word [edx+18h],1Ch ; offset of relocation table
664 add [written_size],ecx
665 call write
666 jc write_failed
667 ret
668
669 make_stub:
670 mov [stub_file],edx
671 or edx,edx
672 jnz stub_from_file
673 push esi
674 mov edx,edi
675 xor eax,eax
676 mov ecx,20h
677 rep stos dword [edi]
678 mov eax,40h+default_stub_end-default_stub
679 mov cx,100h+default_stub_end-default_stub
680 mov word [edx],'MZ'
681 mov byte [edx+4],1
682 mov word [edx+2],ax
683 mov byte [edx+8],4
684 mov byte [edx+0Ah],10h
685 mov word [edx+0Ch],0FFFFh
686 mov word [edx+10h],cx
687 mov word [edx+3Ch],ax
688 mov byte [edx+18h],40h
689 lea edi,[edx+40h]
690 mov esi,default_stub
691 mov ecx,default_stub_end-default_stub
692 rep movs byte [edi],[esi]
693 pop esi
694 jmp stub_ok
695 default_stub:
696 use16
697 push cs
698 pop ds
699 mov dx,stub_message-default_stub
700 mov ah,9
701 int 21h
702 mov ax,4C01h
703 int 21h
704 stub_message db 'This program cannot be run in DOS mode.',0Dh,0Ah,24h
705 rq 1
706 default_stub_end:
707 use32
708 stub_from_file:
709 push esi
710 mov esi,edx
711 call open_binary_file
712 mov edx,edi
713 mov ecx,1Ch
714 mov esi,edx
715 call read
716 jc binary_stub
717 cmp word [esi],'MZ'
718 jne binary_stub
719 add edi,1Ch
720 movzx ecx,word [esi+6]
721 add ecx,11b
722 and ecx,not 11b
723 add ecx,(40h-1Ch) shr 2
724 lea eax,[edi+ecx*4]
725 cmp edi,[tagged_blocks]
726 jae out_of_memory
727 xor eax,eax
728 rep stos dword [edi]
729 mov edx,40h
730 xchg dx,[esi+18h]
731 xor al,al
732 call lseek
733 movzx ecx,word [esi+6]
734 shl ecx,2
735 lea edx,[esi+40h]
736 call read
737 mov edx,edi
738 sub edx,esi
739 shr edx,4
740 xchg dx,[esi+8]
741 shl edx,4
742 xor al,al
743 call lseek
744 movzx ecx,word [esi+4]
745 dec ecx
746 shl ecx,9
747 movzx edx,word [esi+2]
748 test edx,edx
749 jnz stub_header_size_ok
750 mov dx,200h
751 stub_header_size_ok:
752 add ecx,edx
753 mov edx,edi
754 sub ecx,eax
755 je read_stub_code
756 jb stub_code_ok
757 push ecx
758 dec ecx
759 shr ecx,3
760 inc ecx
761 shl ecx,1
762 lea eax,[edi+ecx*4]
763 cmp eax,[tagged_blocks]
764 jae out_of_memory
765 xor eax,eax
766 rep stos dword [edi]
767 pop ecx
768 read_stub_code:
769 call read
770 stub_code_ok:
771 call close
772 mov edx,edi
773 sub edx,esi
774 mov ax,dx
775 and ax,1FFh
776 mov [esi+2],ax
777 dec edx
778 shr edx,9
779 inc edx
780 mov [esi+4],dx
781 mov eax,edi
782 sub eax,esi
783 mov [esi+3Ch],eax
784 pop esi
785 stub_ok:
786 ret
787 binary_stub:
788 mov esi,edi
789 mov ecx,40h shr 2
790 xor eax,eax
791 rep stos dword [edi]
792 mov al,2
793 xor edx,edx
794 call lseek
795 push eax
796 xor al,al
797 xor edx,edx
798 call lseek
799 mov ecx,[esp]
800 add ecx,40h+111b
801 and ecx,not 111b
802 mov ax,cx
803 and ax,1FFh
804 mov [esi+2],ax
805 lea eax,[ecx+1FFh]
806 shr eax,9
807 mov [esi+4],ax
808 mov [esi+3Ch],ecx
809 sub ecx,40h
810 mov eax,10000h
811 sub eax,ecx
812 jbe binary_heap_ok
813 shr eax,4
814 mov [esi+0Ah],ax
815 binary_heap_ok:
816 mov word [esi],'MZ'
817 mov byte [esi+8],4
818 mov ax,0FFFFh
819 mov [esi+0Ch],ax
820 dec ax
821 mov [esi+10h],ax
822 sub ax,0Eh
823 mov [esi+0Eh],ax
824 mov [esi+16h],ax
825 mov word [esi+14h],100h
826 mov byte [esi+18h],40h
827 mov eax,[tagged_blocks]
828 sub eax,ecx
829 cmp edi,eax
830 jae out_of_memory
831 mov edx,edi
832 shr ecx,2
833 xor eax,eax
834 rep stos dword [edi]
835 pop ecx
836 call read
837 call close
838 pop esi
839 ret
840
841 format_pe:
842 xor edx,edx
843 mov [machine],14Ch
844 mov [subsystem],3
845 mov [subsystem_version],3 + 10 shl 16
846 mov [image_base],400000h
847 and [image_base_high],0
848 test [format_flags],8
849 jz pe_settings
850 mov [machine],8664h
851 mov [subsystem_version],5 + 0 shl 16
852 pe_settings:
853 cmp byte [esi],84h
854 je get_stub_name
855 cmp byte [esi],80h
856 je get_pe_base
857 cmp byte [esi],1Bh
858 jne pe_settings_ok
859 lods byte [esi]
860 lods byte [esi]
861 test al,80h+40h
862 jz subsystem_setting
863 cmp al,80h
864 je dll_flag
865 cmp al,81h
866 je wdm_flag
867 cmp al,82h
868 je large_flag
869 cmp al,83h
870 je nx_flag
871 jmp pe_settings
872 dll_flag:
873 bts [format_flags],8
874 jc setting_already_specified
875 jmp pe_settings
876 wdm_flag:
877 bts [format_flags],9
878 jc setting_already_specified
879 jmp pe_settings
880 large_flag:
881 bts [format_flags],11
882 jc setting_already_specified
883 test [format_flags],8
884 jnz invalid_argument
885 jmp pe_settings
886 nx_flag:
887 bts [format_flags],12
888 jc setting_already_specified
889 jmp pe_settings
890 subsystem_setting:
891 bts [format_flags],7
892 jc setting_already_specified
893 and ax,3Fh
894 mov [subsystem],ax
895 cmp ax,10
896 jb subsystem_type_ok
897 or [format_flags],4
898 subsystem_type_ok:
899 cmp byte [esi],'('
900 jne pe_settings
901 inc esi
902 cmp byte [esi],'.'
903 jne invalid_value
904 inc esi
905 push edx
906 cmp byte [esi+11],0
907 jne invalid_value
908 cmp byte [esi+10],2
909 ja invalid_value
910 mov dx,[esi+8]
911 cmp dx,8000h
912 je zero_version
913 mov eax,[esi+4]
914 cmp dx,7
915 jg invalid_value
916 mov cx,7
917 sub cx,dx
918 mov eax,[esi+4]
919 shr eax,cl
920 mov ebx,eax
921 shr ebx,24
922 cmp bl,100
923 jae invalid_value
924 and eax,0FFFFFFh
925 mov ecx,100
926 mul ecx
927 shrd eax,edx,24
928 jnc version_value_ok
929 inc eax
930 version_value_ok:
931 shl eax,16
932 mov ax,bx
933 jmp subsystem_version_ok
934 zero_version:
935 xor eax,eax
936 subsystem_version_ok:
937 pop edx
938 add esi,13
939 mov [subsystem_version],eax
940 jmp pe_settings
941 get_pe_base:
942 bts [format_flags],10
943 jc setting_already_specified
944 lods word [esi]
945 cmp ah,'('
946 jne invalid_argument
947 cmp byte [esi],'.'
948 je invalid_value
949 push edx edi
950 add edi,[stub_size]
951 test [format_flags],4
952 jnz get_peplus_base
953 call get_dword_value
954 mov [image_base],eax
955 jmp pe_base_ok
956 get_peplus_base:
957 call get_qword_value
958 mov [image_base],eax
959 mov [image_base_high],edx
960 pe_base_ok:
961 pop edi edx
962 cmp [value_type],0
963 jne invalid_use_of_symbol
964 cmp byte [esi],84h
965 jne pe_settings_ok
966 get_stub_name:
967 lods byte [esi]
968 lods word [esi]
969 cmp ax,'('
970 jne invalid_argument
971 lods dword [esi]
972 mov edx,esi
973 add esi,eax
974 inc esi
975 pe_settings_ok:
976 mov ebp,[stub_size]
977 or ebp,ebp
978 jz make_pe_stub
979 cmp edx,[stub_file]
980 je pe_stub_ok
981 sub edi,[stub_size]
982 mov [code_start],edi
983 make_pe_stub:
984 call make_stub
985 mov eax,edi
986 sub eax,[code_start]
987 mov [stub_size],eax
988 mov [code_start],edi
989 mov ebp,eax
990 pe_stub_ok:
991 mov edx,edi
992 mov ecx,18h+0E0h
993 test [format_flags],4
994 jz zero_pe_header
995 add ecx,10h
996 zero_pe_header:
997 add ebp,ecx
998 shr ecx,2
999 xor eax,eax
1000 rep stos dword [edi]
1001 mov word [edx],'PE' ; signature
1002 mov ax,[machine]
1003 mov word [edx+4],ax
1004 mov byte [edx+38h+1],10h ; section alignment
1005 mov byte [edx+3Ch+1],2 ; file alignment
1006 mov byte [edx+40h],1 ; OS version
1007 mov eax,[subsystem_version]
1008 mov [edx+48h],eax
1009 mov ax,[subsystem]
1010 mov [edx+5Ch],ax
1011 cmp ax,1
1012 jne pe_alignment_ok
1013 mov eax,20h
1014 mov dword [edx+38h],eax
1015 mov dword [edx+3Ch],eax
1016 pe_alignment_ok:
1017 mov word [edx+1Ah],VERSION_MAJOR + VERSION_MINOR shl 8
1018 test [format_flags],4
1019 jnz init_peplus_specific
1020 mov byte [edx+14h],0E0h ; size of optional header
1021 mov dword [edx+16h],10B010Fh; flags and magic value
1022 mov eax,[image_base]
1023 mov [edx+34h],eax
1024 mov byte [edx+60h+1],10h ; stack reserve
1025 mov byte [edx+64h+1],10h ; stack commit
1026 mov byte [edx+68h+2],1 ; heap reserve
1027 mov byte [edx+74h],16 ; number of directories
1028 jmp pe_header_ok
1029 init_peplus_specific:
1030 mov byte [edx+14h],0F0h ; size of optional header
1031 mov dword [edx+16h],20B002Fh; flags and magic value
1032 mov eax,[image_base]
1033 mov [edx+30h],eax
1034 mov eax,[image_base_high]
1035 mov [edx+34h],eax
1036 mov byte [edx+60h+1],10h ; stack reserve
1037 mov byte [edx+68h+1],10h ; stack commit
1038 mov byte [edx+70h+2],1 ; heap reserve
1039 mov byte [edx+84h],16 ; number of directories
1040 pe_header_ok:
1041 bsf ecx,[edx+3Ch]
1042 imul ebx,[number_of_sections],28h
1043 or ebx,ebx
1044 jnz reserve_space_for_section_headers
1045 mov ebx,28h
1046 reserve_space_for_section_headers:
1047 add ebx,ebp
1048 dec ebx
1049 shr ebx,cl
1050 inc ebx
1051 shl ebx,cl
1052 sub ebx,ebp
1053 mov ecx,ebx
1054 mov eax,[tagged_blocks]
1055 sub eax,ecx
1056 cmp edi,eax
1057 jae out_of_memory
1058 shr ecx,2
1059 xor eax,eax
1060 rep stos dword [edi]
1061 mov eax,edi
1062 sub eax,[code_start]
1063 add eax,[stub_size]
1064 mov [edx+54h],eax ; size of headers
1065 mov ecx,[edx+38h]
1066 dec ecx
1067 add eax,ecx
1068 not ecx
1069 and eax,ecx
1070 bt [format_flags],8
1071 jc pe_entry_init_ok
1072 mov [edx+28h],eax ; entry point rva
1073 pe_entry_init_ok:
1074 and [number_of_sections],0
1075 movzx ebx,word [edx+14h]
1076 lea ebx,[edx+18h+ebx]
1077 mov [current_section],ebx
1078 mov dword [ebx],'.fla'
1079 mov dword [ebx+4],'t'
1080 mov [ebx+14h],edi
1081 mov [ebx+0Ch],eax
1082 mov dword [ebx+24h],0E0000060h
1083 xor ecx,ecx
1084 xor bl,bl
1085 not eax
1086 not ecx
1087 not bl
1088 add eax,1
1089 adc ecx,0
1090 adc bl,0
1091 add eax,edi
1092 adc ecx,0
1093 adc bl,0
1094 test [format_flags],4
1095 jnz peplus_org
1096 sub eax,[edx+34h]
1097 sbb ecx,0
1098 sbb bl,0
1099 jmp pe_org_ok
1100 peplus_org:
1101 sub eax,[edx+30h]
1102 sbb ecx,[edx+34h]
1103 sbb bl,0
1104 pe_org_ok:
1105 test [format_flags],8
1106 jnz pe64_code
1107 mov bh,2
1108 mov [code_type],32
1109 jmp pe_code_type_ok
1110 pe64_code:
1111 mov bh,4
1112 mov [code_type],64
1113 pe_code_type_ok:
1114 bt [resolver_flags],0
1115 jc pe_labels_type_ok
1116 xor bh,bh
1117 pe_labels_type_ok:
1118 push eax ebx
1119 call init_addressing_space
1120 mov ebp,ebx
1121 pop ebx eax
1122 mov [ds:ebp],eax
1123 mov [ds:ebp+4],ecx
1124 mov [ds:ebp+8],bx
1125 mov [ds:ebp+18h],edi
1126 bt [format_flags],8
1127 jnc dll_flag_ok
1128 or byte [edx+16h+1],20h
1129 dll_flag_ok:
1130 bt [format_flags],9
1131 jnc wdm_flag_ok
1132 or byte [edx+5Eh+1],20h
1133 wdm_flag_ok:
1134 bt [format_flags],11
1135 jnc large_flag_ok
1136 or byte [edx+16h],20h
1137 large_flag_ok:
1138 bt [format_flags],12
1139 jnc nx_ok
1140 or byte [edx+5Eh+1],1
1141 nx_ok:
1142 jmp format_defined
1143 pe_section:
1144 call close_pe_section
1145 push eax ebx
1146 call create_addressing_space
1147 mov ebp,ebx
1148 pop ebx eax
1149 bts [format_flags],5
1150 lea ecx,[ebx+28h]
1151 add edx,[edx+54h]
1152 sub edx,[stub_size]
1153 cmp ecx,edx
1154 jbe new_section
1155 lea ebx,[edx-28h]
1156 or [next_pass_needed],-1
1157 push edi
1158 mov edi,ebx
1159 mov ecx,28h shr 4
1160 xor eax,eax
1161 rep stos dword [edi]
1162 pop edi
1163 new_section:
1164 mov [ebx+0Ch],eax
1165 lods word [esi]
1166 cmp ax,'('
1167 jne invalid_argument
1168 lea edx,[esi+4]
1169 mov ecx,[esi]
1170 lea esi,[esi+4+ecx+1]
1171 cmp ecx,8
1172 ja name_too_long
1173 xor eax,eax
1174 mov [ebx],eax
1175 mov [ebx+4],eax
1176 push esi edi
1177 mov edi,ebx
1178 mov esi,edx
1179 rep movs byte [edi],[esi]
1180 pop edi esi
1181 and dword [ebx+24h],0
1182 mov [ebx+14h],edi
1183 mov edx,[code_start]
1184 mov eax,edi
1185 xor ecx,ecx
1186 sub eax,[ebx+0Ch]
1187 sbb ecx,0
1188 sbb byte [ds:ebp+8],0
1189 mov byte [ds:ebp+9],2
1190 mov [code_type],32
1191 test [format_flags],8
1192 jz pe_section_code_type_ok
1193 mov byte [ds:ebp+9],4
1194 mov [code_type],64
1195 pe_section_code_type_ok:
1196 test [format_flags],4
1197 jnz peplus_section_org
1198 sub eax,[edx+34h]
1199 sbb ecx,0
1200 sbb byte [ds:ebp+8],0
1201 bt [resolver_flags],0
1202 jc pe_section_org_ok
1203 mov byte [ds:ebp+9],0
1204 jmp pe_section_org_ok
1205 peplus_section_org:
1206 sub eax,[edx+30h]
1207 sbb ecx,[edx+34h]
1208 sbb byte [ds:ebp+8],0
1209 bt [resolver_flags],0
1210 jc pe_section_org_ok
1211 mov byte [ds:ebp+9],0
1212 pe_section_org_ok:
1213 mov [ds:ebp],eax
1214 mov [ds:ebp+4],ecx
1215 mov [ds:ebp+18h],edi
1216 get_section_flags:
1217 lods byte [esi]
1218 cmp al,1Ah
1219 je set_directory
1220 cmp al,19h
1221 je section_flag
1222 dec esi
1223 jmp instruction_assembled
1224 set_directory:
1225 movzx eax,byte [esi]
1226 inc esi
1227 mov ecx,ebx
1228 test [format_flags],4
1229 jnz peplus_directory
1230 xchg ecx,[edx+78h+eax*8]
1231 mov dword [edx+78h+eax*8+4],-1
1232 jmp pe_directory_set
1233 peplus_directory:
1234 xchg ecx,[edx+88h+eax*8]
1235 mov dword [edx+88h+eax*8+4],-1
1236 pe_directory_set:
1237 or ecx,ecx
1238 jnz data_already_defined
1239 push ebx edx
1240 call generate_pe_data
1241 pop edx ebx
1242 jmp get_section_flags
1243 section_flag:
1244 lods byte [esi]
1245 cmp al,9
1246 je invalid_argument
1247 cmp al,11
1248 je invalid_argument
1249 mov cl,al
1250 mov eax,1
1251 shl eax,cl
1252 test dword [ebx+24h],eax
1253 jnz setting_already_specified
1254 or dword [ebx+24h],eax
1255 jmp get_section_flags
1256 close_pe_section:
1257 mov ebx,[current_section]
1258 mov edx,[code_start]
1259 mov eax,edi
1260 sub eax,[ebx+14h]
1261 jnz finish_section
1262 bt [format_flags],5
1263 jc finish_section
1264 mov eax,[ebx+0Ch]
1265 ret
1266 finish_section:
1267 mov [ebx+8],eax
1268 cmp edi,[undefined_data_end]
1269 jne align_section
1270 cmp dword [edx+38h],1000h
1271 jb align_section
1272 mov edi,[undefined_data_start]
1273 align_section:
1274 and [undefined_data_end],0
1275 mov ebp,edi
1276 sub ebp,[ebx+14h]
1277 mov ecx,[edx+3Ch]
1278 dec ecx
1279 lea eax,[ebp+ecx]
1280 not ecx
1281 and eax,ecx
1282 mov [ebx+10h],eax
1283 sub eax,ebp
1284 mov ecx,eax
1285 xor al,al
1286 rep stos byte [edi]
1287 mov eax,[code_start]
1288 sub eax,[stub_size]
1289 sub [ebx+14h],eax
1290 mov ecx,[ebx+10h]
1291 test byte [ebx+24h],20h
1292 jz pe_code_sum_ok
1293 add [edx+1Ch],ecx
1294 cmp dword [edx+2Ch],0
1295 jne pe_code_sum_ok
1296 mov eax,[ebx+0Ch]
1297 mov [edx+2Ch],eax
1298 pe_code_sum_ok:
1299 test byte [ebx+24h],40h
1300 jz pe_data_sum_ok
1301 add [edx+20h],ecx
1302 test [format_flags],4
1303 jnz pe_data_sum_ok
1304 cmp dword [edx+30h],0
1305 jne pe_data_sum_ok
1306 mov eax,[ebx+0Ch]
1307 mov [edx+30h],eax
1308 pe_data_sum_ok:
1309 mov eax,[ebx+8]
1310 or eax,eax
1311 jz udata_ok
1312 cmp dword [ebx+10h],0
1313 jne udata_ok
1314 or byte [ebx+24h],80h
1315 add [edx+24h],ecx
1316 udata_ok:
1317 mov ecx,[edx+38h]
1318 dec ecx
1319 add eax,ecx
1320 not ecx
1321 and eax,ecx
1322 add eax,[ebx+0Ch]
1323 add ebx,28h
1324 mov [current_section],ebx
1325 inc word [number_of_sections]
1326 jz format_limitations_exceeded
1327 ret
1328 data_directive:
1329 cmp [output_format],3
1330 jne illegal_instruction
1331 lods byte [esi]
1332 cmp al,1Ah
1333 je predefined_data_type
1334 cmp al,'('
1335 jne invalid_argument
1336 call get_byte_value
1337 cmp al,16
1338 jb data_type_ok
1339 jmp invalid_value
1340 predefined_data_type:
1341 movzx eax,byte [esi]
1342 inc esi
1343 data_type_ok:
1344 mov ebx,[current_section]
1345 mov ecx,edi
1346 sub ecx,[ebx+14h]
1347 add ecx,[ebx+0Ch]
1348 mov edx,[code_start]
1349 test [format_flags],4
1350 jnz peplus_data
1351 xchg ecx,[edx+78h+eax*8]
1352 jmp init_pe_data
1353 peplus_data:
1354 xchg ecx,[edx+88h+eax*8]
1355 init_pe_data:
1356 or ecx,ecx
1357 jnz data_already_defined
1358 call allocate_structure_data
1359 mov word [ebx],data_directive-instruction_handler
1360 mov [ebx+2],al
1361 mov edx,[current_line]
1362 mov [ebx+4],edx
1363 call generate_pe_data
1364 jmp instruction_assembled
1365 end_data:
1366 cmp [output_format],3
1367 jne illegal_instruction
1368 call find_structure_data
1369 jc unexpected_instruction
1370 movzx eax,byte [ebx+2]
1371 mov edx,[current_section]
1372 mov ecx,edi
1373 sub ecx,[edx+14h]
1374 add ecx,[edx+0Ch]
1375 mov edx,[code_start]
1376 test [format_flags],4
1377 jnz end_peplus_data
1378 sub ecx,[edx+78h+eax*8]
1379 mov [edx+78h+eax*8+4],ecx
1380 jmp remove_structure_data
1381 end_peplus_data:
1382 sub ecx,[edx+88h+eax*8]
1383 mov [edx+88h+eax*8+4],ecx
1384 jmp remove_structure_data
1385 pe_entry:
1386 lods byte [esi]
1387 cmp al,'('
1388 jne invalid_argument
1389 cmp byte [esi],'.'
1390 je invalid_value
1391 test [format_flags],8
1392 jnz pe64_entry
1393 call get_dword_value
1394 mov bl,2
1395 bt [resolver_flags],0
1396 jc check_pe_entry_label_type
1397 xor bl,bl
1398 check_pe_entry_label_type:
1399 cmp [value_type],bl
1400 je pe_entry_ok
1401 call recoverable_invalid_address
1402 pe_entry_ok:
1403 cdq
1404 test [format_flags],4
1405 jnz pe64_entry_type_ok
1406 mov edx,[code_start]
1407 sub eax,[edx+34h]
1408 mov [edx+28h],eax
1409 jmp instruction_assembled
1410 pe64_entry:
1411 call get_qword_value
1412 mov bl,4
1413 bt [resolver_flags],0
1414 jc check_pe64_entry_label_type
1415 xor bl,bl
1416 check_pe64_entry_label_type:
1417 cmp [value_type],bl
1418 je pe64_entry_type_ok
1419 call recoverable_invalid_address
1420 pe64_entry_type_ok:
1421 mov ecx,[code_start]
1422 sub eax,[ecx+30h]
1423 sbb edx,[ecx+34h]
1424 jz pe64_entry_range_ok
1425 call recoverable_overflow
1426 pe64_entry_range_ok:
1427 mov [ecx+28h],eax
1428 jmp instruction_assembled
1429 pe_stack:
1430 lods byte [esi]
1431 cmp al,'('
1432 jne invalid_argument
1433 cmp byte [esi],'.'
1434 je invalid_value
1435 test [format_flags],4
1436 jnz peplus_stack
1437 call get_count_value
1438 mov edx,[code_start]
1439 mov [edx+60h],eax
1440 cmp byte [esi],','
1441 jne default_stack_commit
1442 lods byte [esi]
1443 lods byte [esi]
1444 cmp al,'('
1445 jne invalid_argument
1446 cmp byte [esi],'.'
1447 je invalid_value
1448 call get_count_value
1449 mov edx,[code_start]
1450 mov [edx+64h],eax
1451 cmp eax,[edx+60h]
1452 ja value_out_of_range
1453 jmp instruction_assembled
1454 default_stack_commit:
1455 mov dword [edx+64h],1000h
1456 mov eax,[edx+60h]
1457 cmp eax,1000h
1458 ja instruction_assembled
1459 mov dword [edx+64h],eax
1460 jmp instruction_assembled
1461 peplus_stack:
1462 call get_qword_value
1463 cmp [value_type],0
1464 jne invalid_use_of_symbol
1465 mov ecx,[code_start]
1466 mov [ecx+60h],eax
1467 mov [ecx+64h],edx
1468 cmp byte [esi],','
1469 jne default_peplus_stack_commit
1470 lods byte [esi]
1471 lods byte [esi]
1472 cmp al,'('
1473 jne invalid_argument
1474 cmp byte [esi],'.'
1475 je invalid_value
1476 call get_qword_value
1477 cmp [value_type],0
1478 jne invalid_use_of_symbol
1479 mov ecx,[code_start]
1480 mov [ecx+68h],eax
1481 mov [ecx+6Ch],edx
1482 cmp edx,[ecx+64h]
1483 ja value_out_of_range
1484 jb instruction_assembled
1485 cmp eax,[ecx+60h]
1486 ja value_out_of_range
1487 jmp instruction_assembled
1488 default_peplus_stack_commit:
1489 mov dword [ecx+68h],1000h
1490 cmp dword [ecx+64h],0
1491 jne instruction_assembled
1492 mov eax,[ecx+60h]
1493 cmp eax,1000h
1494 ja instruction_assembled
1495 mov dword [ecx+68h],eax
1496 jmp instruction_assembled
1497 pe_heap:
1498 lods byte [esi]
1499 cmp al,'('
1500 jne invalid_argument
1501 cmp byte [esi],'.'
1502 je invalid_value
1503 test [format_flags],4
1504 jnz peplus_heap
1505 call get_count_value
1506 mov edx,[code_start]
1507 mov [edx+68h],eax
1508 cmp byte [esi],','
1509 jne instruction_assembled
1510 lods byte [esi]
1511 lods byte [esi]
1512 cmp al,'('
1513 jne invalid_argument
1514 cmp byte [esi],'.'
1515 je invalid_value
1516 call get_count_value
1517 mov edx,[code_start]
1518 mov [edx+6Ch],eax
1519 cmp eax,[edx+68h]
1520 ja value_out_of_range
1521 jmp instruction_assembled
1522 peplus_heap:
1523 call get_qword_value
1524 cmp [value_type],0
1525 jne invalid_use_of_symbol
1526 mov ecx,[code_start]
1527 mov [ecx+70h],eax
1528 mov [ecx+74h],edx
1529 cmp byte [esi],','
1530 jne instruction_assembled
1531 lods byte [esi]
1532 lods byte [esi]
1533 cmp al,'('
1534 jne invalid_argument
1535 cmp byte [esi],'.'
1536 je invalid_value
1537 call get_qword_value
1538 cmp [value_type],0
1539 jne invalid_use_of_symbol
1540 mov ecx,[code_start]
1541 mov [ecx+78h],eax
1542 mov [ecx+7Ch],edx
1543 cmp edx,[ecx+74h]
1544 ja value_out_of_range
1545 jb instruction_assembled
1546 cmp eax,[ecx+70h]
1547 ja value_out_of_range
1548 jmp instruction_assembled
1549 mark_pe_relocation:
1550 push eax ebx
1551 test [format_flags],4
1552 jz check_standard_pe_relocation_type
1553 cmp [value_type],4
1554 je pe_relocation_type_ok
1555 check_standard_pe_relocation_type:
1556 cmp [value_type],2
1557 je pe_relocation_type_ok
1558 call recoverable_misuse
1559 pe_relocation_type_ok:
1560 mov ebx,[current_section]
1561 mov eax,edi
1562 sub eax,[ebx+14h]
1563 add eax,[ebx+0Ch]
1564 mov ebx,[free_additional_memory]
1565 inc [number_of_relocations]
1566 add ebx,5
1567 cmp ebx,[structures_buffer]
1568 jae out_of_memory
1569 mov [free_additional_memory],ebx
1570 mov [ebx-5],eax
1571 cmp [value_type],2
1572 je fixup_32bit
1573 mov byte [ebx-1],0Ah
1574 jmp fixup_ok
1575 fixup_32bit:
1576 mov byte [ebx-1],3
1577 fixup_ok:
1578 pop ebx eax
1579 ret
1580 generate_pe_data:
1581 cmp al,2
1582 je make_pe_resource
1583 cmp al,5
1584 je make_pe_fixups
1585 ret
1586 make_pe_fixups:
1587 mov edx,[code_start]
1588 and byte [edx+16h],not 1
1589 or byte [edx+5Eh],40h
1590 bts [resolver_flags],0
1591 jc fixups_ready
1592 or [next_pass_needed],-1
1593 fixups_ready:
1594 and [last_fixup_base],0
1595 call make_fixups
1596 xchg eax,[actual_fixups_size]
1597 sub eax,[actual_fixups_size]
1598 ja reserve_forward_fixups
1599 xor eax,eax
1600 reserve_forward_fixups:
1601 mov [reserved_fixups],edi
1602 add edi,eax
1603 mov [reserved_fixups_size],eax
1604 ret
1605 make_fixups:
1606 push esi
1607 xor ecx,ecx
1608 xchg ecx,[number_of_relocations]
1609 mov esi,[free_additional_memory]
1610 lea eax,[ecx*5]
1611 sub esi,eax
1612 mov [free_additional_memory],esi
1613 mov edx,[last_fixup_base]
1614 mov ebx,[last_fixup_header]
1615 mov ebp,edi
1616 jecxz fixups_done
1617 make_fixup:
1618 cmp [esi],edx
1619 jb store_fixup
1620 mov eax,edi
1621 sub eax,ebp
1622 test eax,11b
1623 jz fixups_block
1624 xor ax,ax
1625 stos word [edi]
1626 add dword [ebx],2
1627 fixups_block:
1628 mov eax,edx
1629 add edx,1000h
1630 cmp [esi],edx
1631 jae fixups_block
1632 stos dword [edi]
1633 mov ebx,edi
1634 mov eax,8
1635 stos dword [edi]
1636 store_fixup:
1637 add dword [ebx],2
1638 mov ah,[esi+1]
1639 and ah,0Fh
1640 mov al,[esi+4]
1641 shl al,4
1642 or ah,al
1643 mov al,[esi]
1644 stos word [edi]
1645 add esi,5
1646 loop make_fixup
1647 fixups_done:
1648 mov [last_fixup_base],edx
1649 mov [last_fixup_header],ebx
1650 pop esi
1651 mov eax,edi
1652 sub eax,ebp
1653 ret
1654 make_pe_resource:
1655 cmp byte [esi],82h
1656 jne resource_done
1657 inc esi
1658 lods word [esi]
1659 cmp ax,'('
1660 jne invalid_argument
1661 lods dword [esi]
1662 mov edx,esi
1663 lea esi,[esi+eax+1]
1664 cmp [next_pass_needed],0
1665 je resource_from_file
1666 cmp [current_pass],0
1667 jne reserve_space_for_resource
1668 and [resource_size],0
1669 reserve_space_for_resource:
1670 add edi,[resource_size]
1671 cmp edi,[tagged_blocks]
1672 ja out_of_memory
1673 jmp resource_done
1674 resource_from_file:
1675 push esi
1676 mov esi,edx
1677 call open_binary_file
1678 push ebx
1679 mov esi,[free_additional_memory]
1680 lea eax,[esi+20h]
1681 cmp eax,[structures_buffer]
1682 ja out_of_memory
1683 mov edx,esi
1684 mov ecx,20h
1685 call read
1686 jc invalid_file_format
1687 xor eax,eax
1688 cmp [esi],eax
1689 jne invalid_file_format
1690 mov ax,0FFFFh
1691 cmp [esi+8],eax
1692 jne invalid_file_format
1693 cmp [esi+12],eax
1694 jne invalid_file_format
1695 mov eax,20h
1696 cmp [esi+4],eax
1697 jne invalid_file_format
1698 read_resource_headers:
1699 test eax,11b
1700 jz resource_file_alignment_ok
1701 mov edx,4
1702 and eax,11b
1703 sub edx,eax
1704 mov al,1
1705 call lseek
1706 resource_file_alignment_ok:
1707 mov [esi],eax
1708 lea edx,[esi+12]
1709 mov ecx,8
1710 call read
1711 jc resource_headers_ok
1712 mov ecx,[esi+16]
1713 add [esi],ecx
1714 lea edx,[esi+20]
1715 sub ecx,8
1716 mov [esi+16],ecx
1717 lea eax,[edx+ecx]
1718 cmp eax,[structures_buffer]
1719 ja out_of_memory
1720 call read
1721 jc invalid_file_format
1722 mov edx,[esi]
1723 add edx,[esi+12]
1724 mov eax,[esi+16]
1725 lea ecx,[esi+20]
1726 lea esi,[ecx+eax]
1727 add ecx,2
1728 cmp word [ecx-2],0FFFFh
1729 je resource_header_type_ok
1730 check_resource_header_type:
1731 cmp ecx,esi
1732 jae invalid_file_format
1733 cmp word [ecx],0
1734 je resource_header_type_ok
1735 add ecx,2
1736 jmp check_resource_header_type
1737 resource_header_type_ok:
1738 add ecx,2
1739 cmp word [ecx],0FFFFh
1740 je resource_header_name_ok
1741 check_resource_header_name:
1742 cmp ecx,esi
1743 jae invalid_file_format
1744 cmp word [ecx],0
1745 je resource_header_name_ok
1746 add ecx,2
1747 jmp check_resource_header_name
1748 resource_header_name_ok:
1749 xor al,al
1750 call lseek
1751 jmp read_resource_headers
1752 resource_headers_ok:
1753 xor eax,eax
1754 mov [esi],eax
1755 mov [resource_data],edi
1756 lea eax,[edi+16]
1757 cmp eax,[tagged_blocks]
1758 jae out_of_memory
1759 xor eax,eax
1760 stos dword [edi]
1761 call make_timestamp
1762 stos dword [edi]
1763 xor eax,eax
1764 stos dword [edi]
1765 stos dword [edi]
1766 xor ebx,ebx
1767 make_type_name_directory:
1768 mov esi,[free_additional_memory]
1769 xor edx,edx
1770 find_type_name:
1771 cmp dword [esi],0
1772 je type_name_ok
1773 add esi,20
1774 cmp word [esi],0FFFFh
1775 je check_next_type_name
1776 or ebx,ebx
1777 jz check_this_type_name
1778 xor ecx,ecx
1779 compare_with_previous_type_name:
1780 mov ax,[esi+ecx]
1781 cmp ax,[ebx+ecx]
1782 ja check_this_type_name
1783 jb check_next_type_name
1784 add ecx,2
1785 mov ax,[esi+ecx]
1786 or ax,[ebx+ecx]
1787 jnz compare_with_previous_type_name
1788 jmp check_next_type_name
1789 check_this_type_name:
1790 or edx,edx
1791 jz type_name_found
1792 xor ecx,ecx
1793 compare_with_current_type_name:
1794 mov ax,[esi+ecx]
1795 cmp ax,[edx+ecx]
1796 ja check_next_type_name
1797 jb type_name_found
1798 add ecx,2
1799 mov ax,[esi+ecx]
1800 or ax,[edx+ecx]
1801 jnz compare_with_current_type_name
1802 jmp same_type_name
1803 type_name_found:
1804 mov edx,esi
1805 same_type_name:
1806 mov [esi-16],edi
1807 check_next_type_name:
1808 mov eax,[esi-4]
1809 add esi,eax
1810 jmp find_type_name
1811 type_name_ok:
1812 or edx,edx
1813 jz type_name_directory_done
1814 mov ebx,edx
1815 make_type_name_entry:
1816 mov eax,[resource_data]
1817 inc word [eax+12]
1818 lea eax,[edi+8]
1819 cmp eax,[tagged_blocks]
1820 jae out_of_memory
1821 mov eax,ebx
1822 stos dword [edi]
1823 xor eax,eax
1824 stos dword [edi]
1825 jmp make_type_name_directory
1826 type_name_directory_done:
1827 mov ebx,-1
1828 make_type_id_directory:
1829 mov esi,[free_additional_memory]
1830 mov edx,10000h
1831 find_type_id:
1832 cmp dword [esi],0
1833 je type_id_ok
1834 add esi,20
1835 cmp word [esi],0FFFFh
1836 jne check_next_type_id
1837 movzx eax,word [esi+2]
1838 cmp eax,ebx
1839 jle check_next_type_id
1840 cmp eax,edx
1841 jg check_next_type_id
1842 mov edx,eax
1843 mov [esi-16],edi
1844 check_next_type_id:
1845 mov eax,[esi-4]
1846 add esi,eax
1847 jmp find_type_id
1848 type_id_ok:
1849 cmp edx,10000h
1850 je type_id_directory_done
1851 mov ebx,edx
1852 make_type_id_entry:
1853 mov eax,[resource_data]
1854 inc word [eax+14]
1855 lea eax,[edi+8]
1856 cmp eax,[tagged_blocks]
1857 jae out_of_memory
1858 mov eax,ebx
1859 stos dword [edi]
1860 xor eax,eax
1861 stos dword [edi]
1862 jmp make_type_id_directory
1863 type_id_directory_done:
1864 mov esi,[resource_data]
1865 add esi,10h
1866 mov ecx,[esi-4]
1867 or cx,cx
1868 jz resource_directories_ok
1869 make_resource_directories:
1870 push ecx
1871 push edi
1872 mov edx,edi
1873 sub edx,[resource_data]
1874 bts edx,31
1875 mov [esi+4],edx
1876 lea eax,[edi+16]
1877 cmp eax,[tagged_blocks]
1878 jae out_of_memory
1879 xor eax,eax
1880 stos dword [edi]
1881 call make_timestamp
1882 stos dword [edi]
1883 xor eax,eax
1884 stos dword [edi]
1885 stos dword [edi]
1886 mov ebp,esi
1887 xor ebx,ebx
1888 make_resource_name_directory:
1889 mov esi,[free_additional_memory]
1890 xor edx,edx
1891 find_resource_name:
1892 cmp dword [esi],0
1893 je resource_name_ok
1894 push esi
1895 cmp [esi+4],ebp
1896 jne check_next_resource_name
1897 add esi,20
1898 call skip_resource_name
1899 cmp word [esi],0FFFFh
1900 je check_next_resource_name
1901 or ebx,ebx
1902 jz check_this_resource_name
1903 xor ecx,ecx
1904 compare_with_previous_resource_name:
1905 mov ax,[esi+ecx]
1906 cmp ax,[ebx+ecx]
1907 ja check_this_resource_name
1908 jb check_next_resource_name
1909 add ecx,2
1910 mov ax,[esi+ecx]
1911 or ax,[ebx+ecx]
1912 jnz compare_with_previous_resource_name
1913 jmp check_next_resource_name
1914 skip_resource_name:
1915 cmp word [esi],0FFFFh
1916 jne skip_unicode_string
1917 add esi,4
1918 ret
1919 skip_unicode_string:
1920 add esi,2
1921 cmp word [esi-2],0
1922 jne skip_unicode_string
1923 ret
1924 check_this_resource_name:
1925 or edx,edx
1926 jz resource_name_found
1927 xor ecx,ecx
1928 compare_with_current_resource_name:
1929 mov ax,[esi+ecx]
1930 cmp ax,[edx+ecx]
1931 ja check_next_resource_name
1932 jb resource_name_found
1933 add ecx,2
1934 mov ax,[esi+ecx]
1935 or ax,[edx+ecx]
1936 jnz compare_with_current_resource_name
1937 jmp same_resource_name
1938 resource_name_found:
1939 mov edx,esi
1940 same_resource_name:
1941 mov eax,[esp]
1942 mov [eax+8],edi
1943 check_next_resource_name:
1944 pop esi
1945 mov eax,[esi+16]
1946 lea esi,[esi+20+eax]
1947 jmp find_resource_name
1948 resource_name_ok:
1949 or edx,edx
1950 jz resource_name_directory_done
1951 mov ebx,edx
1952 make_resource_name_entry:
1953 mov eax,[esp]
1954 inc word [eax+12]
1955 lea eax,[edi+8]
1956 cmp eax,[tagged_blocks]
1957 jae out_of_memory
1958 mov eax,ebx
1959 stos dword [edi]
1960 xor eax,eax
1961 stos dword [edi]
1962 jmp make_resource_name_directory
1963 resource_name_directory_done:
1964 mov ebx,-1
1965 make_resource_id_directory:
1966 mov esi,[free_additional_memory]
1967 mov edx,10000h
1968 find_resource_id:
1969 cmp dword [esi],0
1970 je resource_id_ok
1971 push esi
1972 cmp [esi+4],ebp
1973 jne check_next_resource_id
1974 add esi,20
1975 call skip_resource_name
1976 cmp word [esi],0FFFFh
1977 jne check_next_resource_id
1978 movzx eax,word [esi+2]
1979 cmp eax,ebx
1980 jle check_next_resource_id
1981 cmp eax,edx
1982 jg check_next_resource_id
1983 mov edx,eax
1984 mov eax,[esp]
1985 mov [eax+8],edi
1986 check_next_resource_id:
1987 pop esi
1988 mov eax,[esi+16]
1989 lea esi,[esi+20+eax]
1990 jmp find_resource_id
1991 resource_id_ok:
1992 cmp edx,10000h
1993 je resource_id_directory_done
1994 mov ebx,edx
1995 make_resource_id_entry:
1996 mov eax,[esp]
1997 inc word [eax+14]
1998 lea eax,[edi+8]
1999 cmp eax,[tagged_blocks]
2000 jae out_of_memory
2001 mov eax,ebx
2002 stos dword [edi]
2003 xor eax,eax
2004 stos dword [edi]
2005 jmp make_resource_id_directory
2006 resource_id_directory_done:
2007 pop eax
2008 mov esi,ebp
2009 pop ecx
2010 add esi,8
2011 dec cx
2012 jnz make_resource_directories
2013 resource_directories_ok:
2014 shr ecx,16
2015 jnz make_resource_directories
2016 mov esi,[resource_data]
2017 add esi,10h
2018 movzx eax,word [esi-4]
2019 movzx edx,word [esi-2]
2020 add eax,edx
2021 lea esi,[esi+eax*8]
2022 push edi ; address of language directories
2023 update_resource_directories:
2024 cmp esi,[esp]
2025 je resource_directories_updated
2026 add esi,10h
2027 mov ecx,[esi-4]
2028 or cx,cx
2029 jz language_directories_ok
2030 make_language_directories:
2031 push ecx
2032 push edi
2033 mov edx,edi
2034 sub edx,[resource_data]
2035 bts edx,31
2036 mov [esi+4],edx
2037 lea eax,[edi+16]
2038 cmp eax,[tagged_blocks]
2039 jae out_of_memory
2040 xor eax,eax
2041 stos dword [edi]
2042 call make_timestamp
2043 stos dword [edi]
2044 xor eax,eax
2045 stos dword [edi]
2046 stos dword [edi]
2047 mov ebp,esi
2048 mov ebx,-1
2049 make_language_id_directory:
2050 mov esi,[free_additional_memory]
2051 mov edx,10000h
2052 find_language_id:
2053 cmp dword [esi],0
2054 je language_id_ok
2055 push esi
2056 cmp [esi+8],ebp
2057 jne check_next_language_id
2058 add esi,20
2059 mov eax,esi
2060 call skip_resource_name
2061 call skip_resource_name
2062 neg eax
2063 add eax,esi
2064 and eax,11b
2065 add esi,eax
2066 get_language_id:
2067 movzx eax,word [esi+6]
2068 cmp eax,ebx
2069 jle check_next_language_id
2070 cmp eax,edx
2071 jge check_next_language_id
2072 mov edx,eax
2073 mov eax,[esp]
2074 mov dword [value],eax
2075 check_next_language_id:
2076 pop esi
2077 mov eax,[esi+16]
2078 lea esi,[esi+20+eax]
2079 jmp find_language_id
2080 language_id_ok:
2081 cmp edx,10000h
2082 je language_id_directory_done
2083 mov ebx,edx
2084 make_language_id_entry:
2085 mov eax,[esp]
2086 inc word [eax+14]
2087 lea eax,[edi+8]
2088 cmp eax,[tagged_blocks]
2089 jae out_of_memory
2090 mov eax,ebx
2091 stos dword [edi]
2092 mov eax,dword [value]
2093 stos dword [edi]
2094 jmp make_language_id_directory
2095 language_id_directory_done:
2096 pop eax
2097 mov esi,ebp
2098 pop ecx
2099 add esi,8
2100 dec cx
2101 jnz make_language_directories
2102 language_directories_ok:
2103 shr ecx,16
2104 jnz make_language_directories
2105 jmp update_resource_directories
2106 resource_directories_updated:
2107 mov esi,[resource_data]
2108 push edi
2109 make_name_strings:
2110 add esi,10h
2111 movzx eax,word [esi-2]
2112 movzx ecx,word [esi-4]
2113 add eax,ecx
2114 lea eax,[esi+eax*8]
2115 push eax
2116 or ecx,ecx
2117 jz string_entries_processed
2118 process_string_entries:
2119 push ecx
2120 mov edx,edi
2121 sub edx,[resource_data]
2122 bts edx,31
2123 xchg [esi],edx
2124 mov ebx,edi
2125 xor ax,ax
2126 stos word [edi]
2127 copy_string_data:
2128 lea eax,[edi+2]
2129 cmp eax,[tagged_blocks]
2130 jae out_of_memory
2131 mov ax,[edx]
2132 or ax,ax
2133 jz string_data_copied
2134 stos word [edi]
2135 inc word [ebx]
2136 add edx,2
2137 jmp copy_string_data
2138 string_data_copied:
2139 add esi,8
2140 pop ecx
2141 loop process_string_entries
2142 string_entries_processed:
2143 pop esi
2144 cmp esi,[esp]
2145 jb make_name_strings
2146 mov eax,edi
2147 sub eax,[resource_data]
2148 test al,11b
2149 jz resource_strings_alignment_ok
2150 xor ax,ax
2151 stos word [edi]
2152 resource_strings_alignment_ok:
2153 pop edx
2154 pop ebx ; address of language directories
2155 mov ebp,edi
2156 update_language_directories:
2157 add ebx,10h
2158 movzx eax,word [ebx-2]
2159 movzx ecx,word [ebx-4]
2160 add ecx,eax
2161 make_data_records:
2162 push ecx
2163 mov esi,edi
2164 sub esi,[resource_data]
2165 xchg esi,[ebx+4]
2166 lea eax,[edi+16]
2167 cmp eax,[tagged_blocks]
2168 jae out_of_memory
2169 mov eax,esi
2170 stos dword [edi]
2171 mov eax,[esi+12]
2172 stos dword [edi]
2173 xor eax,eax
2174 stos dword [edi]
2175 stos dword [edi]
2176 pop ecx
2177 add ebx,8
2178 loop make_data_records
2179 cmp ebx,edx
2180 jb update_language_directories
2181 pop ebx ; file handle
2182 mov esi,ebp
2183 mov ebp,edi
2184 update_data_records:
2185 push ebp
2186 mov ecx,edi
2187 mov eax,[current_section]
2188 sub ecx,[eax+14h]
2189 add ecx,[eax+0Ch]
2190 xchg ecx,[esi]
2191 mov edx,[ecx]
2192 xor al,al
2193 call lseek
2194 mov edx,edi
2195 mov ecx,[esi+4]
2196 add edi,ecx
2197 cmp edi,[tagged_blocks]
2198 ja out_of_memory
2199 call read
2200 mov eax,edi
2201 sub eax,[resource_data]
2202 and eax,11b
2203 jz resource_data_alignment_ok
2204 mov ecx,4
2205 sub ecx,eax
2206 xor al,al
2207 rep stos byte [edi]
2208 resource_data_alignment_ok:
2209 pop ebp
2210 add esi,16
2211 cmp esi,ebp
2212 jb update_data_records
2213 pop esi
2214 call close
2215 mov eax,edi
2216 sub eax,[resource_data]
2217 mov [resource_size],eax
2218 resource_done:
2219 ret
2220 close_pe:
2221 call close_pe_section
2222 mov edx,[code_start]
2223 mov [edx+50h],eax
2224 call make_timestamp
2225 mov edx,[code_start]
2226 mov [edx+8],eax
2227 mov eax,[number_of_sections]
2228 mov [edx+6],ax
2229 imul eax,28h
2230 movzx ecx,word [edx+14h]
2231 lea eax,[eax+18h+ecx]
2232 add eax,[stub_size]
2233 mov ecx,[edx+3Ch]
2234 dec ecx
2235 add eax,ecx
2236 not ecx
2237 and eax,ecx
2238 cmp eax,[edx+54h]
2239 je pe_sections_ok
2240 or [next_pass_needed],-1
2241 pe_sections_ok:
2242 xor ecx,ecx
2243 add edx,78h
2244 test [format_flags],4
2245 jz process_directories
2246 add edx,10h
2247 process_directories:
2248 mov eax,[edx+ecx*8]
2249 or eax,eax
2250 jz directory_ok
2251 cmp dword [edx+ecx*8+4],-1
2252 jne directory_ok
2253 section_data:
2254 mov ebx,[edx+ecx*8]
2255 mov eax,[ebx+0Ch]
2256 mov [edx+ecx*8],eax ; directory rva
2257 mov eax,[ebx+8]
2258 mov [edx+ecx*8+4],eax ; directory size
2259 directory_ok:
2260 inc cl
2261 cmp cl,10h
2262 jb process_directories
2263 cmp dword [edx+5*8],0
2264 jne finish_pe_relocations
2265 mov eax,[number_of_relocations]
2266 shl eax,2
2267 sub [free_additional_memory],eax
2268 btr [resolver_flags],0
2269 jnc pe_relocations_ok
2270 or [next_pass_needed],-1
2271 jmp pe_relocations_ok
2272 finish_pe_relocations:
2273 push edi
2274 mov edi,[reserved_fixups]
2275 call make_fixups
2276 pop edi
2277 add [actual_fixups_size],eax
2278 cmp eax,[reserved_fixups_size]
2279 je pe_relocations_ok
2280 or [next_pass_needed],-1
2281 pe_relocations_ok:
2282 mov ebx,[code_start]
2283 sub ebx,[stub_size]
2284 mov ecx,edi
2285 sub ecx,ebx
2286 mov ebp,ecx
2287 shr ecx,1
2288 xor eax,eax
2289 cdq
2290 calculate_checksum:
2291 mov dx,[ebx]
2292 add eax,edx
2293 mov dx,ax
2294 shr eax,16
2295 add eax,edx
2296 add ebx,2
2297 loop calculate_checksum
2298 add eax,ebp
2299 mov ebx,[code_start]
2300 mov [ebx+58h],eax
2301 ret
2302
2303 format_coff:
2304 mov eax,[additional_memory]
2305 mov [symbols_stream],eax
2306 mov ebx,eax
2307 add eax,20h
2308 cmp eax,[structures_buffer]
2309 jae out_of_memory
2310 mov [free_additional_memory],eax
2311 xor eax,eax
2312 mov [ebx],al
2313 mov [ebx+4],eax
2314 mov [ebx+8],edi
2315 mov al,4
2316 mov [ebx+10h],eax
2317 mov al,60h
2318 bt [format_flags],0
2319 jnc flat_section_flags_ok
2320 or eax,0E0000000h
2321 flat_section_flags_ok:
2322 mov dword [ebx+14h],eax
2323 mov [current_section],ebx
2324 xor eax,eax
2325 mov [number_of_sections],eax
2326 mov edx,ebx
2327 call init_addressing_space
2328 mov [ebx+14h],edx
2329 mov byte [ebx+9],2
2330 mov [code_type],32
2331 test [format_flags],8
2332 jz format_defined
2333 mov byte [ebx+9],4
2334 mov [code_type],64
2335 jmp format_defined
2336 coff_section:
2337 call close_coff_section
2338 mov ebx,[free_additional_memory]
2339 lea eax,[ebx+20h]
2340 cmp eax,[structures_buffer]
2341 jae out_of_memory
2342 mov [free_additional_memory],eax
2343 mov [current_section],ebx
2344 inc [number_of_sections]
2345 xor eax,eax
2346 mov [ebx],al
2347 mov [ebx+8],edi
2348 mov [ebx+10h],eax
2349 mov [ebx+14h],eax
2350 mov edx,ebx
2351 call create_addressing_space
2352 xchg edx,ebx
2353 mov [edx+14h],ebx
2354 mov byte [edx+9],2
2355 test [format_flags],8
2356 jz coff_labels_type_ok
2357 mov byte [edx+9],4
2358 coff_labels_type_ok:
2359 lods word [esi]
2360 cmp ax,'('
2361 jne invalid_argument
2362 mov [ebx+4],esi
2363 mov ecx,[esi]
2364 lea esi,[esi+4+ecx+1]
2365 cmp ecx,8
2366 ja name_too_long
2367 coff_section_flags:
2368 cmp byte [esi],8Ch
2369 je coff_section_alignment
2370 cmp byte [esi],19h
2371 jne coff_section_settings_ok
2372 inc esi
2373 lods byte [esi]
2374 bt [format_flags],0
2375 jc coff_section_flag_ok
2376 cmp al,7
2377 ja invalid_argument
2378 coff_section_flag_ok:
2379 mov cl,al
2380 mov eax,1
2381 shl eax,cl
2382 test dword [ebx+14h],eax
2383 jnz setting_already_specified
2384 or dword [ebx+14h],eax
2385 jmp coff_section_flags
2386 coff_section_alignment:
2387 bt [format_flags],0
2388 jnc invalid_argument
2389 inc esi
2390 lods byte [esi]
2391 cmp al,'('
2392 jne invalid_argument
2393 cmp byte [esi],'.'
2394 je invalid_value
2395 push ebx
2396 call get_count_value
2397 pop ebx
2398 mov edx,eax
2399 dec edx
2400 test eax,edx
2401 jnz invalid_value
2402 or eax,eax
2403 jz invalid_value
2404 cmp eax,2000h
2405 ja invalid_value
2406 bsf edx,eax
2407 inc edx
2408 shl edx,20
2409 or [ebx+14h],edx
2410 xchg [ebx+10h],eax
2411 or eax,eax
2412 jnz setting_already_specified
2413 jmp coff_section_flags
2414 coff_section_settings_ok:
2415 cmp dword [ebx+10h],0
2416 jne instruction_assembled
2417 mov dword [ebx+10h],4
2418 bt [format_flags],0
2419 jnc instruction_assembled
2420 or dword [ebx+14h],300000h
2421 jmp instruction_assembled
2422 close_coff_section:
2423 mov ebx,[current_section]
2424 mov eax,edi
2425 mov edx,[ebx+8]
2426 sub eax,edx
2427 mov [ebx+0Ch],eax
2428 xor eax,eax
2429 xchg [undefined_data_end],eax
2430 cmp eax,edi
2431 jne coff_section_ok
2432 cmp edx,[undefined_data_start]
2433 jne coff_section_ok
2434 mov edi,edx
2435 or byte [ebx+14h],80h
2436 coff_section_ok:
2437 ret
2438 mark_coff_relocation:
2439 cmp [value_type],3
2440 je coff_relocation_relative
2441 push ebx eax
2442 test [format_flags],8
2443 jnz coff_64bit_relocation
2444 mov al,6
2445 cmp [value_type],2
2446 je coff_relocation
2447 cmp [value_type],5
2448 jne invalid_use_of_symbol
2449 inc al
2450 jmp coff_relocation
2451 coff_64bit_relocation:
2452 mov al,1
2453 cmp [value_type],4
2454 je coff_relocation
2455 mov al,2
2456 cmp [value_type],2
2457 je coff_relocation
2458 cmp [value_type],5
2459 jne invalid_use_of_symbol
2460 inc al
2461 jmp coff_relocation
2462 coff_relocation_relative:
2463 push ebx
2464 bt [format_flags],0
2465 jnc relative_ok
2466 mov ebx,[current_section]
2467 mov ebx,[ebx+8]
2468 sub ebx,edi
2469 sub eax,ebx
2470 add eax,4
2471 relative_ok:
2472 mov ebx,[addressing_space]
2473 push eax
2474 mov al,20
2475 test [format_flags],8
2476 jnz relative_coff_64bit_relocation
2477 cmp byte [ebx+9],2
2478 jne invalid_use_of_symbol
2479 jmp coff_relocation
2480 relative_coff_64bit_relocation:
2481 mov al,4
2482 cmp byte [ebx+9],4
2483 jne invalid_use_of_symbol
2484 coff_relocation:
2485 mov ebx,[free_additional_memory]
2486 add ebx,0Ch
2487 cmp ebx,[structures_buffer]
2488 jae out_of_memory
2489 mov [free_additional_memory],ebx
2490 mov byte [ebx-0Ch],al
2491 mov eax,[current_section]
2492 mov eax,[eax+8]
2493 neg eax
2494 add eax,edi
2495 mov [ebx-0Ch+4],eax
2496 mov eax,[symbol_identifier]
2497 mov [ebx-0Ch+8],eax
2498 pop eax ebx
2499 ret
2500 close_coff:
2501 call close_coff_section
2502 cmp [next_pass_needed],0
2503 je coff_closed
2504 mov eax,[symbols_stream]
2505 mov [free_additional_memory],eax
2506 coff_closed:
2507 ret
2508 coff_formatter:
2509 sub edi,[code_start]
2510 mov [code_size],edi
2511 call prepare_default_section
2512 mov edi,[free_additional_memory]
2513 mov ebx,edi
2514 mov ecx,28h shr 2
2515 imul ecx,[number_of_sections]
2516 add ecx,14h shr 2
2517 lea eax,[edi+ecx*4]
2518 cmp eax,[structures_buffer]
2519 jae out_of_memory
2520 xor eax,eax
2521 rep stos dword [edi]
2522 mov word [ebx],14Ch
2523 test [format_flags],8
2524 jz coff_magic_ok
2525 mov word [ebx],8664h
2526 coff_magic_ok:
2527 mov word [ebx+12h],104h
2528 bt [format_flags],0
2529 jnc coff_flags_ok
2530 or byte [ebx+12h],80h
2531 coff_flags_ok:
2532 push ebx
2533 call make_timestamp
2534 pop ebx
2535 mov [ebx+4],eax
2536 mov eax,[number_of_sections]
2537 mov [ebx+2],ax
2538 mov esi,[symbols_stream]
2539 xor eax,eax
2540 xor ecx,ecx
2541 enumerate_symbols:
2542 cmp esi,[free_additional_memory]
2543 je symbols_enumerated
2544 mov dl,[esi]
2545 or dl,dl
2546 jz enumerate_section
2547 cmp dl,0C0h
2548 jae enumerate_public
2549 cmp dl,80h
2550 jae enumerate_extrn
2551 add esi,0Ch
2552 jmp enumerate_symbols
2553 enumerate_section:
2554 mov edx,eax
2555 shl edx,8
2556 mov [esi],edx
2557 inc eax
2558 inc ecx
2559 mov [esi+1Eh],cx
2560 add esi,20h
2561 jmp enumerate_symbols
2562 enumerate_public:
2563 mov edx,eax
2564 shl edx,8
2565 mov dl,[esi]
2566 mov [esi],edx
2567 mov edx,[esi+8]
2568 add esi,10h
2569 inc eax
2570 cmp byte [edx+11],0
2571 je enumerate_symbols
2572 mov edx,[edx+20]
2573 cmp byte [edx],0C0h
2574 jae enumerate_symbols
2575 cmp byte [edx],80h
2576 jb enumerate_symbols
2577 inc eax
2578 jmp enumerate_symbols
2579 enumerate_extrn:
2580 mov edx,eax
2581 shl edx,8
2582 mov dl,[esi]
2583 mov [esi],edx
2584 add esi,0Ch
2585 inc eax
2586 jmp enumerate_symbols
2587 prepare_default_section:
2588 mov ebx,[symbols_stream]
2589 cmp dword [ebx+0Ch],0
2590 jne default_section_ok
2591 cmp [number_of_sections],0
2592 je default_section_ok
2593 mov edx,ebx
2594 find_references_to_default_section:
2595 cmp ebx,[free_additional_memory]
2596 jne check_reference
2597 add [symbols_stream],20h
2598 ret
2599 check_reference:
2600 mov al,[ebx]
2601 or al,al
2602 jz skip_other_section
2603 cmp al,0C0h
2604 jae check_public_reference
2605 cmp al,80h
2606 jae next_reference
2607 cmp edx,[ebx+8]
2608 je default_section_ok
2609 next_reference:
2610 add ebx,0Ch
2611 jmp find_references_to_default_section
2612 check_public_reference:
2613 mov eax,[ebx+8]
2614 add ebx,10h
2615 test byte [eax+8],1
2616 jz find_references_to_default_section
2617 mov cx,[current_pass]
2618 cmp cx,[eax+16]
2619 jne find_references_to_default_section
2620 cmp edx,[eax+20]
2621 je default_section_ok
2622 jmp find_references_to_default_section
2623 skip_other_section:
2624 add ebx,20h
2625 jmp find_references_to_default_section
2626 default_section_ok:
2627 inc [number_of_sections]
2628 ret
2629 symbols_enumerated:
2630 mov [ebx+0Ch],eax
2631 mov ebp,edi
2632 sub ebp,ebx
2633 push ebp
2634 lea edi,[ebx+14h]
2635 mov esi,[symbols_stream]
2636 find_section:
2637 cmp esi,[free_additional_memory]
2638 je sections_finished
2639 mov al,[esi]
2640 or al,al
2641 jz section_found
2642 add esi,0Ch
2643 cmp al,0C0h
2644 jb find_section
2645 add esi,4
2646 jmp find_section
2647 section_found:
2648 push esi edi
2649 mov esi,[esi+4]
2650 or esi,esi
2651 jz default_section
2652 mov ecx,[esi]
2653 add esi,4
2654 rep movs byte [edi],[esi]
2655 jmp section_name_ok
2656 default_section:
2657 mov al,'.'
2658 stos byte [edi]
2659 mov eax,'flat'
2660 stos dword [edi]
2661 section_name_ok:
2662 pop edi esi
2663 mov eax,[esi+0Ch]
2664 mov [edi+10h],eax
2665 mov eax,[esi+14h]
2666 mov [edi+24h],eax
2667 test al,80h
2668 jnz section_ptr_ok
2669 mov eax,[esi+8]
2670 sub eax,[code_start]
2671 add eax,ebp
2672 mov [edi+14h],eax
2673 section_ptr_ok:
2674 mov ebx,[code_start]
2675 mov edx,[code_size]
2676 add ebx,edx
2677 add edx,ebp
2678 xor ecx,ecx
2679 add esi,20h
2680 find_relocations:
2681 cmp esi,[free_additional_memory]
2682 je section_relocations_done
2683 mov al,[esi]
2684 or al,al
2685 jz section_relocations_done
2686 cmp al,80h
2687 jb add_relocation
2688 cmp al,0C0h
2689 jb next_relocation
2690 add esi,10h
2691 jmp find_relocations
2692 add_relocation:
2693 lea eax,[ebx+0Ah]
2694 cmp eax,[tagged_blocks]
2695 ja out_of_memory
2696 mov eax,[esi+4]
2697 mov [ebx],eax
2698 mov eax,[esi+8]
2699 mov eax,[eax]
2700 shr eax,8
2701 mov [ebx+4],eax
2702 movzx ax,byte [esi]
2703 mov [ebx+8],ax
2704 add ebx,0Ah
2705 inc ecx
2706 next_relocation:
2707 add esi,0Ch
2708 jmp find_relocations
2709 section_relocations_done:
2710 cmp ecx,10000h
2711 jb section_relocations_count_16bit
2712 bt [format_flags],0
2713 jnc format_limitations_exceeded
2714 mov word [edi+20h],0FFFFh
2715 or dword [edi+24h],1000000h
2716 mov [edi+18h],edx
2717 push esi edi
2718 push ecx
2719 lea esi,[ebx-1]
2720 add ebx,0Ah
2721 lea edi,[ebx-1]
2722 imul ecx,0Ah
2723 std
2724 rep movs byte [edi],[esi]
2725 cld
2726 pop ecx
2727 inc esi
2728 inc ecx
2729 mov [esi],ecx
2730 xor eax,eax
2731 mov [esi+4],eax
2732 mov [esi+8],ax
2733 pop edi esi
2734 jmp section_relocations_ok
2735 section_relocations_count_16bit:
2736 mov [edi+20h],cx
2737 jcxz section_relocations_ok
2738 mov [edi+18h],edx
2739 section_relocations_ok:
2740 sub ebx,[code_start]
2741 mov [code_size],ebx
2742 add edi,28h
2743 jmp find_section
2744 sections_finished:
2745 mov edx,[free_additional_memory]
2746 mov ebx,[code_size]
2747 add ebp,ebx
2748 mov [edx+8],ebp
2749 add ebx,[code_start]
2750 mov edi,ebx
2751 mov ecx,[edx+0Ch]
2752 imul ecx,12h shr 1
2753 xor eax,eax
2754 shr ecx,1
2755 jnc zero_symbols_table
2756 stos word [edi]
2757 zero_symbols_table:
2758 rep stos dword [edi]
2759 mov edx,edi
2760 stos dword [edi]
2761 mov esi,[symbols_stream]
2762 make_symbols_table:
2763 cmp esi,[free_additional_memory]
2764 je symbols_table_ok
2765 mov al,[esi]
2766 cmp al,0C0h
2767 jae add_public_symbol
2768 cmp al,80h
2769 jae add_extrn_symbol
2770 or al,al
2771 jz add_section_symbol
2772 add esi,0Ch
2773 jmp make_symbols_table
2774 add_section_symbol:
2775 call store_symbol_name
2776 movzx eax,word [esi+1Eh]
2777 mov [ebx+0Ch],ax
2778 mov byte [ebx+10h],3
2779 add esi,20h
2780 add ebx,12h
2781 jmp make_symbols_table
2782 add_extrn_symbol:
2783 call store_symbol_name
2784 mov byte [ebx+10h],2
2785 add esi,0Ch
2786 add ebx,12h
2787 jmp make_symbols_table
2788 add_public_symbol:
2789 call store_symbol_name
2790 mov eax,[esi+0Ch]
2791 mov [current_line],eax
2792 mov eax,[esi+8]
2793 test byte [eax+8],1
2794 jz undefined_coff_public
2795 mov cx,[current_pass]
2796 cmp cx,[eax+16]
2797 jne undefined_coff_public
2798 mov cl,[eax+11]
2799 or cl,cl
2800 jz public_constant
2801 test [format_flags],8
2802 jnz check_64bit_public_symbol
2803 cmp cl,2
2804 je public_symbol_type_ok
2805 jmp invalid_use_of_symbol
2806 undefined_coff_public:
2807 mov [error_info],eax
2808 jmp undefined_symbol
2809 check_64bit_public_symbol:
2810 cmp cl,4
2811 jne invalid_use_of_symbol
2812 public_symbol_type_ok:
2813 mov ecx,[eax+20]
2814 cmp byte [ecx],80h
2815 je alias_symbol
2816 cmp byte [ecx],0
2817 jne invalid_use_of_symbol
2818 mov cx,[ecx+1Eh]
2819 mov [ebx+0Ch],cx
2820 public_symbol_section_ok:
2821 movzx ecx,byte [eax+9]
2822 shr cl,1
2823 and cl,1
2824 neg ecx
2825 cmp ecx,[eax+4]
2826 jne value_out_of_range
2827 xor ecx,[eax]
2828 js value_out_of_range
2829 mov eax,[eax]
2830 mov [ebx+8],eax
2831 mov al,2
2832 cmp byte [esi],0C0h
2833 je store_symbol_class
2834 inc al
2835 cmp byte [esi],0C1h
2836 je store_symbol_class
2837 mov al,105
2838 store_symbol_class:
2839 mov byte [ebx+10h],al
2840 add esi,10h
2841 add ebx,12h
2842 jmp make_symbols_table
2843 alias_symbol:
2844 bt [format_flags],0
2845 jnc invalid_use_of_symbol
2846 mov ecx,[eax]
2847 or ecx,[eax+4]
2848 jnz invalid_use_of_symbol
2849 mov byte [ebx+10h],69h
2850 mov byte [ebx+11h],1
2851 add ebx,12h
2852 mov ecx,[eax+20]
2853 mov ecx,[ecx]
2854 shr ecx,8
2855 mov [ebx],ecx
2856 mov byte [ebx+4],3
2857 add esi,10h
2858 add ebx,12h
2859 jmp make_symbols_table
2860 public_constant:
2861 mov word [ebx+0Ch],0FFFFh
2862 jmp public_symbol_section_ok
2863 symbols_table_ok:
2864 mov eax,edi
2865 sub eax,edx
2866 mov [edx],eax
2867 sub edi,[code_start]
2868 mov [code_size],edi
2869 and [written_size],0
2870 mov edx,[output_file]
2871 call create
2872 jc write_failed
2873 mov edx,[free_additional_memory]
2874 pop ecx
2875 add [written_size],ecx
2876 call write
2877 jc write_failed
2878 jmp write_output
2879 store_symbol_name:
2880 push esi
2881 mov esi,[esi+4]
2882 or esi,esi
2883 jz default_name
2884 lods dword [esi]
2885 mov ecx,eax
2886 cmp ecx,8
2887 ja add_string
2888 push edi
2889 mov edi,ebx
2890 rep movs byte [edi],[esi]
2891 pop edi esi
2892 ret
2893 default_name:
2894 mov dword [ebx],'.fla'
2895 mov dword [ebx+4],'t'
2896 pop esi
2897 ret
2898 add_string:
2899 mov eax,edi
2900 sub eax,edx
2901 mov [ebx+4],eax
2902 inc ecx
2903 rep movs byte [edi],[esi]
2904 pop esi
2905 ret
2906
2907 format_elf:
2908 test [format_flags],8
2909 jnz format_elf64
2910 mov edx,edi
2911 mov ecx,34h shr 2
2912 lea eax,[edi+ecx*4]
2913 cmp eax,[tagged_blocks]
2914 jae out_of_memory
2915 xor eax,eax
2916 rep stos dword [edi]
2917 mov dword [edx],7Fh + 'ELF' shl 8
2918 mov al,1
2919 mov [edx+4],al
2920 mov [edx+5],al
2921 mov [edx+6],al
2922 mov [edx+14h],al
2923 mov byte [edx+12h],3
2924 mov byte [edx+28h],34h
2925 mov byte [edx+2Eh],28h
2926 mov [code_type],32
2927 cmp word [esi],1D19h
2928 je format_elf_exe
2929 elf_header_ok:
2930 mov byte [edx+10h],1
2931 mov eax,[additional_memory]
2932 mov [symbols_stream],eax
2933 mov ebx,eax
2934 add eax,20h
2935 cmp eax,[structures_buffer]
2936 jae out_of_memory
2937 mov [free_additional_memory],eax
2938 xor eax,eax
2939 mov [current_section],ebx
2940 mov [number_of_sections],eax
2941 mov [ebx],al
2942 mov [ebx+4],eax
2943 mov [ebx+8],edi
2944 mov al,111b
2945 mov [ebx+14h],eax
2946 mov al,4
2947 mov [ebx+10h],eax
2948 mov edx,ebx
2949 call init_addressing_space
2950 xchg edx,ebx
2951 mov [edx+14h],ebx
2952 mov byte [edx+9],2
2953 test [format_flags],8
2954 jz format_defined
2955 mov byte [edx+9],4
2956 mov byte [ebx+10h],8
2957 jmp format_defined
2958 format_elf64:
2959 mov edx,edi
2960 mov ecx,40h shr 2
2961 lea eax,[edi+ecx*4]
2962 cmp eax,[tagged_blocks]
2963 jae out_of_memory
2964 xor eax,eax
2965 rep stos dword [edi]
2966 mov dword [edx],7Fh + 'ELF' shl 8
2967 mov al,1
2968 mov [edx+5],al
2969 mov [edx+6],al
2970 mov [edx+14h],al
2971 mov byte [edx+4],2
2972 mov byte [edx+12h],62
2973 mov byte [edx+34h],40h
2974 mov byte [edx+3Ah],40h
2975 mov [code_type],64
2976 cmp word [esi],1D19h
2977 jne elf_header_ok
2978 jmp format_elf64_exe
2979 elf_section:
2980 bt [format_flags],0
2981 jc illegal_instruction
2982 call close_coff_section
2983 mov ebx,[free_additional_memory]
2984 lea eax,[ebx+20h]
2985 cmp eax,[structures_buffer]
2986 jae out_of_memory
2987 mov [free_additional_memory],eax
2988 mov [current_section],ebx
2989 inc word [number_of_sections]
2990 jz format_limitations_exceeded
2991 xor eax,eax
2992 mov [ebx],al
2993 mov [ebx+8],edi
2994 mov [ebx+10h],eax
2995 mov al,10b
2996 mov [ebx+14h],eax
2997 mov edx,ebx
2998 call create_addressing_space
2999 xchg edx,ebx
3000 mov [edx+14h],ebx
3001 mov byte [edx+9],2
3002 test [format_flags],8
3003 jz elf_labels_type_ok
3004 mov byte [edx+9],4
3005 elf_labels_type_ok:
3006 lods word [esi]
3007 cmp ax,'('
3008 jne invalid_argument
3009 mov [ebx+4],esi
3010 mov ecx,[esi]
3011 lea esi,[esi+4+ecx+1]
3012 elf_section_flags:
3013 cmp byte [esi],8Ch
3014 je elf_section_alignment
3015 cmp byte [esi],19h
3016 jne elf_section_settings_ok
3017 inc esi
3018 lods byte [esi]
3019 sub al,28
3020 xor al,11b
3021 test al,not 10b
3022 jnz invalid_argument
3023 mov cl,al
3024 mov al,1
3025 shl al,cl
3026 test byte [ebx+14h],al
3027 jnz setting_already_specified
3028 or byte [ebx+14h],al
3029 jmp elf_section_flags
3030 elf_section_alignment:
3031 inc esi
3032 lods byte [esi]
3033 cmp al,'('
3034 jne invalid_argument
3035 cmp byte [esi],'.'
3036 je invalid_value
3037 push ebx
3038 call get_count_value
3039 pop ebx
3040 mov edx,eax
3041 dec edx
3042 test eax,edx
3043 jnz invalid_value
3044 or eax,eax
3045 jz invalid_value
3046 xchg [ebx+10h],eax
3047 or eax,eax
3048 jnz setting_already_specified
3049 jmp elf_section_flags
3050 elf_section_settings_ok:
3051 cmp dword [ebx+10h],0
3052 jne instruction_assembled
3053 mov dword [ebx+10h],4
3054 test [format_flags],8
3055 jz instruction_assembled
3056 mov byte [ebx+10h],8
3057 jmp instruction_assembled
3058 mark_elf_relocation:
3059 push ebx
3060 mov ebx,[addressing_space]
3061 cmp [value_type],3
3062 je elf_relocation_relative
3063 cmp [value_type],7
3064 je elf_relocation_relative
3065 push eax
3066 cmp [value_type],5
3067 je elf_gotoff_relocation
3068 ja invalid_use_of_symbol
3069 mov al,1 ; R_386_32 / R_AMD64_64
3070 test [format_flags],8
3071 jz coff_relocation
3072 cmp [value_type],4
3073 je coff_relocation
3074 mov al,11 ; R_AMD64_32S
3075 jmp coff_relocation
3076 elf_gotoff_relocation:
3077 test [format_flags],8
3078 jnz invalid_use_of_symbol
3079 mov al,9 ; R_386_GOTOFF
3080 jmp coff_relocation
3081 elf_relocation_relative:
3082 cmp byte [ebx+9],0
3083 je invalid_use_of_symbol
3084 mov ebx,[current_section]
3085 mov ebx,[ebx+8]
3086 sub ebx,edi
3087 sub eax,ebx
3088 push eax
3089 mov al,2 ; R_386_PC32 / R_AMD64_PC32
3090 cmp [value_type],3
3091 je coff_relocation
3092 mov al,4 ; R_386_PLT32 / R_AMD64_PLT32
3093 jmp coff_relocation
3094 close_elf:
3095 bt [format_flags],0
3096 jc close_elf_exe
3097 call close_coff_section
3098 cmp [next_pass_needed],0
3099 je elf_closed
3100 mov eax,[symbols_stream]
3101 mov [free_additional_memory],eax
3102 elf_closed:
3103 ret
3104 elf_formatter:
3105 push edi
3106 call prepare_default_section
3107 mov esi,[symbols_stream]
3108 mov edi,[free_additional_memory]
3109 xor eax,eax
3110 mov ecx,4
3111 rep stos dword [edi]
3112 test [format_flags],8
3113 jz find_first_section
3114 mov ecx,2
3115 rep stos dword [edi]
3116 find_first_section:
3117 mov al,[esi]
3118 or al,al
3119 jz first_section_found
3120 cmp al,0C0h
3121 jb skip_other_symbol
3122 add esi,4
3123 skip_other_symbol:
3124 add esi,0Ch
3125 jmp find_first_section
3126 first_section_found:
3127 mov ebx,esi
3128 mov ebp,esi
3129 add esi,20h
3130 xor ecx,ecx
3131 xor edx,edx
3132 find_next_section:
3133 cmp esi,[free_additional_memory]
3134 je make_section_symbol
3135 mov al,[esi]
3136 or al,al
3137 jz make_section_symbol
3138 cmp al,0C0h
3139 jae skip_public
3140 cmp al,80h
3141 jae skip_extrn
3142 or byte [ebx+14h],40h
3143 skip_extrn:
3144 add esi,0Ch
3145 jmp find_next_section
3146 skip_public:
3147 add esi,10h
3148 jmp find_next_section
3149 make_section_symbol:
3150 mov eax,edi
3151 xchg eax,[ebx+4]
3152 stos dword [edi]
3153 test [format_flags],8
3154 jnz elf64_section_symbol
3155 xor eax,eax
3156 stos dword [edi]
3157 stos dword [edi]
3158 call store_section_index
3159 jmp section_symbol_ok
3160 store_section_index:
3161 inc ecx
3162 mov eax,ecx
3163 shl eax,8
3164 mov [ebx],eax
3165 inc dx
3166 jz format_limitations_exceeded
3167 mov eax,edx
3168 shl eax,16
3169 mov al,3
3170 test byte [ebx+14h],40h
3171 jz section_index_ok
3172 or ah,-1
3173 inc dx
3174 jz format_limitations_exceeded
3175 section_index_ok:
3176 stos dword [edi]
3177 ret
3178 elf64_section_symbol:
3179 call store_section_index
3180 xor eax,eax
3181 stos dword [edi]
3182 stos dword [edi]
3183 stos dword [edi]
3184 stos dword [edi]
3185 section_symbol_ok:
3186 mov ebx,esi
3187 add esi,20h
3188 cmp ebx,[free_additional_memory]
3189 jne find_next_section
3190 inc dx
3191 jz format_limitations_exceeded
3192 mov [current_section],edx
3193 mov esi,[symbols_stream]
3194 find_other_symbols:
3195 cmp esi,[free_additional_memory]
3196 je elf_symbol_table_ok
3197 mov al,[esi]
3198 or al,al
3199 jz skip_section
3200 cmp al,0C0h
3201 jae make_public_symbol
3202 cmp al,80h
3203 jae make_extrn_symbol
3204 add esi,0Ch
3205 jmp find_other_symbols
3206 skip_section:
3207 add esi,20h
3208 jmp find_other_symbols
3209 make_public_symbol:
3210 mov eax,[esi+0Ch]
3211 mov [current_line],eax
3212 cmp byte [esi],0C0h
3213 jne invalid_argument
3214 mov ebx,[esi+8]
3215 test byte [ebx+8],1
3216 jz undefined_public
3217 mov ax,[current_pass]
3218 cmp ax,[ebx+16]
3219 jne undefined_public
3220 mov dl,[ebx+11]
3221 or dl,dl
3222 jz public_absolute
3223 mov eax,[ebx+20]
3224 cmp byte [eax],0
3225 jne invalid_use_of_symbol
3226 mov eax,[eax+4]
3227 test [format_flags],8
3228 jnz elf64_public
3229 cmp dl,2
3230 jne invalid_use_of_symbol
3231 mov dx,[eax+0Eh]
3232 jmp section_for_public_ok
3233 undefined_public:
3234 mov [error_info],ebx
3235 jmp undefined_symbol
3236 elf64_public:
3237 cmp dl,4
3238 jne invalid_use_of_symbol
3239 mov dx,[eax+6]
3240 jmp section_for_public_ok
3241 public_absolute:
3242 mov dx,0FFF1h
3243 section_for_public_ok:
3244 mov eax,[esi+4]
3245 stos dword [edi]
3246 test [format_flags],8
3247 jnz elf64_public_symbol
3248 movzx eax,byte [ebx+9]
3249 shr al,1
3250 and al,1
3251 neg eax
3252 cmp eax,[ebx+4]
3253 jne value_out_of_range
3254 xor eax,[ebx]
3255 js value_out_of_range
3256 mov eax,[ebx]
3257 stos dword [edi]
3258 xor eax,eax
3259 mov al,[ebx+10]
3260 stos dword [edi]
3261 mov eax,edx
3262 shl eax,16
3263 mov al,10h
3264 cmp byte [ebx+10],0
3265 je elf_public_function
3266 or al,1
3267 jmp store_elf_public_info
3268 elf_public_function:
3269 or al,2
3270 store_elf_public_info:
3271 stos dword [edi]
3272 jmp public_symbol_ok
3273 elf64_public_symbol:
3274 mov eax,edx
3275 shl eax,16
3276 mov al,10h
3277 cmp byte [ebx+10],0
3278 je elf64_public_function
3279 or al,1
3280 jmp store_elf64_public_info
3281 elf64_public_function:
3282 or al,2
3283 store_elf64_public_info:
3284 stos dword [edi]
3285 mov al,[ebx+9]
3286 shl eax,31-1
3287 xor eax,[ebx+4]
3288 js value_out_of_range
3289 mov eax,[ebx]
3290 stos dword [edi]
3291 mov eax,[ebx+4]
3292 stos dword [edi]
3293 mov al,[ebx+10]
3294 stos dword [edi]
3295 xor al,al
3296 stos dword [edi]
3297 public_symbol_ok:
3298 inc ecx
3299 mov eax,ecx
3300 shl eax,8
3301 mov al,0C0h
3302 mov [esi],eax
3303 add esi,10h
3304 jmp find_other_symbols
3305 make_extrn_symbol:
3306 mov eax,[esi+4]
3307 stos dword [edi]
3308 test [format_flags],8
3309 jnz elf64_extrn_symbol
3310 xor eax,eax
3311 stos dword [edi]
3312 mov eax,[esi+8]
3313 stos dword [edi]
3314 mov eax,10h
3315 stos dword [edi]
3316 jmp extrn_symbol_ok
3317 elf64_extrn_symbol:
3318 mov eax,10h
3319 stos dword [edi]
3320 xor al,al
3321 stos dword [edi]
3322 stos dword [edi]
3323 mov eax,[esi+8]
3324 stos dword [edi]
3325 xor eax,eax
3326 stos dword [edi]
3327 extrn_symbol_ok:
3328 inc ecx
3329 mov eax,ecx
3330 shl eax,8
3331 mov al,80h
3332 mov [esi],eax
3333 add esi,0Ch
3334 jmp find_other_symbols
3335 elf_symbol_table_ok:
3336 mov edx,edi
3337 mov ebx,[free_additional_memory]
3338 xor al,al
3339 stos byte [edi]
3340 add edi,16
3341 mov [edx+1],edx
3342 add ebx,10h
3343 test [format_flags],8
3344 jz make_string_table
3345 add ebx,8
3346 make_string_table:
3347 cmp ebx,edx
3348 je elf_string_table_ok
3349 test [format_flags],8
3350 jnz make_elf64_string
3351 cmp byte [ebx+0Dh],0
3352 je rel_prefix_ok
3353 mov byte [ebx+0Dh],0
3354 mov eax,'.rel'
3355 stos dword [edi]
3356 rel_prefix_ok:
3357 mov esi,edi
3358 sub esi,edx
3359 xchg esi,[ebx]
3360 add ebx,10h
3361 make_elf_string:
3362 or esi,esi
3363 jz default_string
3364 lods dword [esi]
3365 mov ecx,eax
3366 rep movs byte [edi],[esi]
3367 xor al,al
3368 stos byte [edi]
3369 jmp make_string_table
3370 make_elf64_string:
3371 cmp byte [ebx+5],0
3372 je elf64_rel_prefix_ok
3373 mov byte [ebx+5],0
3374 mov eax,'.rel'
3375 stos dword [edi]
3376 mov al,'a'
3377 stos byte [edi]
3378 elf64_rel_prefix_ok:
3379 mov esi,edi
3380 sub esi,edx
3381 xchg esi,[ebx]
3382 add ebx,18h
3383 jmp make_elf_string
3384 default_string:
3385 mov eax,'.fla'
3386 stos dword [edi]
3387 mov ax,'t'
3388 stos word [edi]
3389 jmp make_string_table
3390 elf_string_table_ok:
3391 mov [edx+1+8],edi
3392 mov ebx,[code_start]
3393 mov eax,edi
3394 sub eax,[free_additional_memory]
3395 test [format_flags],8
3396 jnz finish_elf64_header
3397 mov [ebx+20h],eax
3398 mov eax,[current_section]
3399 inc ax
3400 jz format_limitations_exceeded
3401 mov [ebx+32h],ax
3402 inc ax
3403 jz format_limitations_exceeded
3404 mov [ebx+30h],ax
3405 jmp elf_header_finished
3406 finish_elf64_header:
3407 mov [ebx+28h],eax
3408 mov eax,[current_section]
3409 inc ax
3410 jz format_limitations_exceeded
3411 mov [ebx+3Eh],ax
3412 inc ax
3413 jz format_limitations_exceeded
3414 mov [ebx+3Ch],ax
3415 elf_header_finished:
3416 xor eax,eax
3417 mov ecx,10
3418 rep stos dword [edi]
3419 test [format_flags],8
3420 jz elf_null_section_ok
3421 mov ecx,6
3422 rep stos dword [edi]
3423 elf_null_section_ok:
3424 mov esi,ebp
3425 xor ecx,ecx
3426 make_section_entry:
3427 mov ebx,edi
3428 mov eax,[esi+4]
3429 mov eax,[eax]
3430 stos dword [edi]
3431 mov eax,1
3432 cmp dword [esi+0Ch],0
3433 je bss_section
3434 test byte [esi+14h],80h
3435 jz section_type_ok
3436 bss_section:
3437 mov al,8
3438 section_type_ok:
3439 stos dword [edi]
3440 mov eax,[esi+14h]
3441 and al,3Fh
3442 call store_elf_machine_word
3443 xor eax,eax
3444 call store_elf_machine_word
3445 mov eax,[esi+8]
3446 mov [image_base],eax
3447 sub eax,[code_start]
3448 call store_elf_machine_word
3449 mov eax,[esi+0Ch]
3450 call store_elf_machine_word
3451 xor eax,eax
3452 stos dword [edi]
3453 stos dword [edi]
3454 mov eax,[esi+10h]
3455 call store_elf_machine_word
3456 xor eax,eax
3457 call store_elf_machine_word
3458 inc ecx
3459 add esi,20h
3460 xchg edi,[esp]
3461 mov ebp,edi
3462 convert_relocations:
3463 cmp esi,[free_additional_memory]
3464 je relocations_converted
3465 mov al,[esi]
3466 or al,al
3467 jz relocations_converted
3468 cmp al,80h
3469 jb make_relocation_entry
3470 cmp al,0C0h
3471 jb relocation_entry_ok
3472 add esi,10h
3473 jmp convert_relocations
3474 make_relocation_entry:
3475 test [format_flags],8
3476 jnz make_elf64_relocation_entry
3477 mov eax,[esi+4]
3478 stos dword [edi]
3479 mov eax,[esi+8]
3480 mov eax,[eax]
3481 mov al,[esi]
3482 stos dword [edi]
3483 jmp relocation_entry_ok
3484 make_elf64_relocation_entry:
3485 mov eax,[esi+4]
3486 stos dword [edi]
3487 xor eax,eax
3488 stos dword [edi]
3489 movzx eax,byte [esi]
3490 stos dword [edi]
3491 mov eax,[esi+8]
3492 mov eax,[eax]
3493 shr eax,8
3494 stos dword [edi]
3495 xor eax,eax
3496 stos dword [edi]
3497 stos dword [edi]
3498 relocation_entry_ok:
3499 add esi,0Ch
3500 jmp convert_relocations
3501 store_elf_machine_word:
3502 stos dword [edi]
3503 test [format_flags],8
3504 jz elf_machine_word_ok
3505 and dword [edi],0
3506 add edi,4
3507 elf_machine_word_ok:
3508 ret
3509 relocations_converted:
3510 cmp edi,ebp
3511 xchg edi,[esp]
3512 je rel_section_ok
3513 mov eax,[ebx]
3514 sub eax,4
3515 test [format_flags],8
3516 jz store_relocations_name_offset
3517 dec eax
3518 store_relocations_name_offset:
3519 stos dword [edi]
3520 test [format_flags],8
3521 jnz rela_section
3522 mov eax,9
3523 jmp store_relocations_type
3524 rela_section:
3525 mov eax,4
3526 store_relocations_type:
3527 stos dword [edi]
3528 xor al,al
3529 call store_elf_machine_word
3530 call store_elf_machine_word
3531 mov eax,ebp
3532 sub eax,[code_start]
3533 call store_elf_machine_word
3534 mov eax,[esp]
3535 sub eax,ebp
3536 call store_elf_machine_word
3537 mov eax,[current_section]
3538 stos dword [edi]
3539 mov eax,ecx
3540 stos dword [edi]
3541 inc ecx
3542 test [format_flags],8
3543 jnz finish_elf64_rela_section
3544 mov eax,4
3545 stos dword [edi]
3546 mov al,8
3547 stos dword [edi]
3548 jmp rel_section_ok
3549 finish_elf64_rela_section:
3550 mov eax,8
3551 stos dword [edi]
3552 xor al,al
3553 stos dword [edi]
3554 mov al,24
3555 stos dword [edi]
3556 xor al,al
3557 stos dword [edi]
3558 rel_section_ok:
3559 cmp esi,[free_additional_memory]
3560 jne make_section_entry
3561 pop eax
3562 mov ebx,[code_start]
3563 sub eax,ebx
3564 mov [code_size],eax
3565 mov ecx,20h
3566 test [format_flags],8
3567 jz adjust_elf_section_headers_offset
3568 mov ecx,28h
3569 adjust_elf_section_headers_offset:
3570 add [ebx+ecx],eax
3571 mov eax,1
3572 stos dword [edi]
3573 mov al,2
3574 stos dword [edi]
3575 xor al,al
3576 call store_elf_machine_word
3577 call store_elf_machine_word
3578 mov eax,[code_size]
3579 call store_elf_machine_word
3580 mov eax,[edx+1]
3581 sub eax,[free_additional_memory]
3582 call store_elf_machine_word
3583 mov eax,[current_section]
3584 inc eax
3585 stos dword [edi]
3586 mov eax,[number_of_sections]
3587 inc eax
3588 stos dword [edi]
3589 test [format_flags],8
3590 jnz finish_elf64_sym_section
3591 mov eax,4
3592 stos dword [edi]
3593 mov al,10h
3594 stos dword [edi]
3595 jmp sym_section_ok
3596 finish_elf64_sym_section:
3597 mov eax,8
3598 stos dword [edi]
3599 xor al,al
3600 stos dword [edi]
3601 mov al,18h
3602 stos dword [edi]
3603 xor al,al
3604 stos dword [edi]
3605 sym_section_ok:
3606 mov al,1+8
3607 stos dword [edi]
3608 mov al,3
3609 stos dword [edi]
3610 xor al,al
3611 call store_elf_machine_word
3612 call store_elf_machine_word
3613 mov eax,[edx+1]
3614 sub eax,[free_additional_memory]
3615 add eax,[code_size]
3616 call store_elf_machine_word
3617 mov eax,[edx+1+8]
3618 sub eax,[edx+1]
3619 call store_elf_machine_word
3620 xor eax,eax
3621 stos dword [edi]
3622 stos dword [edi]
3623 mov al,1
3624 call store_elf_machine_word
3625 xor eax,eax
3626 call store_elf_machine_word
3627 mov eax,'tab'
3628 mov dword [edx+1],'.sym'
3629 mov [edx+1+4],eax
3630 mov dword [edx+1+8],'.str'
3631 mov [edx+1+8+4],eax
3632 mov [resource_data],edx
3633 mov [written_size],0
3634 mov edx,[output_file]
3635 call create
3636 jc write_failed
3637 call write_code
3638 mov ecx,edi
3639 mov edx,[free_additional_memory]
3640 sub ecx,edx
3641 add [written_size],ecx
3642 call write
3643 jc write_failed
3644 jmp output_written
3645
3646 format_elf_exe:
3647 add esi,2
3648 or [format_flags],1
3649 cmp byte [esi],'('
3650 jne elf_exe_brand_ok
3651 inc esi
3652 cmp byte [esi],'.'
3653 je invalid_value
3654 push edx
3655 call get_byte_value
3656 cmp [value_type],0
3657 jne invalid_use_of_symbol
3658 pop edx
3659 mov [edx+7],al
3660 elf_exe_brand_ok:
3661 mov [image_base],8048000h
3662 cmp byte [esi],80h
3663 jne elf_exe_base_ok
3664 lods word [esi]
3665 cmp ah,'('
3666 jne invalid_argument
3667 cmp byte [esi],'.'
3668 je invalid_value
3669 push edx
3670 call get_dword_value
3671 cmp [value_type],0
3672 jne invalid_use_of_symbol
3673 mov [image_base],eax
3674 pop edx
3675 elf_exe_base_ok:
3676 mov byte [edx+10h],2
3677 mov byte [edx+2Ah],20h
3678 mov ebx,edi
3679 mov ecx,20h shr 2
3680 cmp [current_pass],0
3681 je init_elf_segments
3682 imul ecx,[number_of_sections]
3683 init_elf_segments:
3684 xor eax,eax
3685 rep stos dword [edi]
3686 and [number_of_sections],0
3687 mov byte [ebx],1
3688 mov word [ebx+1Ch],1000h
3689 mov byte [ebx+18h],111b
3690 mov eax,edi
3691 xor ebp,ebp
3692 xor cl,cl
3693 sub eax,[code_start]
3694 sbb ebp,0
3695 sbb cl,0
3696 mov [ebx+4],eax
3697 add eax,[image_base]
3698 adc ebp,0
3699 adc cl,0
3700 mov [ebx+8],eax
3701 mov [ebx+0Ch],eax
3702 mov [edx+18h],eax
3703 not eax
3704 not ebp
3705 not cl
3706 add eax,1
3707 adc ebp,0
3708 adc cl,0
3709 add eax,edi
3710 adc ebp,0
3711 adc cl,0
3712 mov edx,ebp
3713 elf_exe_addressing_setup:
3714 push eax
3715 call init_addressing_space
3716 pop eax
3717 mov [ebx],eax
3718 mov [ebx+4],edx
3719 mov [ebx+8],cl
3720 mov [symbols_stream],edi
3721 jmp format_defined
3722 format_elf64_exe:
3723 add esi,2
3724 or [format_flags],1
3725 cmp byte [esi],'('
3726 jne elf64_exe_brand_ok
3727 inc esi
3728 cmp byte [esi],'.'
3729 je invalid_value
3730 push edx
3731 call get_byte_value
3732 cmp [value_type],0
3733 jne invalid_use_of_symbol
3734 pop edx
3735 mov [edx+7],al
3736 elf64_exe_brand_ok:
3737 mov [image_base],400000h
3738 and [image_base_high],0
3739 cmp byte [esi],80h
3740 jne elf64_exe_base_ok
3741 lods word [esi]
3742 cmp ah,'('
3743 jne invalid_argument
3744 cmp byte [esi],'.'
3745 je invalid_value
3746 push edx
3747 call get_qword_value
3748 cmp [value_type],0
3749 jne invalid_use_of_symbol
3750 mov [image_base],eax
3751 mov [image_base_high],edx
3752 pop edx
3753 elf64_exe_base_ok:
3754 mov byte [edx+10h],2
3755 mov byte [edx+36h],38h
3756 mov ebx,edi
3757 mov ecx,38h shr 2
3758 cmp [current_pass],0
3759 je init_elf64_segments
3760 imul ecx,[number_of_sections]
3761 init_elf64_segments:
3762 xor eax,eax
3763 rep stos dword [edi]
3764 and [number_of_sections],0
3765 mov byte [ebx],1
3766 mov word [ebx+30h],1000h
3767 mov byte [ebx+4],111b
3768 push edx
3769 mov eax,edi
3770 sub eax,[code_start]
3771 mov [ebx+8],eax
3772 xor edx,edx
3773 xor cl,cl
3774 add eax,[image_base]
3775 adc edx,[image_base_high]
3776 adc cl,0
3777 mov [ebx+10h],eax
3778 mov [ebx+10h+4],edx
3779 mov [ebx+18h],eax
3780 mov [ebx+18h+4],edx
3781 pop ebx
3782 mov [ebx+18h],eax
3783 mov [ebx+18h+4],edx
3784 not eax
3785 not edx
3786 not cl
3787 add eax,1
3788 adc edx,0
3789 adc cl,0
3790 add eax,edi
3791 adc edx,0
3792 adc cl,0
3793 jmp elf_exe_addressing_setup
3794 elf_entry:
3795 lods byte [esi]
3796 cmp al,'('
3797 jne invalid_argument
3798 cmp byte [esi],'.'
3799 je invalid_value
3800 test [format_flags],8
3801 jnz elf64_entry
3802 call get_dword_value
3803 cmp [value_type],0
3804 jne invalid_use_of_symbol
3805 mov edx,[code_start]
3806 mov [edx+18h],eax
3807 jmp instruction_assembled
3808 elf64_entry:
3809 call get_qword_value
3810 cmp [value_type],0
3811 jne invalid_use_of_symbol
3812 mov ebx,[code_start]
3813 mov [ebx+18h],eax
3814 mov [ebx+1Ch],edx
3815 jmp instruction_assembled
3816 elf_segment:
3817 bt [format_flags],0
3818 jnc illegal_instruction
3819 test [format_flags],8
3820 jnz elf64_segment
3821 call close_elf_segment
3822 push eax
3823 call create_addressing_space
3824 mov ebp,ebx
3825 mov ebx,[number_of_sections]
3826 shl ebx,5
3827 add ebx,[code_start]
3828 add ebx,34h
3829 cmp ebx,[symbols_stream]
3830 jb new_elf_segment
3831 mov ebx,[symbols_stream]
3832 sub ebx,20h
3833 push edi
3834 mov edi,ebx
3835 mov ecx,20h shr 2
3836 xor eax,eax
3837 rep stos dword [edi]
3838 pop edi
3839 or [next_pass_needed],-1
3840 new_elf_segment:
3841 mov byte [ebx],1
3842 mov word [ebx+1Ch],1000h
3843 elf_segment_flags:
3844 cmp byte [esi],1Eh
3845 je elf_segment_type
3846 cmp byte [esi],19h
3847 jne elf_segment_flags_ok
3848 lods word [esi]
3849 sub ah,28
3850 jbe invalid_argument
3851 cmp ah,1
3852 je mark_elf_segment_flag
3853 cmp ah,3
3854 ja invalid_argument
3855 xor ah,1
3856 cmp ah,2
3857 je mark_elf_segment_flag
3858 inc ah
3859 mark_elf_segment_flag:
3860 test [ebx+18h],ah
3861 jnz setting_already_specified
3862 or [ebx+18h],ah
3863 jmp elf_segment_flags
3864 elf_segment_type:
3865 cmp byte [ebx],1
3866 jne setting_already_specified
3867 lods word [esi]
3868 mov ecx,[number_of_sections]
3869 jecxz elf_segment_type_ok
3870 mov edx,[code_start]
3871 add edx,34h
3872 scan_elf_segment_types:
3873 cmp edx,[symbols_stream]
3874 jae elf_segment_type_ok
3875 cmp [edx],ah
3876 je data_already_defined
3877 add edx,20h
3878 loop scan_elf_segment_types
3879 elf_segment_type_ok:
3880 mov [ebx],ah
3881 mov word [ebx+1Ch],1
3882 jmp elf_segment_flags
3883 elf_segment_flags_ok:
3884 mov eax,edi
3885 sub eax,[code_start]
3886 mov [ebx+4],eax
3887 pop edx
3888 and eax,0FFFh
3889 add edx,eax
3890 mov [ebx+8],edx
3891 mov [ebx+0Ch],edx
3892 mov eax,edx
3893 xor edx,edx
3894 xor cl,cl
3895 not eax
3896 not edx
3897 not cl
3898 add eax,1
3899 adc edx,0
3900 adc cl,0
3901 add eax,edi
3902 adc edx,0
3903 adc cl,0
3904 elf_segment_addressing_setup:
3905 mov [ds:ebp],eax
3906 mov [ds:ebp+4],edx
3907 mov [ds:ebp+8],cl
3908 inc [number_of_sections]
3909 jmp instruction_assembled
3910 close_elf_segment:
3911 cmp [number_of_sections],0
3912 jne finish_elf_segment
3913 cmp edi,[symbols_stream]
3914 jne first_elf_segment_ok
3915 push edi
3916 mov edi,[code_start]
3917 add edi,34h
3918 mov ecx,20h shr 2
3919 xor eax,eax
3920 rep stos dword [edi]
3921 pop edi
3922 mov eax,[image_base]
3923 ret
3924 first_elf_segment_ok:
3925 inc [number_of_sections]
3926 finish_elf_segment:
3927 mov ebx,[number_of_sections]
3928 dec ebx
3929 shl ebx,5
3930 add ebx,[code_start]
3931 add ebx,34h
3932 mov eax,edi
3933 sub eax,[code_start]
3934 sub eax,[ebx+4]
3935 mov edx,edi
3936 cmp edi,[undefined_data_end]
3937 jne elf_segment_size_ok
3938 mov edi,[undefined_data_start]
3939 elf_segment_size_ok:
3940 mov [ebx+14h],eax
3941 add eax,edi
3942 sub eax,edx
3943 mov [ebx+10h],eax
3944 and [undefined_data_end],0
3945 mov eax,[ebx+8]
3946 cmp byte [ebx],1
3947 jne elf_segment_position_ok
3948 add eax,[ebx+14h]
3949 add eax,0FFFh
3950 elf_segment_position_ok:
3951 and eax,not 0FFFh
3952 ret
3953 elf64_segment:
3954 call close_elf64_segment
3955 push eax edx
3956 call create_addressing_space
3957 mov ebp,ebx
3958 mov ebx,[number_of_sections]
3959 imul ebx,38h
3960 add ebx,[code_start]
3961 add ebx,40h
3962 cmp ebx,[symbols_stream]
3963 jb new_elf64_segment
3964 mov ebx,[symbols_stream]
3965 sub ebx,38h
3966 push edi
3967 mov edi,ebx
3968 mov ecx,38h shr 2
3969 xor eax,eax
3970 rep stos dword [edi]
3971 pop edi
3972 or [next_pass_needed],-1
3973 new_elf64_segment:
3974 mov byte [ebx],1
3975 mov word [ebx+30h],1000h
3976 elf64_segment_flags:
3977 cmp byte [esi],1Eh
3978 je elf64_segment_type
3979 cmp byte [esi],19h
3980 jne elf64_segment_flags_ok
3981 lods word [esi]
3982 sub ah,28
3983 jbe invalid_argument
3984 cmp ah,1
3985 je mark_elf64_segment_flag
3986 cmp ah,3
3987 ja invalid_argument
3988 xor ah,1
3989 cmp ah,2
3990 je mark_elf64_segment_flag
3991 inc ah
3992 mark_elf64_segment_flag:
3993 test [ebx+4],ah
3994 jnz setting_already_specified
3995 or [ebx+4],ah
3996 jmp elf64_segment_flags
3997 elf64_segment_type:
3998 cmp byte [ebx],1
3999 jne setting_already_specified
4000 lods word [esi]
4001 mov ecx,[number_of_sections]
4002 jecxz elf64_segment_type_ok
4003 mov edx,[code_start]
4004 add edx,40h
4005 scan_elf64_segment_types:
4006 cmp edx,[symbols_stream]
4007 jae elf64_segment_type_ok
4008 cmp [edx],ah
4009 je data_already_defined
4010 add edx,38h
4011 loop scan_elf64_segment_types
4012 elf64_segment_type_ok:
4013 mov [ebx],ah
4014 mov word [ebx+30h],1
4015 jmp elf64_segment_flags
4016 elf64_segment_flags_ok:
4017 mov ecx,edi
4018 sub ecx,[code_start]
4019 mov [ebx+8],ecx
4020 pop edx eax
4021 and ecx,0FFFh
4022 add eax,ecx
4023 adc edx,0
4024 mov [ebx+10h],eax
4025 mov [ebx+10h+4],edx
4026 mov [ebx+18h],eax
4027 mov [ebx+18h+4],edx
4028 xor cl,cl
4029 not eax
4030 not edx
4031 not cl
4032 add eax,1
4033 adc edx,0
4034 adc cl,0
4035 add eax,edi
4036 adc edx,0
4037 adc cl,0
4038 jmp elf_segment_addressing_setup
4039 close_elf64_segment:
4040 cmp [number_of_sections],0
4041 jne finish_elf64_segment
4042 cmp edi,[symbols_stream]
4043 jne first_elf64_segment_ok
4044 push edi
4045 mov edi,[code_start]
4046 add edi,40h
4047 mov ecx,38h shr 2
4048 xor eax,eax
4049 rep stos dword [edi]
4050 pop edi
4051 mov eax,[image_base]
4052 mov edx,[image_base_high]
4053 ret
4054 first_elf64_segment_ok:
4055 inc [number_of_sections]
4056 finish_elf64_segment:
4057 mov ebx,[number_of_sections]
4058 dec ebx
4059 imul ebx,38h
4060 add ebx,[code_start]
4061 add ebx,40h
4062 mov eax,edi
4063 sub eax,[code_start]
4064 sub eax,[ebx+8]
4065 mov edx,edi
4066 cmp edi,[undefined_data_end]
4067 jne elf64_segment_size_ok
4068 mov edi,[undefined_data_start]
4069 elf64_segment_size_ok:
4070 mov [ebx+28h],eax
4071 add eax,edi
4072 sub eax,edx
4073 mov [ebx+20h],eax
4074 and [undefined_data_end],0
4075 mov eax,[ebx+10h]
4076 mov edx,[ebx+10h+4]
4077 cmp byte [ebx],1
4078 jne elf64_segment_position_ok
4079 add eax,[ebx+28h]
4080 adc edx,0
4081 add eax,0FFFh
4082 adc edx,0
4083 elf64_segment_position_ok:
4084 and eax,not 0FFFh
4085 ret
4086 close_elf_exe:
4087 test [format_flags],8
4088 jnz close_elf64_exe
4089 call close_elf_segment
4090 mov edx,[code_start]
4091 mov eax,[number_of_sections]
4092 mov byte [edx+1Ch],34h
4093 mov [edx+2Ch],ax
4094 shl eax,5
4095 add eax,edx
4096 add eax,34h
4097 cmp eax,[symbols_stream]
4098 je elf_exe_ok
4099 or [next_pass_needed],-1
4100 elf_exe_ok:
4101 ret
4102 close_elf64_exe:
4103 call close_elf64_segment
4104 mov edx,[code_start]
4105 mov eax,[number_of_sections]
4106 mov byte [edx+20h],40h
4107 mov [edx+38h],ax
4108 imul eax,38h
4109 add eax,edx
4110 add eax,40h
4111 cmp eax,[symbols_stream]
4112 je elf64_exe_ok
4113 or [next_pass_needed],-1
4114 elf64_exe_ok:
4115 ret
0
1 ; flat assembler interface for Unix/libc
2 ; Copyright (c) 1999-2014, Tomasz Grysztar.
3 ; All rights reserved.
4
5 format ELF
6 public main
7
8 macro ccall proc,[arg]
9 { common
10 local size
11 size = 0
12 mov ebp,esp
13 if ~ arg eq
14 forward
15 size = size + 4
16 common
17 sub esp,size
18 end if
19 and esp,-16
20 if ~ arg eq
21 add esp,size
22 reverse
23 pushd arg
24 common
25 end if
26 call proc
27 mov esp,ebp }
28
29 extrn gettimeofday
30
31 section '.text' executable align 16
32
33 main:
34 mov ecx,[esp+4]
35 mov [argc],ecx
36 mov ebx,[esp+8]
37 mov [argv],ebx
38 push ebp
39 mov [stack_frame],esp
40
41 mov [con_handle],1
42 mov esi,_logo
43 call display_string
44
45 call get_params
46 jc information
47
48 call init_memory
49
50 mov esi,_memory_prefix
51 call display_string
52 mov eax,[memory_end]
53 sub eax,[memory_start]
54 add eax,[additional_memory_end]
55 sub eax,[additional_memory]
56 shr eax,10
57 call display_number
58 mov esi,_memory_suffix
59 call display_string
60
61 ccall gettimeofday,buffer,0
62 mov eax,dword [buffer]
63 mov ecx,1000
64 mul ecx
65 mov ebx,eax
66 mov eax,dword [buffer+4]
67 div ecx
68 add eax,ebx
69 mov [start_time],eax
70
71 call preprocessor
72 call parser
73 call assembler
74 call formatter
75
76 call display_user_messages
77 movzx eax,[current_pass]
78 inc eax
79 call display_number
80 mov esi,_passes_suffix
81 call display_string
82 ccall gettimeofday,buffer,0
83 mov eax,dword [buffer]
84 mov ecx,1000
85 mul ecx
86 mov ebx,eax
87 mov eax,dword [buffer+4]
88 div ecx
89 add eax,ebx
90 sub eax,[start_time]
91 jnc time_ok
92 add eax,3600000
93 time_ok:
94 xor edx,edx
95 mov ebx,100
96 div ebx
97 or eax,eax
98 jz display_bytes_count
99 xor edx,edx
100 mov ebx,10
101 div ebx
102 push edx
103 call display_number
104 mov dl,'.'
105 call display_character
106 pop eax
107 call display_number
108 mov esi,_seconds_suffix
109 call display_string
110 display_bytes_count:
111 mov eax,[written_size]
112 call display_number
113 mov esi,_bytes_suffix
114 call display_string
115 xor al,al
116 jmp exit_program
117
118 information:
119 mov esi,_usage
120 call display_string
121 mov al,1
122 jmp exit_program
123
124 get_params:
125 mov [input_file],0
126 mov [output_file],0
127 mov [symbols_file],0
128 mov [memory_setting],0
129 mov [passes_limit],100
130 mov ecx,[argc]
131 mov ebx,[argv]
132 add ebx,4
133 dec ecx
134 jz bad_params
135 get_param:
136 mov esi,[ebx]
137 mov al,[esi]
138 cmp al,'-'
139 je option_param
140 cmp [input_file],0
141 jne get_output_file
142 mov [input_file],esi
143 jmp next_param
144 get_output_file:
145 cmp [output_file],0
146 jne bad_params
147 mov [output_file],esi
148 jmp next_param
149 option_param:
150 inc esi
151 lodsb
152 cmp al,'m'
153 je memory_option
154 cmp al,'M'
155 je memory_option
156 cmp al,'p'
157 je passes_option
158 cmp al,'P'
159 je passes_option
160 cmp al,'s'
161 je symbols_option
162 cmp al,'S'
163 je symbols_option
164 bad_params:
165 stc
166 ret
167 memory_option:
168 cmp byte [esi],0
169 jne get_memory_setting
170 dec ecx
171 jz bad_params
172 add ebx,4
173 mov esi,[ebx]
174 get_memory_setting:
175 call get_option_value
176 or edx,edx
177 jz bad_params
178 cmp edx,1 shl (32-10)
179 jae bad_params
180 mov [memory_setting],edx
181 jmp next_param
182 passes_option:
183 cmp byte [esi],0
184 jne get_passes_setting
185 dec ecx
186 jz bad_params
187 add ebx,4
188 mov esi,[ebx]
189 get_passes_setting:
190 call get_option_value
191 or edx,edx
192 jz bad_params
193 cmp edx,10000h
194 ja bad_params
195 mov [passes_limit],dx
196 next_param:
197 add ebx,4
198 dec ecx
199 jnz get_param
200 cmp [input_file],0
201 je bad_params
202 clc
203 ret
204 symbols_option:
205 cmp byte [esi],0
206 jne get_symbols_setting
207 dec ecx
208 jz bad_params
209 add ebx,4
210 mov esi,[ebx]
211 get_symbols_setting:
212 mov [symbols_file],esi
213 jmp next_param
214 get_option_value:
215 xor eax,eax
216 mov edx,eax
217 get_option_digit:
218 lodsb
219 cmp al,20h
220 je option_value_ok
221 cmp al,0Dh
222 je option_value_ok
223 or al,al
224 jz option_value_ok
225 sub al,30h
226 jc invalid_option_value
227 cmp al,9
228 ja invalid_option_value
229 imul edx,10
230 jo invalid_option_value
231 add edx,eax
232 jc invalid_option_value
233 jmp get_option_digit
234 option_value_ok:
235 dec esi
236 clc
237 ret
238 invalid_option_value:
239 stc
240 ret
241
242 include 'system.inc'
243
244 include '..\version.inc'
245
246 _copyright db 'Copyright (c) 1999-2014, Tomasz Grysztar',0xA,0
247
248 _logo db 'flat assembler version ',VERSION_STRING,0
249 _usage db 0xA
250 db 'usage: fasm <source> [output]',0xA
251 db 'optional settings:',0xA
252 db ' -m <limit> set the limit in kilobytes for the available memory',0Dh,0Ah
253 db ' -p <limit> set the maximum allowed number of passes',0Dh,0Ah
254 db ' -s <file> dump symbolic information for debugging',0Dh,0Ah
255 db 0
256 _memory_prefix db ' (',0
257 _memory_suffix db ' kilobytes memory)',0xA,0
258 _passes_suffix db ' passes, ',0
259 _seconds_suffix db ' seconds, ',0
260 _bytes_suffix db ' bytes.',0xA,0
261
262 include '..\errors.inc'
263 include '..\symbdump.inc'
264 include '..\preproce.inc'
265 include '..\parser.inc'
266 include '..\exprpars.inc'
267 include '..\assemble.inc'
268 include '..\exprcalc.inc'
269 include '..\formats.inc'
270 include '..\x86_64.inc'
271 include '..\avx.inc'
272
273 include '..\tables.inc'
274 include '..\messages.inc'
275
276 section '.bss' writeable align 4
277
278 include '..\variable.inc'
279
280 argc dd ?
281 argv dd ?
282 stack_frame dd ?
283 memory_setting dd ?
284 start_time dd ?
285 timestamp dq ?
286 con_handle dd ?
287 displayed_count dd ?
288 last_displayed db ?
289 character db ?
290
291 buffer rb 1000h
0
1 ; flat assembler interface for Unix/libc
2 ; Copyright (c) 1999-2014, Tomasz Grysztar.
3 ; All rights reserved.
4
5 extrn malloc
6 extrn free
7 extrn getenv
8 extrn fopen
9 extrn fclose
10 extrn fread
11 extrn fwrite
12 extrn fseek
13 extrn ftell
14 extrn time
15 extrn exit
16
17 extrn 'write' as libc_write
18
19 init_memory:
20 mov eax,esp
21 and eax,not 0FFFh
22 add eax,1000h-10000h
23 mov [stack_limit],eax
24 mov ecx,[memory_setting]
25 shl ecx,10
26 jnz allocate_memory
27 mov ecx,1000000h
28 allocate_memory:
29 mov [memory_setting],ecx
30 ccall malloc,ecx
31 or eax,eax
32 jz out_of_memory
33 mov [additional_memory],eax
34 add eax,[memory_setting]
35 mov [memory_end],eax
36 mov eax,[memory_setting]
37 shr eax,2
38 add eax,[additional_memory]
39 mov [additional_memory_end],eax
40 mov [memory_start],eax
41 ret
42
43 exit_program:
44 movzx eax,al
45 push eax
46 ccall free,[additional_memory]
47 pop eax
48 ccall exit,eax
49 mov esp,[stack_frame]
50 pop ebp
51 ret
52
53 get_environment_variable:
54 ccall getenv,esi
55 mov esi,eax
56 or eax,eax
57 jz no_environment_variable
58 copy_variable_value:
59 lodsb
60 cmp edi,[memory_end]
61 jae out_of_memory
62 stosb
63 or al,al
64 jnz copy_variable_value
65 dec edi
66 ret
67 no_environment_variable:
68 stosb
69 dec edi
70 ret
71
72 open:
73 push esi edi ebp
74 call adapt_path
75 ccall fopen,buffer,open_mode
76 pop ebp edi esi
77 or eax,eax
78 jz file_error
79 mov ebx,eax
80 clc
81 ret
82 adapt_path:
83 mov esi,edx
84 mov edi,buffer
85 copy_path:
86 lods byte [esi]
87 cmp al,'\'
88 jne path_char_ok
89 mov al,'/'
90 path_char_ok:
91 stos byte [edi]
92 or al,al
93 jnz copy_path
94 cmp edi,buffer+1000h
95 ja out_of_memory
96 ret
97 create:
98 push esi edi ebp
99 call adapt_path
100 ccall fopen,buffer,create_mode
101 pop ebp edi esi
102 or eax,eax
103 jz file_error
104 mov ebx,eax
105 clc
106 ret
107 close:
108 ccall fclose,ebx
109 ret
110 read:
111 push ebx ecx edx esi edi ebp
112 ccall fread,edx,1,ecx,ebx
113 pop ebp edi esi edx ecx ebx
114 cmp eax,ecx
115 jne file_error
116 clc
117 ret
118 file_error:
119 stc
120 ret
121 write:
122 push ebx ecx edx esi edi ebp
123 ccall fwrite,edx,1,ecx,ebx
124 pop ebp edi esi edx ecx ebx
125 cmp eax,ecx
126 jne file_error
127 clc
128 ret
129 lseek:
130 push ebx
131 movzx eax,al
132 ccall fseek,ebx,edx,eax
133 mov ebx,[esp]
134 ccall ftell,ebx
135 pop ebx
136 ret
137
138 display_string:
139 lodsb
140 or al,al
141 jz string_displayed
142 mov dl,al
143 call display_character
144 jmp display_string
145 string_displayed:
146 ret
147 display_character:
148 mov [character],dl
149 ccall libc_write,[con_handle],character,1
150 ret
151 display_number:
152 push ebx
153 mov ecx,1000000000
154 xor edx,edx
155 xor bl,bl
156 display_loop:
157 div ecx
158 push edx
159 cmp ecx,1
160 je display_digit
161 or bl,bl
162 jnz display_digit
163 or al,al
164 jz digit_ok
165 not bl
166 display_digit:
167 mov dl,al
168 add dl,30h
169 push ebx ecx
170 call display_character
171 pop ecx ebx
172 digit_ok:
173 mov eax,ecx
174 xor edx,edx
175 mov ecx,10
176 div ecx
177 mov ecx,eax
178 pop eax
179 or ecx,ecx
180 jnz display_loop
181 pop ebx
182 ret
183
184 display_user_messages:
185 mov [displayed_count],0
186 call show_display_buffer
187 cmp [displayed_count],0
188 je line_break_ok
189 cmp [last_displayed],0Ah
190 je line_break_ok
191 mov dl,0Ah
192 call display_character
193 line_break_ok:
194 ret
195 display_block:
196 jecxz block_displayed
197 add [displayed_count],ecx
198 mov al,[esi+ecx-1]
199 mov [last_displayed],al
200 display_characters:
201 lodsb
202 mov dl,al
203 push ecx esi
204 call display_character
205 pop esi ecx
206 loop display_characters
207 block_displayed:
208 ret
209
210 fatal_error:
211 mov [con_handle],2
212 mov esi,error_prefix
213 call display_string
214 pop esi
215 call display_string
216 mov esi,error_suffix
217 call display_string
218 mov al,0FFh
219 jmp exit_program
220 assembler_error:
221 mov [con_handle],2
222 call display_user_messages
223 push dword 0
224 mov ebx,[current_line]
225 get_error_lines:
226 mov eax,[ebx]
227 cmp byte [eax],0
228 je get_next_error_line
229 push ebx
230 test byte [ebx+7],80h
231 jz display_error_line
232 mov edx,ebx
233 find_definition_origin:
234 mov edx,[edx+12]
235 test byte [edx+7],80h
236 jnz find_definition_origin
237 push edx
238 get_next_error_line:
239 mov ebx,[ebx+8]
240 jmp get_error_lines
241 display_error_line:
242 mov esi,[ebx]
243 call display_string
244 mov esi,line_number_start
245 call display_string
246 mov eax,[ebx+4]
247 and eax,7FFFFFFFh
248 call display_number
249 mov dl,']'
250 call display_character
251 pop esi
252 cmp ebx,esi
253 je line_number_ok
254 mov dl,20h
255 call display_character
256 push esi
257 mov esi,[esi]
258 movzx ecx,byte [esi]
259 inc esi
260 call display_block
261 mov esi,line_number_start
262 call display_string
263 pop esi
264 mov eax,[esi+4]
265 and eax,7FFFFFFFh
266 call display_number
267 mov dl,']'
268 call display_character
269 line_number_ok:
270 mov esi,line_data_start
271 call display_string
272 mov esi,ebx
273 mov edx,[esi]
274 call open
275 mov al,2
276 xor edx,edx
277 call lseek
278 mov edx,[esi+8]
279 sub eax,edx
280 jz line_data_displayed
281 push eax
282 xor al,al
283 call lseek
284 mov ecx,[esp]
285 mov edx,[additional_memory]
286 lea eax,[edx+ecx]
287 cmp eax,[additional_memory_end]
288 ja out_of_memory
289 call read
290 call close
291 pop ecx
292 mov esi,[additional_memory]
293 get_line_data:
294 mov al,[esi]
295 cmp al,0Ah
296 je display_line_data
297 cmp al,0Dh
298 je display_line_data
299 cmp al,1Ah
300 je display_line_data
301 or al,al
302 jz display_line_data
303 inc esi
304 loop get_line_data
305 display_line_data:
306 mov ecx,esi
307 mov esi,[additional_memory]
308 sub ecx,esi
309 call display_block
310 line_data_displayed:
311 mov esi,lf
312 call display_string
313 pop ebx
314 or ebx,ebx
315 jnz display_error_line
316 mov esi,error_prefix
317 call display_string
318 pop esi
319 call display_string
320 mov esi,error_suffix
321 call display_string
322 mov al,2
323 jmp exit_program
324
325 make_timestamp:
326 ccall time,timestamp
327 mov eax,dword [timestamp]
328 mov edx,dword [timestamp+4]
329 ret
330
331 open_mode db 'r',0
332 create_mode db 'w',0
333
334 error_prefix db 'error: ',0
335 error_suffix db '.'
336 lf db 0xA,0
337 line_number_start db ' [',0
338 line_data_start db ':',0xA,0
0
1 ; flat assembler core
2 ; Copyright (c) 1999-2014, Tomasz Grysztar.
3 ; All rights reserved.
4
5 _out_of_memory db 'out of memory',0
6 _stack_overflow db 'out of stack space',0
7 _main_file_not_found db 'source file not found',0
8 _unexpected_end_of_file db 'unexpected end of file',0
9 _code_cannot_be_generated db 'code cannot be generated',0
10 _format_limitations_exceeded db 'format limitations exceeded',0
11 _invalid_definition db 'invalid definition provided',0
12 _write_failed db 'write failed',0
13 _file_not_found db 'file not found',0
14 _error_reading_file db 'error reading file',0
15 _invalid_file_format db 'invalid file format',0
16 _invalid_macro_arguments db 'invalid macro arguments',0
17 _incomplete_macro db 'incomplete macro',0
18 _unexpected_characters db 'unexpected characters',0
19 _invalid_argument db 'invalid argument',0
20 _illegal_instruction db 'illegal instruction',0
21 _invalid_operand db 'invalid operand',0
22 _invalid_operand_size db 'invalid size of operand',0
23 _operand_size_not_specified db 'operand size not specified',0
24 _operand_sizes_do_not_match db 'operand sizes do not match',0
25 _invalid_address_size db 'invalid size of address value',0
26 _address_sizes_do_not_agree db 'address sizes do not agree',0
27 _disallowed_combination_of_registers db 'disallowed combination of registers',0
28 _long_immediate_not_encodable db 'not encodable with long immediate',0
29 _relative_jump_out_of_range db 'relative jump out of range',0
30 _invalid_expression db 'invalid expression',0
31 _invalid_address db 'invalid address',0
32 _invalid_value db 'invalid value',0
33 _value_out_of_range db 'value out of range',0
34 _undefined_symbol db 'undefined symbol',0
35 _symbol_out_of_scope_1 db 'symbol',0
36 _symbol_out_of_scope_2 db 'out of scope',0
37 _invalid_use_of_symbol db 'invalid use of symbol',0
38 _name_too_long db 'name too long',0
39 _invalid_name db 'invalid name',0
40 _reserved_word_used_as_symbol db 'reserved word used as symbol',0
41 _symbol_already_defined db 'symbol already defined',0
42 _missing_end_quote db 'missing end quote',0
43 _missing_end_directive db 'missing end directive',0
44 _unexpected_instruction db 'unexpected instruction',0
45 _extra_characters_on_line db 'extra characters on line',0
46 _section_not_aligned_enough db 'section is not aligned enough',0
47 _setting_already_specified db 'setting already specified',0
48 _data_already_defined db 'data already defined',0
49 _too_many_repeats db 'too many repeats',0
50 _invoked_error db 'error directive encountered in source file',0
51 _assertion_failed db 'assertion failed',0
0
1 ; flat assembler core
2 ; Copyright (c) 1999-2014, Tomasz Grysztar.
3 ; All rights reserved.
4
5 parser:
6 mov eax,[memory_end]
7 mov [labels_list],eax
8 mov eax,[additional_memory]
9 mov [free_additional_memory],eax
10 xor eax,eax
11 mov [current_locals_prefix],eax
12 mov [anonymous_reverse],eax
13 mov [anonymous_forward],eax
14 mov [hash_tree],eax
15 mov [blocks_stack],eax
16 mov [parsed_lines],eax
17 mov esi,[memory_start]
18 mov edi,[source_start]
19 parser_loop:
20 mov [current_line],esi
21 lea eax,[edi+100h]
22 cmp eax,[labels_list]
23 jae out_of_memory
24 cmp byte [esi+16],0
25 je empty_line
26 cmp byte [esi+16],3Bh
27 je empty_line
28 mov al,0Fh
29 stos byte [edi]
30 mov eax,esi
31 stos dword [edi]
32 inc [parsed_lines]
33 add esi,16
34 parse_line:
35 mov [formatter_symbols_allowed],0
36 cmp byte [esi],1Ah
37 jne empty_instruction
38 push edi
39 add esi,2
40 movzx ecx,byte [esi-1]
41 cmp byte [esi+ecx],':'
42 je simple_label
43 cmp byte [esi+ecx],'='
44 je constant_label
45 call get_instruction
46 jnc main_instruction_identified
47 cmp byte [esi+ecx],1Ah
48 jne no_data_label
49 push esi ecx
50 lea esi,[esi+ecx+2]
51 movzx ecx,byte [esi-1]
52 call get_data_directive
53 jnc data_label
54 pop ecx esi
55 no_data_label:
56 call get_data_directive
57 jnc main_instruction_identified
58 pop edi
59 sub esi,2
60 xor bx,bx
61 call parse_line_contents
62 jmp parse_next_line
63 simple_label:
64 pop edi
65 call identify_label
66 cmp byte [esi+1],':'
67 je block_label
68 mov byte [edi],2
69 inc edi
70 stos dword [edi]
71 inc esi
72 xor al,al
73 stos byte [edi]
74 jmp parse_line
75 block_label:
76 mov byte [edi],4
77 inc edi
78 stos dword [edi]
79 add esi,2
80 jmp parse_line
81 constant_label:
82 pop edi
83 call get_label_id
84 mov byte [edi],3
85 inc edi
86 stos dword [edi]
87 xor al,al
88 stos byte [edi]
89 inc esi
90 xor bx,bx
91 call parse_line_contents
92 jmp parse_next_line
93 data_label:
94 pop ecx edx
95 pop edi
96 push eax ebx esi
97 mov esi,edx
98 movzx ecx,byte [esi-1]
99 call identify_label
100 mov byte [edi],2
101 inc edi
102 stos dword [edi]
103 pop esi ebx eax
104 stos byte [edi]
105 push edi
106 main_instruction_identified:
107 pop edi
108 mov dl,al
109 mov al,1
110 stos byte [edi]
111 mov ax,bx
112 stos word [edi]
113 mov al,dl
114 stos byte [edi]
115 cmp bx,if_directive-instruction_handler
116 je parse_block
117 cmp bx,repeat_directive-instruction_handler
118 je parse_block
119 cmp bx,while_directive-instruction_handler
120 je parse_block
121 cmp bx,end_directive-instruction_handler
122 je parse_end_directive
123 cmp bx,else_directive-instruction_handler
124 je parse_else
125 cmp bx,assert_directive-instruction_handler
126 je parse_assert
127 common_parse:
128 call parse_line_contents
129 jmp parse_next_line
130 empty_instruction:
131 lods byte [esi]
132 or al,al
133 jz parse_next_line
134 cmp al,':'
135 je invalid_name
136 dec esi
137 mov [parenthesis_stack],0
138 call parse_argument
139 jmp parse_next_line
140 empty_line:
141 add esi,16
142 skip_rest_of_line:
143 call skip_foreign_line
144 parse_next_line:
145 cmp esi,[source_start]
146 jb parser_loop
147 source_parsed:
148 cmp [blocks_stack],0
149 je blocks_stack_ok
150 pop eax
151 pop [current_line]
152 jmp missing_end_directive
153 blocks_stack_ok:
154 xor al,al
155 stos byte [edi]
156 add edi,0Fh
157 and edi,not 0Fh
158 mov [code_start],edi
159 ret
160 parse_block:
161 mov eax,esp
162 sub eax,100h
163 jc stack_overflow
164 cmp eax,[stack_limit]
165 jb stack_overflow
166 push [current_line]
167 mov ax,bx
168 shl eax,16
169 push eax
170 inc [blocks_stack]
171 cmp bx,if_directive-instruction_handler
172 je parse_if
173 cmp bx,while_directive-instruction_handler
174 je parse_while
175 call parse_line_contents
176 jmp parse_next_line
177 parse_end_directive:
178 cmp byte [esi],1Ah
179 jne common_parse
180 push edi
181 inc esi
182 movzx ecx,byte [esi]
183 inc esi
184 call get_instruction
185 pop edi
186 jnc parse_end_block
187 sub esi,2
188 jmp common_parse
189 parse_end_block:
190 mov dl,al
191 mov al,1
192 stos byte [edi]
193 mov ax,bx
194 stos word [edi]
195 mov al,dl
196 stos byte [edi]
197 lods byte [esi]
198 or al,al
199 jnz extra_characters_on_line
200 cmp bx,if_directive-instruction_handler
201 je close_parsing_block
202 cmp bx,repeat_directive-instruction_handler
203 je close_parsing_block
204 cmp bx,while_directive-instruction_handler
205 je close_parsing_block
206 jmp parse_next_line
207 close_parsing_block:
208 cmp [blocks_stack],0
209 je unexpected_instruction
210 cmp bx,[esp+2]
211 jne unexpected_instruction
212 dec [blocks_stack]
213 pop eax edx
214 cmp bx,if_directive-instruction_handler
215 jne parse_next_line
216 test al,1100b
217 jz parse_next_line
218 test al,10000b
219 jnz parse_next_line
220 sub edi,8
221 jmp parse_next_line
222 parse_if:
223 push edi
224 call parse_line_contents
225 xor al,al
226 stos byte [edi]
227 xchg esi,[esp]
228 mov edi,esi
229 call preevaluate_logical_expression
230 pop esi
231 cmp al,'0'
232 je parse_false_condition_block
233 cmp al,'1'
234 je parse_true_condition_block
235 or byte [esp],10000b
236 jmp parse_next_line
237 parse_while:
238 push edi
239 call parse_line_contents
240 xor al,al
241 stos byte [edi]
242 xchg esi,[esp]
243 mov edi,esi
244 call preevaluate_logical_expression
245 pop esi
246 cmp al,'0'
247 je parse_false_condition_block
248 cmp al,'1'
249 jne parse_next_line
250 stos byte [edi]
251 jmp parse_next_line
252 parse_false_condition_block:
253 or byte [esp],1
254 sub edi,4
255 jmp skip_parsing
256 parse_true_condition_block:
257 or byte [esp],100b
258 sub edi,4
259 jmp parse_next_line
260 parse_else:
261 cmp [blocks_stack],0
262 je unexpected_instruction
263 cmp word [esp+2],if_directive-instruction_handler
264 jne unexpected_instruction
265 lods byte [esi]
266 or al,al
267 jz parse_pure_else
268 cmp al,1Ah
269 jne extra_characters_on_line
270 push edi
271 movzx ecx,byte [esi]
272 inc esi
273 call get_instruction
274 jc extra_characters_on_line
275 pop edi
276 cmp bx,if_directive-instruction_handler
277 jne extra_characters_on_line
278 test byte [esp],100b
279 jnz skip_true_condition_else
280 mov dl,al
281 mov al,1
282 stos byte [edi]
283 mov ax,bx
284 stos word [edi]
285 mov al,dl
286 stos byte [edi]
287 jmp parse_if
288 parse_assert:
289 push edi
290 call parse_line_contents
291 xor al,al
292 stos byte [edi]
293 xchg esi,[esp]
294 mov edi,esi
295 call preevaluate_logical_expression
296 pop esi
297 or al,al
298 jz parse_next_line
299 stos byte [edi]
300 jmp parse_next_line
301 skip_true_condition_else:
302 sub edi,4
303 or byte [esp],1
304 jmp skip_parsing_contents
305 parse_pure_else:
306 bts dword [esp],1
307 jc unexpected_instruction
308 test byte [esp],100b
309 jz parse_next_line
310 sub edi,4
311 or byte [esp],1
312 jmp skip_parsing
313 skip_parsing:
314 cmp esi,[source_start]
315 jae source_parsed
316 mov [current_line],esi
317 add esi,16
318 skip_parsing_line:
319 cmp byte [esi],1Ah
320 jne skip_parsing_contents
321 inc esi
322 movzx ecx,byte [esi]
323 inc esi
324 cmp byte [esi+ecx],':'
325 je skip_parsing_label
326 push edi
327 call get_instruction
328 pop edi
329 jnc skip_parsing_instruction
330 add esi,ecx
331 jmp skip_parsing_contents
332 skip_parsing_label:
333 lea esi,[esi+ecx+1]
334 jmp skip_parsing_line
335 skip_parsing_instruction:
336 cmp bx,if_directive-instruction_handler
337 je skip_parsing_block
338 cmp bx,repeat_directive-instruction_handler
339 je skip_parsing_block
340 cmp bx,while_directive-instruction_handler
341 je skip_parsing_block
342 cmp bx,end_directive-instruction_handler
343 je skip_parsing_end_directive
344 cmp bx,else_directive-instruction_handler
345 je skip_parsing_else
346 skip_parsing_contents:
347 lods byte [esi]
348 or al,al
349 jz skip_parsing
350 cmp al,1Ah
351 je skip_parsing_symbol
352 cmp al,3Bh
353 je skip_parsing_symbol
354 cmp al,22h
355 je skip_parsing_string
356 jmp skip_parsing_contents
357 skip_parsing_symbol:
358 lods byte [esi]
359 movzx eax,al
360 add esi,eax
361 jmp skip_parsing_contents
362 skip_parsing_string:
363 lods dword [esi]
364 add esi,eax
365 jmp skip_parsing_contents
366 skip_parsing_block:
367 mov eax,esp
368 sub eax,100h
369 jc stack_overflow
370 cmp eax,[stack_limit]
371 jb stack_overflow
372 push [current_line]
373 mov ax,bx
374 shl eax,16
375 push eax
376 inc [blocks_stack]
377 jmp skip_parsing_contents
378 skip_parsing_end_directive:
379 cmp byte [esi],1Ah
380 jne skip_parsing_contents
381 push edi
382 inc esi
383 movzx ecx,byte [esi]
384 inc esi
385 call get_instruction
386 pop edi
387 jnc skip_parsing_end_block
388 add esi,ecx
389 jmp skip_parsing_contents
390 skip_parsing_end_block:
391 lods byte [esi]
392 or al,al
393 jnz extra_characters_on_line
394 cmp bx,if_directive-instruction_handler
395 je close_skip_parsing_block
396 cmp bx,repeat_directive-instruction_handler
397 je close_skip_parsing_block
398 cmp bx,while_directive-instruction_handler
399 je close_skip_parsing_block
400 jmp skip_parsing
401 close_skip_parsing_block:
402 cmp [blocks_stack],0
403 je unexpected_instruction
404 cmp bx,[esp+2]
405 jne unexpected_instruction
406 dec [blocks_stack]
407 pop eax edx
408 test al,1
409 jz skip_parsing
410 cmp bx,if_directive-instruction_handler
411 jne parse_next_line
412 test al,10000b
413 jz parse_next_line
414 mov al,0Fh
415 stos byte [edi]
416 mov eax,[current_line]
417 stos dword [edi]
418 inc [parsed_lines]
419 mov eax,1 + (end_directive-instruction_handler) shl 8
420 stos dword [edi]
421 mov eax,1 + (if_directive-instruction_handler) shl 8
422 stos dword [edi]
423 jmp parse_next_line
424 skip_parsing_else:
425 cmp [blocks_stack],0
426 je unexpected_instruction
427 cmp word [esp+2],if_directive-instruction_handler
428 jne unexpected_instruction
429 lods byte [esi]
430 or al,al
431 jz skip_parsing_pure_else
432 cmp al,1Ah
433 jne extra_characters_on_line
434 push edi
435 movzx ecx,byte [esi]
436 inc esi
437 call get_instruction
438 jc extra_characters_on_line
439 pop edi
440 cmp bx,if_directive-instruction_handler
441 jne extra_characters_on_line
442 mov al,[esp]
443 test al,1
444 jz skip_parsing_contents
445 test al,100b
446 jnz skip_parsing_contents
447 test al,10000b
448 jnz parse_else_if
449 xor al,al
450 mov [esp],al
451 mov al,0Fh
452 stos byte [edi]
453 mov eax,[current_line]
454 stos dword [edi]
455 inc [parsed_lines]
456 parse_else_if:
457 mov eax,1 + (if_directive-instruction_handler) shl 8
458 stos dword [edi]
459 jmp parse_if
460 skip_parsing_pure_else:
461 bts dword [esp],1
462 jc unexpected_instruction
463 mov al,[esp]
464 test al,1
465 jz skip_parsing
466 test al,100b
467 jnz skip_parsing
468 and al,not 1
469 or al,1000b
470 mov [esp],al
471 jmp parse_next_line
472
473 parse_line_contents:
474 mov [parenthesis_stack],0
475 parse_instruction_arguments:
476 cmp bx,prefix_instruction-instruction_handler
477 je allow_embedded_instruction
478 cmp bx,times_directive-instruction_handler
479 je parse_times_directive
480 cmp bx,end_directive-instruction_handler
481 je allow_embedded_instruction
482 cmp bx,label_directive-instruction_handler
483 je parse_label_directive
484 cmp bx,segment_directive-instruction_handler
485 je parse_segment_directive
486 cmp bx,load_directive-instruction_handler
487 je parse_load_directive
488 cmp bx,extrn_directive-instruction_handler
489 je parse_extrn_directive
490 cmp bx,public_directive-instruction_handler
491 je parse_public_directive
492 cmp bx,section_directive-instruction_handler
493 je parse_formatter_argument
494 cmp bx,format_directive-instruction_handler
495 je parse_formatter_argument
496 cmp bx,data_directive-instruction_handler
497 je parse_formatter_argument
498 jmp parse_argument
499 parse_formatter_argument:
500 or [formatter_symbols_allowed],-1
501 parse_argument:
502 lea eax,[edi+100h]
503 cmp eax,[labels_list]
504 jae out_of_memory
505 lods byte [esi]
506 cmp al,':'
507 je instruction_separator
508 cmp al,','
509 je separator
510 cmp al,'='
511 je expression_comparator
512 cmp al,'|'
513 je separator
514 cmp al,'&'
515 je separator
516 cmp al,'~'
517 je separator
518 cmp al,'>'
519 je greater
520 cmp al,'<'
521 je less
522 cmp al,')'
523 je close_parenthesis
524 or al,al
525 jz contents_parsed
526 cmp al,'['
527 je address_argument
528 cmp al,']'
529 je separator
530 cmp al,'{'
531 je unallowed_character
532 cmp al,'}'
533 je unallowed_character
534 cmp al,'#'
535 je unallowed_character
536 cmp al,'`'
537 je unallowed_character
538 cmp al,3Bh
539 je foreign_argument
540 dec esi
541 cmp al,1Ah
542 jne expression_argument
543 push edi
544 mov edi,directive_operators
545 call get_operator
546 or al,al
547 jnz operator_argument
548 inc esi
549 movzx ecx,byte [esi]
550 inc esi
551 call get_symbol
552 jnc symbol_argument
553 cmp ecx,1
554 jne check_argument
555 cmp byte [esi],'?'
556 jne check_argument
557 pop edi
558 movs byte [edi],[esi]
559 jmp argument_parsed
560 foreign_argument:
561 dec esi
562 call skip_foreign_line
563 jmp contents_parsed
564 symbol_argument:
565 pop edi
566 stos word [edi]
567 jmp argument_parsed
568 operator_argument:
569 pop edi
570 cmp al,85h
571 je ptr_argument
572 stos byte [edi]
573 cmp al,80h
574 je forced_multipart_expression
575 cmp al,8Ch
576 je forced_expression
577 cmp al,81h
578 je forced_parenthesis
579 cmp al,82h
580 je parse_from_operator
581 cmp al,89h
582 je parse_label_operator
583 cmp al,0F8h
584 je forced_expression
585 jmp argument_parsed
586 instruction_separator:
587 stos byte [edi]
588 allow_embedded_instruction:
589 cmp byte [esi],1Ah
590 jne parse_argument
591 push edi
592 inc esi
593 movzx ecx,byte [esi]
594 inc esi
595 call get_instruction
596 jnc embedded_instruction
597 call get_data_directive
598 jnc embedded_instruction
599 pop edi
600 sub esi,2
601 jmp parse_argument
602 embedded_instruction:
603 pop edi
604 mov dl,al
605 mov al,1
606 stos byte [edi]
607 mov ax,bx
608 stos word [edi]
609 mov al,dl
610 stos byte [edi]
611 jmp parse_instruction_arguments
612 parse_times_directive:
613 mov al,'('
614 stos byte [edi]
615 call convert_expression
616 mov al,')'
617 stos byte [edi]
618 cmp byte [esi],':'
619 jne allow_embedded_instruction
620 movs byte [edi],[esi]
621 jmp allow_embedded_instruction
622 parse_segment_directive:
623 or [formatter_symbols_allowed],-1
624 parse_label_directive:
625 cmp byte [esi],1Ah
626 jne argument_parsed
627 push esi
628 inc esi
629 movzx ecx,byte [esi]
630 inc esi
631 call identify_label
632 pop ebx
633 cmp eax,0Fh
634 je non_label_identified
635 mov byte [edi],2
636 inc edi
637 stos dword [edi]
638 xor al,al
639 stos byte [edi]
640 jmp argument_parsed
641 non_label_identified:
642 mov esi,ebx
643 jmp argument_parsed
644 parse_load_directive:
645 cmp byte [esi],1Ah
646 jne argument_parsed
647 push esi
648 inc esi
649 movzx ecx,byte [esi]
650 inc esi
651 call get_label_id
652 pop ebx
653 cmp eax,0Fh
654 je non_label_identified
655 mov byte [edi],2
656 inc edi
657 stos dword [edi]
658 xor al,al
659 stos byte [edi]
660 jmp argument_parsed
661 parse_public_directive:
662 cmp byte [esi],1Ah
663 jne parse_argument
664 inc esi
665 push esi
666 movzx ecx,byte [esi]
667 inc esi
668 push esi ecx
669 push edi
670 or [formatter_symbols_allowed],-1
671 call get_symbol
672 mov [formatter_symbols_allowed],0
673 pop edi
674 jc parse_public_label
675 cmp al,1Dh
676 jne parse_public_label
677 add esp,12
678 stos word [edi]
679 jmp parse_public_directive
680 parse_public_label:
681 pop ecx esi
682 mov al,2
683 stos byte [edi]
684 call get_label_id
685 stos dword [edi]
686 mov ax,8600h
687 stos word [edi]
688 pop ebx
689 push ebx esi edi
690 mov edi,directive_operators
691 call get_operator
692 pop edi edx ebx
693 cmp al,86h
694 je argument_parsed
695 mov esi,edx
696 xchg esi,ebx
697 movzx ecx,byte [esi]
698 inc esi
699 mov ax,'('
700 stos word [edi]
701 mov eax,ecx
702 stos dword [edi]
703 rep movs byte [edi],[esi]
704 xor al,al
705 stos byte [edi]
706 xchg esi,ebx
707 jmp argument_parsed
708 parse_extrn_directive:
709 cmp byte [esi],22h
710 je parse_quoted_extrn
711 cmp byte [esi],1Ah
712 jne parse_argument
713 push esi
714 movzx ecx,byte [esi+1]
715 add esi,2
716 mov ax,'('
717 stos word [edi]
718 mov eax,ecx
719 stos dword [edi]
720 rep movs byte [edi],[esi]
721 mov ax,8600h
722 stos word [edi]
723 pop esi
724 parse_label_operator:
725 cmp byte [esi],1Ah
726 jne argument_parsed
727 inc esi
728 movzx ecx,byte [esi]
729 inc esi
730 mov al,2
731 stos byte [edi]
732 call get_label_id
733 stos dword [edi]
734 xor al,al
735 stos byte [edi]
736 jmp argument_parsed
737 parse_from_operator:
738 cmp byte [esi],22h
739 jne forced_multipart_expression
740 jmp argument_parsed
741 parse_quoted_extrn:
742 inc esi
743 mov ax,'('
744 stos word [edi]
745 lods dword [esi]
746 mov ecx,eax
747 stos dword [edi]
748 rep movs byte [edi],[esi]
749 xor al,al
750 stos byte [edi]
751 push esi edi
752 mov edi,directive_operators
753 call get_operator
754 mov edx,esi
755 pop edi esi
756 cmp al,86h
757 jne argument_parsed
758 stos byte [edi]
759 mov esi,edx
760 jmp parse_label_operator
761 ptr_argument:
762 call parse_address
763 jmp address_parsed
764 check_argument:
765 push esi ecx
766 sub esi,2
767 mov edi,single_operand_operators
768 call get_operator
769 pop ecx esi
770 or al,al
771 jnz not_instruction
772 call get_instruction
773 jnc embedded_instruction
774 call get_data_directive
775 jnc embedded_instruction
776 not_instruction:
777 pop edi
778 sub esi,2
779 expression_argument:
780 cmp byte [esi],22h
781 jne not_string
782 mov eax,[esi+1]
783 lea ebx,[esi+5+eax]
784 push ebx ecx esi edi
785 call parse_expression
786 pop eax edx ecx ebx
787 cmp esi,ebx
788 jne expression_argument_parsed
789 mov edi,eax
790 mov esi,edx
791 string_argument:
792 inc esi
793 mov ax,'('
794 stos word [edi]
795 lods dword [esi]
796 mov ecx,eax
797 stos dword [edi]
798 shr ecx,1
799 jnc string_movsb_ok
800 movs byte [edi],[esi]
801 string_movsb_ok:
802 shr ecx,1
803 jnc string_movsw_ok
804 movs word [edi],[esi]
805 string_movsw_ok:
806 rep movs dword [edi],[esi]
807 xor al,al
808 stos byte [edi]
809 jmp expression_argument_parsed
810 parse_expression:
811 mov al,'('
812 stos byte [edi]
813 call convert_expression
814 mov al,')'
815 stos byte [edi]
816 ret
817 not_string:
818 cmp byte [esi],'('
819 jne expression
820 mov eax,esp
821 sub eax,100h
822 jc stack_overflow
823 cmp eax,[stack_limit]
824 jb stack_overflow
825 push esi edi
826 inc esi
827 mov al,'{'
828 stos byte [edi]
829 inc [parenthesis_stack]
830 jmp parse_argument
831 expression_comparator:
832 stos byte [edi]
833 jmp forced_expression
834 greater:
835 cmp byte [esi],'='
836 jne separator
837 inc esi
838 mov al,0F2h
839 jmp separator
840 less:
841 cmp byte [edi-1],0F6h
842 je separator
843 cmp byte [esi],'>'
844 je not_equal
845 cmp byte [esi],'='
846 jne separator
847 inc esi
848 mov al,0F3h
849 jmp separator
850 not_equal:
851 inc esi
852 mov al,0F1h
853 jmp expression_comparator
854 expression:
855 call parse_expression
856 jmp expression_argument_parsed
857 forced_expression:
858 xor al,al
859 xchg al,[formatter_symbols_allowed]
860 push eax
861 call parse_expression
862 forced_expression_parsed:
863 pop eax
864 mov [formatter_symbols_allowed],al
865 jmp argument_parsed
866 forced_multipart_expression:
867 xor al,al
868 xchg al,[formatter_symbols_allowed]
869 push eax
870 call parse_expression
871 cmp byte [esi],':'
872 jne forced_expression_parsed
873 movs byte [edi],[esi]
874 call parse_expression
875 jmp forced_expression_parsed
876 address_argument:
877 call parse_address
878 lods byte [esi]
879 cmp al,']'
880 je address_parsed
881 dec esi
882 mov al,')'
883 stos byte [edi]
884 jmp argument_parsed
885 address_parsed:
886 mov al,']'
887 stos byte [edi]
888 jmp argument_parsed
889 parse_address:
890 mov al,'['
891 stos byte [edi]
892 cmp word [esi],021Ah
893 jne convert_address
894 push esi
895 add esi,4
896 lea ebx,[esi+1]
897 cmp byte [esi],':'
898 pop esi
899 jne convert_address
900 add esi,2
901 mov ecx,2
902 push ebx edi
903 call get_symbol
904 pop edi esi
905 jc unknown_segment_prefix
906 cmp al,10h
907 jne unknown_segment_prefix
908 mov al,ah
909 and ah,11110000b
910 cmp ah,60h
911 jne unknown_segment_prefix
912 stos byte [edi]
913 jmp convert_address
914 unknown_segment_prefix:
915 sub esi,5
916 convert_address:
917 push edi
918 mov edi,address_sizes
919 call get_operator
920 pop edi
921 or al,al
922 jz convert_expression
923 add al,70h
924 stos byte [edi]
925 jmp convert_expression
926 forced_parenthesis:
927 cmp byte [esi],'('
928 jne argument_parsed
929 inc esi
930 mov al,'{'
931 jmp separator
932 unallowed_character:
933 mov al,0FFh
934 jmp separator
935 close_parenthesis:
936 mov al,'}'
937 separator:
938 stos byte [edi]
939 argument_parsed:
940 cmp [parenthesis_stack],0
941 je parse_argument
942 dec [parenthesis_stack]
943 add esp,8
944 jmp argument_parsed
945 expression_argument_parsed:
946 cmp [parenthesis_stack],0
947 je parse_argument
948 cmp byte [esi],')'
949 jne argument_parsed
950 dec [parenthesis_stack]
951 pop edi esi
952 jmp expression
953 contents_parsed:
954 cmp [parenthesis_stack],0
955 je contents_ok
956 dec [parenthesis_stack]
957 add esp,8
958 jmp contents_parsed
959 contents_ok:
960 ret
961
962 identify_label:
963 cmp byte [esi],'.'
964 je local_label_name
965 call get_label_id
966 cmp eax,10h
967 jb label_identified
968 or ebx,ebx
969 jz anonymous_label_name
970 dec ebx
971 mov [current_locals_prefix],ebx
972 label_identified:
973 ret
974 anonymous_label_name:
975 cmp byte [esi-1],'@'
976 je anonymous_label_name_ok
977 mov eax,0Fh
978 anonymous_label_name_ok:
979 ret
980 local_label_name:
981 call get_label_id
982 ret
983
984 get_operator:
985 cmp byte [esi],1Ah
986 jne get_simple_operator
987 mov edx,esi
988 push ebp
989 inc esi
990 lods byte [esi]
991 movzx ebp,al
992 push edi
993 mov ecx,ebp
994 call lower_case
995 pop edi
996 check_operator:
997 mov esi,converted
998 movzx ecx,byte [edi]
999 jecxz no_operator
1000 inc edi
1001 mov ebx,edi
1002 add ebx,ecx
1003 cmp ecx,ebp
1004 jne next_operator
1005 repe cmps byte [esi],[edi]
1006 je operator_found
1007 jb no_operator
1008 next_operator:
1009 mov edi,ebx
1010 inc edi
1011 jmp check_operator
1012 no_operator:
1013 mov esi,edx
1014 mov ecx,ebp
1015 pop ebp
1016 no_simple_operator:
1017 xor al,al
1018 ret
1019 operator_found:
1020 lea esi,[edx+2+ebp]
1021 mov ecx,ebp
1022 pop ebp
1023 mov al,[edi]
1024 ret
1025 get_simple_operator:
1026 mov al,[esi]
1027 cmp al,22h
1028 je no_simple_operator
1029 simple_operator:
1030 cmp byte [edi],1
1031 jb no_simple_operator
1032 ja simple_next_operator
1033 cmp al,[edi+1]
1034 je simple_operator_found
1035 simple_next_operator:
1036 movzx ecx,byte [edi]
1037 lea edi,[edi+1+ecx+1]
1038 jmp simple_operator
1039 simple_operator_found:
1040 inc esi
1041 mov al,[edi+2]
1042 ret
1043
1044 get_symbol:
1045 push esi
1046 mov ebp,ecx
1047 call lower_case
1048 mov ecx,ebp
1049 cmp cl,11
1050 ja no_symbol
1051 sub cl,2
1052 jc no_symbol
1053 movzx ebx,word [symbols+ecx*4]
1054 add ebx,symbols
1055 movzx edx,word [symbols+ecx*4+2]
1056 scan_symbols:
1057 or edx,edx
1058 jz no_symbol
1059 mov eax,edx
1060 shr eax,1
1061 lea edi,[ebp+2]
1062 imul eax,edi
1063 lea edi,[ebx+eax]
1064 mov esi,converted
1065 mov ecx,ebp
1066 repe cmps byte [esi],[edi]
1067 ja symbols_up
1068 jb symbols_down
1069 mov ax,[edi]
1070 cmp al,18h
1071 jb symbol_ok
1072 cmp [formatter_symbols_allowed],0
1073 je no_symbol
1074 symbol_ok:
1075 pop esi
1076 add esi,ebp
1077 clc
1078 ret
1079 no_symbol:
1080 pop esi
1081 mov ecx,ebp
1082 stc
1083 ret
1084 symbols_down:
1085 shr edx,1
1086 jmp scan_symbols
1087 symbols_up:
1088 lea ebx,[edi+ecx+2]
1089 shr edx,1
1090 adc edx,-1
1091 jmp scan_symbols
1092
1093 get_data_directive:
1094 push esi
1095 mov ebp,ecx
1096 call lower_case
1097 mov ecx,ebp
1098 cmp cl,4
1099 ja no_instruction
1100 sub cl,2
1101 jc no_instruction
1102 movzx ebx,word [data_directives+ecx*4]
1103 add ebx,data_directives
1104 movzx edx,word [data_directives+ecx*4+2]
1105 jmp scan_instructions
1106
1107 get_instruction:
1108 push esi
1109 mov ebp,ecx
1110 call lower_case
1111 mov ecx,ebp
1112 cmp cl,16
1113 ja no_instruction
1114 sub cl,2
1115 jc no_instruction
1116 movzx ebx,word [instructions+ecx*4]
1117 add ebx,instructions
1118 movzx edx,word [instructions+ecx*4+2]
1119 scan_instructions:
1120 or edx,edx
1121 jz no_instruction
1122 mov eax,edx
1123 shr eax,1
1124 lea edi,[ebp+3]
1125 imul eax,edi
1126 lea edi,[ebx+eax]
1127 mov esi,converted
1128 mov ecx,ebp
1129 repe cmps byte [esi],[edi]
1130 ja instructions_up
1131 jb instructions_down
1132 pop esi
1133 add esi,ebp
1134 mov al,[edi]
1135 mov bx,[edi+1]
1136 clc
1137 ret
1138 no_instruction:
1139 pop esi
1140 mov ecx,ebp
1141 stc
1142 ret
1143 instructions_down:
1144 shr edx,1
1145 jmp scan_instructions
1146 instructions_up:
1147 lea ebx,[edi+ecx+3]
1148 shr edx,1
1149 adc edx,-1
1150 jmp scan_instructions
1151
1152 get_label_id:
1153 cmp ecx,100h
1154 jae name_too_long
1155 cmp byte [esi],'@'
1156 je anonymous_label
1157 cmp byte [esi],'.'
1158 jne standard_label
1159 cmp byte [esi+1],'.'
1160 je standard_label
1161 cmp [current_locals_prefix],0
1162 je standard_label
1163 push edi
1164 mov edi,[additional_memory_end]
1165 sub edi,2
1166 sub edi,ecx
1167 push ecx esi
1168 mov esi,[current_locals_prefix]
1169 lods byte [esi]
1170 movzx ecx,al
1171 sub edi,ecx
1172 cmp edi,[free_additional_memory]
1173 jb out_of_memory
1174 mov word [edi],0
1175 add edi,2
1176 mov ebx,edi
1177 rep movs byte [edi],[esi]
1178 pop esi ecx
1179 add al,cl
1180 jc name_too_long
1181 rep movs byte [edi],[esi]
1182 pop edi
1183 push ebx esi
1184 movzx ecx,al
1185 mov byte [ebx-1],al
1186 mov esi,ebx
1187 call get_label_id
1188 pop esi ebx
1189 cmp ebx,[eax+24]
1190 jne composed_label_id_ok
1191 lea edx,[ebx-2]
1192 mov [additional_memory_end],edx
1193 composed_label_id_ok:
1194 ret
1195 anonymous_label:
1196 cmp ecx,2
1197 jne standard_label
1198 mov al,[esi+1]
1199 mov ebx,characters
1200 xlat byte [ebx]
1201 cmp al,'@'
1202 je new_anonymous
1203 cmp al,'b'
1204 je anonymous_back
1205 cmp al,'r'
1206 je anonymous_back
1207 cmp al,'f'
1208 jne standard_label
1209 add esi,2
1210 mov eax,[anonymous_forward]
1211 or eax,eax
1212 jnz anonymous_ok
1213 mov eax,[current_line]
1214 mov [error_line],eax
1215 call allocate_label
1216 mov [anonymous_forward],eax
1217 anonymous_ok:
1218 xor ebx,ebx
1219 ret
1220 anonymous_back:
1221 mov eax,[anonymous_reverse]
1222 add esi,2
1223 or eax,eax
1224 jz bogus_anonymous
1225 jmp anonymous_ok
1226 bogus_anonymous:
1227 call allocate_label
1228 mov [anonymous_reverse],eax
1229 jmp anonymous_ok
1230 new_anonymous:
1231 add esi,2
1232 mov eax,[anonymous_forward]
1233 or eax,eax
1234 jnz new_anonymous_ok
1235 call allocate_label
1236 new_anonymous_ok:
1237 mov [anonymous_reverse],eax
1238 mov [anonymous_forward],0
1239 jmp anonymous_ok
1240 standard_label:
1241 cmp byte [esi],'%'
1242 je get_predefined_id
1243 cmp byte [esi],'$'
1244 je current_address_label
1245 cmp byte [esi],'?'
1246 jne find_label
1247 cmp ecx,1
1248 jne find_label
1249 inc esi
1250 mov eax,0Fh
1251 ret
1252 current_address_label:
1253 cmp ecx,2
1254 ja find_label
1255 inc esi
1256 jb get_current_offset_id
1257 inc esi
1258 cmp byte [esi-1],'$'
1259 je get_org_origin_id
1260 sub esi,ecx
1261 jmp find_label
1262 get_current_offset_id:
1263 xor eax,eax
1264 ret
1265 get_counter_id:
1266 mov eax,1
1267 ret
1268 get_timestamp_id:
1269 mov eax,2
1270 ret
1271 get_org_origin_id:
1272 mov eax,3
1273 ret
1274 get_predefined_id:
1275 cmp ecx,2
1276 ja find_label
1277 inc esi
1278 cmp cl,1
1279 je get_counter_id
1280 lods byte [esi]
1281 mov ebx,characters
1282 xlat [ebx]
1283 cmp al,'t'
1284 je get_timestamp_id
1285 sub esi,2
1286 find_label:
1287 xor ebx,ebx
1288 mov eax,2166136261
1289 mov ebp,16777619
1290 hash_label:
1291 xor al,[esi+ebx]
1292 mul ebp
1293 inc bl
1294 cmp bl,cl
1295 jb hash_label
1296 mov ebp,eax
1297 shl eax,8
1298 and ebp,0FFh shl 24
1299 xor ebp,eax
1300 or ebp,ebx
1301 mov [label_hash],ebp
1302 push edi esi
1303 push ecx
1304 mov ecx,32
1305 mov ebx,hash_tree
1306 follow_tree:
1307 mov edx,[ebx]
1308 or edx,edx
1309 jz extend_tree
1310 xor eax,eax
1311 shl ebp,1
1312 adc eax,0
1313 lea ebx,[edx+eax*4]
1314 dec ecx
1315 jnz follow_tree
1316 mov [label_leaf],ebx
1317 pop edx
1318 mov eax,[ebx]
1319 or eax,eax
1320 jz add_label
1321 mov ebx,esi
1322 mov ebp,[label_hash]
1323 compare_labels:
1324 mov esi,ebx
1325 mov ecx,edx
1326 mov edi,[eax+4]
1327 mov edi,[edi+24]
1328 repe cmps byte [esi],[edi]
1329 je label_found
1330 mov eax,[eax]
1331 or eax,eax
1332 jnz compare_labels
1333 jmp add_label
1334 label_found:
1335 add esp,4
1336 pop edi
1337 mov eax,[eax+4]
1338 ret
1339 extend_tree:
1340 mov edx,[free_additional_memory]
1341 lea eax,[edx+8]
1342 cmp eax,[additional_memory_end]
1343 ja out_of_memory
1344 mov [free_additional_memory],eax
1345 xor eax,eax
1346 mov [edx],eax
1347 mov [edx+4],eax
1348 shl ebp,1
1349 adc eax,0
1350 mov [ebx],edx
1351 lea ebx,[edx+eax*4]
1352 dec ecx
1353 jnz extend_tree
1354 mov [label_leaf],ebx
1355 pop edx
1356 add_label:
1357 mov ecx,edx
1358 pop esi
1359 cmp byte [esi-2],0
1360 je label_name_ok
1361 mov al,[esi]
1362 cmp al,30h
1363 jb name_first_char_ok
1364 cmp al,39h
1365 jbe invalid_name
1366 name_first_char_ok:
1367 cmp al,'$'
1368 jne check_for_reserved_word
1369 cmp ecx,1
1370 jne invalid_name
1371 reserved_word:
1372 mov eax,0Fh
1373 pop edi
1374 ret
1375 check_for_reserved_word:
1376 call get_instruction
1377 jnc reserved_word
1378 call get_data_directive
1379 jnc reserved_word
1380 call get_symbol
1381 jnc reserved_word
1382 sub esi,2
1383 mov edi,operators
1384 call get_operator
1385 or al,al
1386 jnz reserved_word
1387 mov edi,single_operand_operators
1388 call get_operator
1389 or al,al
1390 jnz reserved_word
1391 mov edi,directive_operators
1392 call get_operator
1393 or al,al
1394 jnz reserved_word
1395 inc esi
1396 movzx ecx,byte [esi]
1397 inc esi
1398 label_name_ok:
1399 mov edx,[free_additional_memory]
1400 lea eax,[edx+8]
1401 cmp eax,[additional_memory_end]
1402 ja out_of_memory
1403 mov [free_additional_memory],eax
1404 mov ebx,esi
1405 add esi,ecx
1406 mov eax,[label_leaf]
1407 mov edi,[eax]
1408 mov [edx],edi
1409 mov [eax],edx
1410 call allocate_label
1411 mov [edx+4],eax
1412 mov [eax+24],ebx
1413 pop edi
1414 ret
1415 allocate_label:
1416 mov eax,[labels_list]
1417 mov ecx,LABEL_STRUCTURE_SIZE shr 2
1418 initialize_label:
1419 sub eax,4
1420 mov dword [eax],0
1421 loop initialize_label
1422 mov [labels_list],eax
1423 ret
1424
1425 LABEL_STRUCTURE_SIZE = 32
0
1 ; flat assembler core
2 ; Copyright (c) 1999-2014, Tomasz Grysztar.
3 ; All rights reserved.
4
5 preprocessor:
6 mov edi,characters
7 xor al,al
8 make_characters_table:
9 stosb
10 inc al
11 jnz make_characters_table
12 mov esi,characters+'a'
13 mov edi,characters+'A'
14 mov ecx,26
15 rep movsb
16 mov edi,characters
17 mov esi,symbol_characters+1
18 movzx ecx,byte [esi-1]
19 xor eax,eax
20 mark_symbol_characters:
21 lodsb
22 mov byte [edi+eax],0
23 loop mark_symbol_characters
24 mov edi,locals_counter
25 mov ax,1 + '0' shl 8
26 stos word [edi]
27 mov edi,[memory_start]
28 mov [include_paths],edi
29 mov esi,include_variable
30 call get_environment_variable
31 xor al,al
32 stos byte [edi]
33 mov [memory_start],edi
34 mov eax,[additional_memory]
35 mov [free_additional_memory],eax
36 mov eax,[additional_memory_end]
37 mov [labels_list],eax
38 xor eax,eax
39 mov [source_start],eax
40 mov [tagged_blocks],eax
41 mov [hash_tree],eax
42 mov [error],eax
43 mov [macro_status],al
44 mov esi,[input_file]
45 mov edx,esi
46 call open
47 jc main_file_not_found
48 mov edi,[memory_start]
49 call preprocess_file
50 cmp [macro_status],0
51 je process_postponed
52 mov eax,[error_line]
53 mov [current_line],eax
54 jmp incomplete_macro
55 process_postponed:
56 mov edx,hash_tree
57 mov ecx,32
58 find_postponed_list:
59 mov edx,[edx]
60 or edx,edx
61 loopnz find_postponed_list
62 jz preprocessing_finished
63 process_postponed_list:
64 mov eax,[edx]
65 or eax,eax
66 jz preprocessing_finished
67 push edx
68 mov ebx,edx
69 find_earliest_postponed:
70 mov eax,[edx]
71 or eax,eax
72 jz earliest_postponed_found
73 mov ebx,edx
74 mov edx,eax
75 jmp find_earliest_postponed
76 earliest_postponed_found:
77 mov [ebx],eax
78 call use_postponed_macro
79 pop edx
80 jmp process_postponed_list
81 preprocessing_finished:
82 mov [source_start],edi
83 ret
84 use_postponed_macro:
85 lea esi,[edi-1]
86 push ecx esi
87 mov [struc_name],0
88 jmp use_macro
89
90 preprocess_file:
91 push [memory_end]
92 push esi
93 mov al,2
94 xor edx,edx
95 call lseek
96 push eax
97 xor al,al
98 xor edx,edx
99 call lseek
100 pop ecx
101 mov edx,[memory_end]
102 dec edx
103 mov byte [edx],1Ah
104 sub edx,ecx
105 jc out_of_memory
106 mov esi,edx
107 cmp edx,edi
108 jbe out_of_memory
109 mov [memory_end],edx
110 call read
111 call close
112 pop edx
113 xor ecx,ecx
114 mov ebx,esi
115 preprocess_source:
116 inc ecx
117 mov [current_line],edi
118 mov eax,edx
119 stos dword [edi]
120 mov eax,ecx
121 stos dword [edi]
122 mov eax,esi
123 sub eax,ebx
124 stos dword [edi]
125 xor eax,eax
126 stos dword [edi]
127 push ebx edx
128 call convert_line
129 call preprocess_line
130 pop edx ebx
131 next_line:
132 cmp byte [esi-1],0
133 je file_end
134 cmp byte [esi-1],1Ah
135 jne preprocess_source
136 file_end:
137 pop [memory_end]
138 clc
139 ret
140
141 convert_line:
142 push ecx
143 test [macro_status],0Fh
144 jz convert_line_data
145 mov ax,3Bh
146 stos word [edi]
147 convert_line_data:
148 cmp edi,[memory_end]
149 jae out_of_memory
150 lods byte [esi]
151 cmp al,20h
152 je convert_line_data
153 cmp al,9
154 je convert_line_data
155 mov ah,al
156 mov ebx,characters
157 xlat byte [ebx]
158 or al,al
159 jz convert_separator
160 cmp ah,27h
161 je convert_string
162 cmp ah,22h
163 je convert_string
164 mov byte [edi],1Ah
165 scas word [edi]
166 xchg al,ah
167 stos byte [edi]
168 mov ebx,characters
169 xor ecx,ecx
170 convert_symbol:
171 lods byte [esi]
172 stos byte [edi]
173 xlat byte [ebx]
174 or al,al
175 loopnzd convert_symbol
176 neg ecx
177 cmp ecx,255
178 ja name_too_long
179 mov ebx,edi
180 sub ebx,ecx
181 mov byte [ebx-2],cl
182 found_separator:
183 dec edi
184 mov ah,[esi-1]
185 convert_separator:
186 xchg al,ah
187 cmp al,20h
188 jb control_character
189 je convert_line_data
190 symbol_character:
191 cmp al,3Bh
192 je ignore_comment
193 cmp al,5Ch
194 je backslash_character
195 stos byte [edi]
196 jmp convert_line_data
197 control_character:
198 cmp al,1Ah
199 je line_end
200 cmp al,0Dh
201 je cr_character
202 cmp al,0Ah
203 je lf_character
204 cmp al,9
205 je convert_line_data
206 or al,al
207 jnz symbol_character
208 jmp line_end
209 lf_character:
210 lods byte [esi]
211 cmp al,0Dh
212 je line_end
213 dec esi
214 jmp line_end
215 cr_character:
216 lods byte [esi]
217 cmp al,0Ah
218 je line_end
219 dec esi
220 jmp line_end
221 convert_string:
222 mov al,22h
223 stos byte [edi]
224 scas dword [edi]
225 mov ebx,edi
226 copy_string:
227 lods byte [esi]
228 stos byte [edi]
229 cmp al,0Ah
230 je no_end_quote
231 cmp al,0Dh
232 je no_end_quote
233 or al,al
234 jz no_end_quote
235 cmp al,1Ah
236 je no_end_quote
237 cmp al,ah
238 jne copy_string
239 lods byte [esi]
240 cmp al,ah
241 je copy_string
242 dec esi
243 dec edi
244 mov eax,edi
245 sub eax,ebx
246 mov [ebx-4],eax
247 jmp convert_line_data
248 backslash_character:
249 mov byte [edi],0
250 lods byte [esi]
251 cmp al,20h
252 je concatenate_lines
253 cmp al,9
254 je concatenate_lines
255 cmp al,1Ah
256 je unexpected_end_of_file
257 or al,al
258 jz unexpected_end_of_file
259 cmp al,0Ah
260 je concatenate_lf
261 cmp al,0Dh
262 je concatenate_cr
263 cmp al,3Bh
264 je find_concatenated_line
265 mov al,1Ah
266 stos byte [edi]
267 mov ecx,edi
268 mov ax,5C01h
269 stos word [edi]
270 dec esi
271 group_backslashes:
272 lods byte [esi]
273 cmp al,5Ch
274 jne backslashed_symbol
275 stos byte [edi]
276 inc byte [ecx]
277 jmp group_backslashes
278 no_end_quote:
279 mov byte [ebx-5],0
280 jmp missing_end_quote
281 backslashed_symbol:
282 cmp al,1Ah
283 je unexpected_end_of_file
284 or al,al
285 jz unexpected_end_of_file
286 cmp al,0Ah
287 je extra_characters_on_line
288 cmp al,0Dh
289 je extra_characters_on_line
290 cmp al,20h
291 je extra_characters_on_line
292 cmp al,9
293 je extra_characters_on_line
294 cmp al,22h
295 je extra_characters_on_line
296 cmp al,27h
297 je extra_characters_on_line
298 cmp al,3Bh
299 je extra_characters_on_line
300 mov ah,al
301 mov ebx,characters
302 xlat byte [ebx]
303 or al,al
304 jz backslashed_symbol_character
305 mov al,ah
306 convert_backslashed_symbol:
307 stos byte [edi]
308 xlat byte [ebx]
309 or al,al
310 jz found_separator
311 inc byte [ecx]
312 jz name_too_long
313 lods byte [esi]
314 jmp convert_backslashed_symbol
315 backslashed_symbol_character:
316 mov al,ah
317 stos byte [edi]
318 inc byte [ecx]
319 jmp convert_line_data
320 concatenate_lines:
321 lods byte [esi]
322 cmp al,20h
323 je concatenate_lines
324 cmp al,9
325 je concatenate_lines
326 cmp al,1Ah
327 je unexpected_end_of_file
328 or al,al
329 jz unexpected_end_of_file
330 cmp al,0Ah
331 je concatenate_lf
332 cmp al,0Dh
333 je concatenate_cr
334 cmp al,3Bh
335 jne extra_characters_on_line
336 find_concatenated_line:
337 lods byte [esi]
338 cmp al,0Ah
339 je concatenate_lf
340 cmp al,0Dh
341 je concatenate_cr
342 or al,al
343 jz concatenate_ok
344 cmp al,1Ah
345 jne find_concatenated_line
346 jmp unexpected_end_of_file
347 concatenate_lf:
348 lods byte [esi]
349 cmp al,0Dh
350 je concatenate_ok
351 dec esi
352 jmp concatenate_ok
353 concatenate_cr:
354 lods byte [esi]
355 cmp al,0Ah
356 je concatenate_ok
357 dec esi
358 concatenate_ok:
359 inc dword [esp]
360 jmp convert_line_data
361 ignore_comment:
362 lods byte [esi]
363 cmp al,0Ah
364 je lf_character
365 cmp al,0Dh
366 je cr_character
367 or al,al
368 jz line_end
369 cmp al,1Ah
370 jne ignore_comment
371 line_end:
372 xor al,al
373 stos byte [edi]
374 pop ecx
375 ret
376
377 lower_case:
378 mov edi,converted
379 mov ebx,characters
380 convert_case:
381 lods byte [esi]
382 xlat byte [ebx]
383 stos byte [edi]
384 loop convert_case
385 case_ok:
386 ret
387
388 get_directive:
389 push edi
390 mov edx,esi
391 mov ebp,ecx
392 call lower_case
393 pop edi
394 scan_directives:
395 mov esi,converted
396 movzx eax,byte [edi]
397 or al,al
398 jz no_directive
399 mov ecx,ebp
400 inc edi
401 mov ebx,edi
402 add ebx,eax
403 mov ah,[esi]
404 cmp ah,[edi]
405 jb no_directive
406 ja next_directive
407 cmp cl,al
408 jne next_directive
409 repe cmps byte [esi],[edi]
410 jb no_directive
411 je directive_ok
412 next_directive:
413 mov edi,ebx
414 add edi,2
415 jmp scan_directives
416 no_directive:
417 mov esi,edx
418 mov ecx,ebp
419 stc
420 ret
421 directive_ok:
422 lea esi,[edx+ebp]
423 call directive_handler
424 directive_handler:
425 pop ecx
426 movzx eax,word [ebx]
427 add eax,ecx
428 clc
429 ret
430
431 preprocess_line:
432 mov eax,esp
433 sub eax,100h
434 jc stack_overflow
435 cmp eax,[stack_limit]
436 jb stack_overflow
437 push ecx esi
438 preprocess_current_line:
439 mov esi,[current_line]
440 add esi,16
441 cmp word [esi],3Bh
442 jne line_start_ok
443 add esi,2
444 line_start_ok:
445 test [macro_status],0F0h
446 jnz macro_preprocessing
447 cmp byte [esi],1Ah
448 jne not_fix_constant
449 movzx edx,byte [esi+1]
450 lea edx,[esi+2+edx]
451 cmp word [edx],031Ah
452 jne not_fix_constant
453 mov ebx,characters
454 movzx eax,byte [edx+2]
455 xlat byte [ebx]
456 ror eax,8
457 mov al,[edx+3]
458 xlat byte [ebx]
459 ror eax,8
460 mov al,[edx+4]
461 xlat byte [ebx]
462 ror eax,16
463 cmp eax,'fix'
464 je define_fix_constant
465 not_fix_constant:
466 call process_fix_constants
467 jmp initial_preprocessing_ok
468 macro_preprocessing:
469 call process_macro_operators
470 initial_preprocessing_ok:
471 mov esi,[current_line]
472 add esi,16
473 mov al,[macro_status]
474 test al,2
475 jnz skip_macro_block
476 test al,1
477 jnz find_macro_block
478 preprocess_instruction:
479 mov [current_offset],esi
480 lods byte [esi]
481 movzx ecx,byte [esi]
482 inc esi
483 cmp al,1Ah
484 jne not_preprocessor_symbol
485 cmp cl,3
486 jb not_preprocessor_directive
487 push edi
488 mov edi,preprocessor_directives
489 call get_directive
490 pop edi
491 jc not_preprocessor_directive
492 mov byte [edx-2],3Bh
493 jmp near eax
494 not_preprocessor_directive:
495 xor ch,ch
496 call get_preprocessor_symbol
497 jc not_macro
498 mov byte [ebx-2],3Bh
499 mov [struc_name],0
500 jmp use_macro
501 not_macro:
502 mov [struc_name],esi
503 add esi,ecx
504 lods byte [esi]
505 cmp al,':'
506 je preprocess_label
507 cmp al,1Ah
508 jne not_preprocessor_symbol
509 lods byte [esi]
510 cmp al,3
511 jne not_symbolic_constant
512 mov ebx,characters
513 movzx eax,byte [esi]
514 xlat byte [ebx]
515 ror eax,8
516 mov al,[esi+1]
517 xlat byte [ebx]
518 ror eax,8
519 mov al,[esi+2]
520 xlat byte [ebx]
521 ror eax,16
522 cmp eax,'equ'
523 je define_equ_constant
524 mov al,3
525 not_symbolic_constant:
526 mov ch,1
527 mov cl,al
528 call get_preprocessor_symbol
529 jc not_preprocessor_symbol
530 push edx esi
531 mov esi,[struc_name]
532 mov [struc_label],esi
533 sub [struc_label],2
534 mov cl,[esi-1]
535 mov ch,10b
536 call get_preprocessor_symbol
537 jc struc_name_ok
538 mov ecx,[edx+12]
539 add ecx,3
540 lea ebx,[edi+ecx]
541 mov ecx,edi
542 sub ecx,[struc_label]
543 lea esi,[edi-1]
544 lea edi,[ebx-1]
545 std
546 rep movs byte [edi],[esi]
547 cld
548 mov edi,[struc_label]
549 mov esi,[edx+8]
550 mov ecx,[edx+12]
551 add [struc_name],ecx
552 add [struc_name],3
553 call move_data
554 mov al,3Ah
555 stos byte [edi]
556 mov ax,3Bh
557 stos word [edi]
558 mov edi,ebx
559 pop esi
560 add esi,[edx+12]
561 add esi,3
562 pop edx
563 jmp use_macro
564 struc_name_ok:
565 mov edx,[struc_name]
566 movzx eax,byte [edx-1]
567 add edx,eax
568 push edi
569 lea esi,[edi-1]
570 mov ecx,edi
571 sub ecx,edx
572 std
573 rep movs byte [edi],[esi]
574 cld
575 pop edi
576 inc edi
577 mov al,3Ah
578 mov [edx],al
579 inc al
580 mov [edx+1],al
581 pop esi edx
582 inc esi
583 jmp use_macro
584 preprocess_label:
585 dec esi
586 sub esi,ecx
587 lea ebp,[esi-2]
588 mov ch,10b
589 call get_preprocessor_symbol
590 jnc symbolic_constant_in_label
591 lea esi,[esi+ecx+1]
592 cmp byte [esi],':'
593 jne preprocess_instruction
594 inc esi
595 jmp preprocess_instruction
596 symbolic_constant_in_label:
597 mov ebx,[edx+8]
598 mov ecx,[edx+12]
599 add ecx,ebx
600 check_for_broken_label:
601 cmp ebx,ecx
602 je label_broken
603 cmp byte [ebx],1Ah
604 jne label_broken
605 movzx eax,byte [ebx+1]
606 lea ebx,[ebx+2+eax]
607 cmp ebx,ecx
608 je label_constant_ok
609 cmp byte [ebx],':'
610 jne label_broken
611 inc ebx
612 cmp byte [ebx],':'
613 jne check_for_broken_label
614 inc ebx
615 jmp check_for_broken_label
616 label_broken:
617 push line_preprocessed
618 jmp replace_symbolic_constant
619 label_constant_ok:
620 mov ecx,edi
621 sub ecx,esi
622 mov edi,[edx+12]
623 add edi,ebp
624 push edi
625 lea eax,[edi+ecx]
626 push eax
627 cmp esi,edi
628 je replace_label
629 jb move_rest_of_line_up
630 rep movs byte [edi],[esi]
631 jmp replace_label
632 move_rest_of_line_up:
633 lea esi,[esi+ecx-1]
634 lea edi,[edi+ecx-1]
635 std
636 rep movs byte [edi],[esi]
637 cld
638 replace_label:
639 mov ecx,[edx+12]
640 mov edi,[esp+4]
641 sub edi,ecx
642 mov esi,[edx+8]
643 rep movs byte [edi],[esi]
644 pop edi esi
645 inc esi
646 jmp preprocess_instruction
647 not_preprocessor_symbol:
648 mov esi,[current_offset]
649 call process_equ_constants
650 line_preprocessed:
651 pop esi ecx
652 ret
653
654 get_preprocessor_symbol:
655 push ebp edi esi
656 mov ebp,ecx
657 shl ebp,22
658 movzx ecx,cl
659 mov ebx,hash_tree
660 mov edi,10
661 follow_hashes_roots:
662 mov edx,[ebx]
663 or edx,edx
664 jz preprocessor_symbol_not_found
665 xor eax,eax
666 shl ebp,1
667 adc eax,0
668 lea ebx,[edx+eax*4]
669 dec edi
670 jnz follow_hashes_roots
671 mov edi,ebx
672 call calculate_hash
673 mov ebp,eax
674 and ebp,3FFh
675 shl ebp,10
676 xor ebp,eax
677 mov ebx,edi
678 mov edi,22
679 follow_hashes_tree:
680 mov edx,[ebx]
681 or edx,edx
682 jz preprocessor_symbol_not_found
683 xor eax,eax
684 shl ebp,1
685 adc eax,0
686 lea ebx,[edx+eax*4]
687 dec edi
688 jnz follow_hashes_tree
689 mov al,cl
690 mov edx,[ebx]
691 or edx,edx
692 jz preprocessor_symbol_not_found
693 compare_with_preprocessor_symbol:
694 mov edi,[edx+4]
695 cmp edi,1
696 jbe next_equal_hash
697 repe cmps byte [esi],[edi]
698 je preprocessor_symbol_found
699 mov cl,al
700 mov esi,[esp]
701 next_equal_hash:
702 mov edx,[edx]
703 or edx,edx
704 jnz compare_with_preprocessor_symbol
705 preprocessor_symbol_not_found:
706 pop esi edi ebp
707 stc
708 ret
709 preprocessor_symbol_found:
710 pop ebx edi ebp
711 clc
712 ret
713 calculate_hash:
714 xor ebx,ebx
715 mov eax,2166136261
716 mov ebp,16777619
717 fnv1a_hash:
718 xor al,[esi+ebx]
719 mul ebp
720 inc bl
721 cmp bl,cl
722 jb fnv1a_hash
723 ret
724 add_preprocessor_symbol:
725 push edi esi
726 xor eax,eax
727 or cl,cl
728 jz reshape_hash
729 cmp ch,11b
730 je preprocessor_symbol_name_ok
731 push ecx
732 movzx ecx,cl
733 mov edi,preprocessor_directives
734 call get_directive
735 jnc reserved_word_used_as_symbol
736 pop ecx
737 preprocessor_symbol_name_ok:
738 call calculate_hash
739 reshape_hash:
740 mov ebp,eax
741 and ebp,3FFh
742 shr eax,10
743 xor ebp,eax
744 shl ecx,22
745 or ebp,ecx
746 mov ebx,hash_tree
747 mov ecx,32
748 find_leave_for_symbol:
749 mov edx,[ebx]
750 or edx,edx
751 jz extend_hashes_tree
752 xor eax,eax
753 rol ebp,1
754 adc eax,0
755 lea ebx,[edx+eax*4]
756 dec ecx
757 jnz find_leave_for_symbol
758 mov edx,[ebx]
759 or edx,edx
760 jz add_symbol_entry
761 shr ebp,30
762 cmp ebp,11b
763 je reuse_symbol_entry
764 cmp dword [edx+4],0
765 jne add_symbol_entry
766 find_entry_to_reuse:
767 mov edi,[edx]
768 or edi,edi
769 jz reuse_symbol_entry
770 cmp dword [edi+4],0
771 jne reuse_symbol_entry
772 mov edx,edi
773 jmp find_entry_to_reuse
774 add_symbol_entry:
775 mov eax,edx
776 mov edx,[labels_list]
777 sub edx,16
778 cmp edx,[free_additional_memory]
779 jb out_of_memory
780 mov [labels_list],edx
781 mov [edx],eax
782 mov [ebx],edx
783 reuse_symbol_entry:
784 pop esi edi
785 mov [edx+4],esi
786 ret
787 extend_hashes_tree:
788 mov edx,[labels_list]
789 sub edx,8
790 cmp edx,[free_additional_memory]
791 jb out_of_memory
792 mov [labels_list],edx
793 xor eax,eax
794 mov [edx],eax
795 mov [edx+4],eax
796 shl ebp,1
797 adc eax,0
798 mov [ebx],edx
799 lea ebx,[edx+eax*4]
800 dec ecx
801 jnz extend_hashes_tree
802 mov edx,[labels_list]
803 sub edx,16
804 cmp edx,[free_additional_memory]
805 jb out_of_memory
806 mov [labels_list],edx
807 mov dword [edx],0
808 mov [ebx],edx
809 pop esi edi
810 mov [edx+4],esi
811 ret
812
813 define_fix_constant:
814 add edx,5
815 add esi,2
816 push edx
817 mov ch,11b
818 jmp define_preprocessor_constant
819 define_equ_constant:
820 add esi,3
821 push esi
822 call process_equ_constants
823 mov esi,[struc_name]
824 mov ch,10b
825 define_preprocessor_constant:
826 mov byte [esi-2],3Bh
827 mov cl,[esi-1]
828 call add_preprocessor_symbol
829 pop ebx
830 mov ecx,edi
831 dec ecx
832 sub ecx,ebx
833 mov [edx+8],ebx
834 mov [edx+12],ecx
835 jmp line_preprocessed
836 define_symbolic_constant:
837 lods byte [esi]
838 cmp al,1Ah
839 jne invalid_name
840 lods byte [esi]
841 mov cl,al
842 mov ch,10b
843 call add_preprocessor_symbol
844 movzx eax,byte [esi-1]
845 add esi,eax
846 lea ecx,[edi-1]
847 sub ecx,esi
848 mov [edx+8],esi
849 mov [edx+12],ecx
850 jmp line_preprocessed
851
852 define_struc:
853 mov ch,1
854 jmp make_macro
855 define_macro:
856 xor ch,ch
857 make_macro:
858 lods byte [esi]
859 cmp al,1Ah
860 jne invalid_name
861 lods byte [esi]
862 mov cl,al
863 call add_preprocessor_symbol
864 mov eax,[current_line]
865 mov [edx+12],eax
866 movzx eax,byte [esi-1]
867 add esi,eax
868 mov [edx+8],esi
869 mov al,[macro_status]
870 and al,0F0h
871 or al,1
872 mov [macro_status],al
873 mov eax,[current_line]
874 mov [error_line],eax
875 xor ebp,ebp
876 lods byte [esi]
877 or al,al
878 jz line_preprocessed
879 cmp al,'{'
880 je found_macro_block
881 dec esi
882 skip_macro_arguments:
883 lods byte [esi]
884 cmp al,1Ah
885 je skip_macro_argument
886 cmp al,'['
887 jne invalid_macro_arguments
888 or ebp,-1
889 jz invalid_macro_arguments
890 lods byte [esi]
891 cmp al,1Ah
892 jne invalid_macro_arguments
893 skip_macro_argument:
894 movzx eax,byte [esi]
895 inc esi
896 add esi,eax
897 lods byte [esi]
898 cmp al,'='
899 je macro_argument_with_default_value
900 cmp al,'*'
901 jne macro_argument_end
902 lods byte [esi]
903 macro_argument_end:
904 cmp al,','
905 je skip_macro_arguments
906 cmp al,']'
907 jne end_macro_arguments
908 lods byte [esi]
909 not ebp
910 end_macro_arguments:
911 or ebp,ebp
912 jnz invalid_macro_arguments
913 or al,al
914 jz line_preprocessed
915 cmp al,'{'
916 je found_macro_block
917 jmp invalid_macro_arguments
918 macro_argument_with_default_value:
919 or [default_argument_value],-1
920 call skip_macro_argument_value
921 inc esi
922 jmp macro_argument_end
923 skip_macro_argument_value:
924 cmp byte [esi],'<'
925 jne simple_argument
926 mov ecx,1
927 inc esi
928 enclosed_argument:
929 lods byte [esi]
930 or al,al
931 jz invalid_macro_arguments
932 cmp al,1Ah
933 je enclosed_symbol
934 cmp al,22h
935 je enclosed_string
936 cmp al,'>'
937 je enclosed_argument_end
938 cmp al,'<'
939 jne enclosed_argument
940 inc ecx
941 jmp enclosed_argument
942 enclosed_symbol:
943 movzx eax,byte [esi]
944 inc esi
945 add esi,eax
946 jmp enclosed_argument
947 enclosed_string:
948 lods dword [esi]
949 add esi,eax
950 jmp enclosed_argument
951 enclosed_argument_end:
952 loop enclosed_argument
953 lods byte [esi]
954 or al,al
955 jz argument_value_end
956 cmp al,','
957 je argument_value_end
958 cmp [default_argument_value],0
959 je invalid_macro_arguments
960 cmp al,'{'
961 je argument_value_end
962 or ebp,ebp
963 jz invalid_macro_arguments
964 cmp al,']'
965 je argument_value_end
966 jmp invalid_macro_arguments
967 simple_argument:
968 lods byte [esi]
969 or al,al
970 jz argument_value_end
971 cmp al,','
972 je argument_value_end
973 cmp al,22h
974 je argument_string
975 cmp al,1Ah
976 je argument_symbol
977 cmp [default_argument_value],0
978 je simple_argument
979 cmp al,'{'
980 je argument_value_end
981 or ebp,ebp
982 jz simple_argument
983 cmp al,']'
984 je argument_value_end
985 argument_symbol:
986 movzx eax,byte [esi]
987 inc esi
988 add esi,eax
989 jmp simple_argument
990 argument_string:
991 lods dword [esi]
992 add esi,eax
993 jmp simple_argument
994 argument_value_end:
995 dec esi
996 ret
997 find_macro_block:
998 add esi,2
999 lods byte [esi]
1000 or al,al
1001 jz line_preprocessed
1002 cmp al,'{'
1003 jne unexpected_characters
1004 found_macro_block:
1005 or [macro_status],2
1006 skip_macro_block:
1007 lods byte [esi]
1008 cmp al,1Ah
1009 je skip_macro_symbol
1010 cmp al,3Bh
1011 je skip_macro_symbol
1012 cmp al,22h
1013 je skip_macro_string
1014 or al,al
1015 jz line_preprocessed
1016 cmp al,'}'
1017 jne skip_macro_block
1018 mov al,[macro_status]
1019 and [macro_status],0F0h
1020 test al,8
1021 jnz use_instant_macro
1022 cmp byte [esi],0
1023 je line_preprocessed
1024 mov ecx,edi
1025 sub ecx,esi
1026 mov edx,esi
1027 lea esi,[esi+ecx-1]
1028 lea edi,[edi+1+16]
1029 mov ebx,edi
1030 dec edi
1031 std
1032 rep movs byte [edi],[esi]
1033 cld
1034 mov edi,edx
1035 xor al,al
1036 stos byte [edi]
1037 mov esi,[current_line]
1038 mov [current_line],edi
1039 mov ecx,4
1040 rep movs dword [edi],[esi]
1041 mov edi,ebx
1042 jmp initial_preprocessing_ok
1043 skip_macro_symbol:
1044 movzx eax,byte [esi]
1045 inc esi
1046 add esi,eax
1047 jmp skip_macro_block
1048 skip_macro_string:
1049 lods dword [esi]
1050 add esi,eax
1051 jmp skip_macro_block
1052 postpone_directive:
1053 push esi
1054 mov esi,edx
1055 xor ecx,ecx
1056 call add_preprocessor_symbol
1057 mov eax,[current_line]
1058 mov [edx+12],eax
1059 pop esi
1060 mov [edx+8],esi
1061 mov al,[macro_status]
1062 and al,0F0h
1063 or al,1
1064 mov [macro_status],al
1065 mov eax,[current_line]
1066 mov [error_line],eax
1067 lods byte [esi]
1068 or al,al
1069 jz line_preprocessed
1070 cmp al,'{'
1071 jne unexpected_characters
1072 jmp found_macro_block
1073 rept_directive:
1074 mov [base_code],0
1075 jmp define_instant_macro
1076 irp_directive:
1077 mov [base_code],1
1078 jmp define_instant_macro
1079 irps_directive:
1080 mov [base_code],2
1081 jmp define_instant_macro
1082 irpv_directive:
1083 mov [base_code],3
1084 jmp define_instant_macro
1085 match_directive:
1086 mov [base_code],10h
1087 define_instant_macro:
1088 mov al,[macro_status]
1089 and al,0F0h
1090 or al,8+1
1091 mov [macro_status],al
1092 mov eax,[current_line]
1093 mov [error_line],eax
1094 mov [instant_macro_start],esi
1095 cmp [base_code],10h
1096 je prepare_match
1097 skip_parameters:
1098 lods byte [esi]
1099 or al,al
1100 jz parameters_skipped
1101 cmp al,'{'
1102 je parameters_skipped
1103 cmp al,22h
1104 je skip_quoted_parameter
1105 cmp al,1Ah
1106 jne skip_parameters
1107 lods byte [esi]
1108 movzx eax,al
1109 add esi,eax
1110 jmp skip_parameters
1111 skip_quoted_parameter:
1112 lods dword [esi]
1113 add esi,eax
1114 jmp skip_parameters
1115 parameters_skipped:
1116 dec esi
1117 mov [parameters_end],esi
1118 lods byte [esi]
1119 cmp al,'{'
1120 je found_macro_block
1121 or al,al
1122 jnz invalid_macro_arguments
1123 jmp line_preprocessed
1124 prepare_match:
1125 call skip_pattern
1126 mov [value_type],80h+10b
1127 call process_symbolic_constants
1128 jmp parameters_skipped
1129 skip_pattern:
1130 lods byte [esi]
1131 or al,al
1132 jz invalid_macro_arguments
1133 cmp al,','
1134 je pattern_skipped
1135 cmp al,22h
1136 je skip_quoted_string_in_pattern
1137 cmp al,1Ah
1138 je skip_symbol_in_pattern
1139 cmp al,'='
1140 jne skip_pattern
1141 mov al,[esi]
1142 cmp al,1Ah
1143 je skip_pattern
1144 cmp al,22h
1145 je skip_pattern
1146 inc esi
1147 jmp skip_pattern
1148 skip_symbol_in_pattern:
1149 lods byte [esi]
1150 movzx eax,al
1151 add esi,eax
1152 jmp skip_pattern
1153 skip_quoted_string_in_pattern:
1154 lods dword [esi]
1155 add esi,eax
1156 jmp skip_pattern
1157 pattern_skipped:
1158 ret
1159
1160 purge_macro:
1161 xor ch,ch
1162 jmp restore_preprocessor_symbol
1163 purge_struc:
1164 mov ch,1
1165 jmp restore_preprocessor_symbol
1166 restore_equ_constant:
1167 mov ch,10b
1168 restore_preprocessor_symbol:
1169 push ecx
1170 lods byte [esi]
1171 cmp al,1Ah
1172 jne invalid_name
1173 lods byte [esi]
1174 mov cl,al
1175 call get_preprocessor_symbol
1176 jc no_symbol_to_restore
1177 mov dword [edx+4],0
1178 jmp symbol_restored
1179 no_symbol_to_restore:
1180 add esi,ecx
1181 symbol_restored:
1182 pop ecx
1183 lods byte [esi]
1184 cmp al,','
1185 je restore_preprocessor_symbol
1186 or al,al
1187 jnz extra_characters_on_line
1188 jmp line_preprocessed
1189
1190 process_fix_constants:
1191 mov [value_type],11b
1192 jmp process_symbolic_constants
1193 process_equ_constants:
1194 mov [value_type],10b
1195 process_symbolic_constants:
1196 mov ebp,esi
1197 lods byte [esi]
1198 cmp al,1Ah
1199 je check_symbol
1200 cmp al,22h
1201 je ignore_string
1202 cmp al,'{'
1203 je check_brace
1204 or al,al
1205 jnz process_symbolic_constants
1206 ret
1207 ignore_string:
1208 lods dword [esi]
1209 add esi,eax
1210 jmp process_symbolic_constants
1211 check_brace:
1212 test [value_type],80h
1213 jz process_symbolic_constants
1214 ret
1215 no_replacing:
1216 movzx ecx,byte [esi-1]
1217 add esi,ecx
1218 jmp process_symbolic_constants
1219 check_symbol:
1220 mov cl,[esi]
1221 inc esi
1222 mov ch,[value_type]
1223 call get_preprocessor_symbol
1224 jc no_replacing
1225 mov [current_section],edi
1226 replace_symbolic_constant:
1227 mov ecx,[edx+12]
1228 mov edx,[edx+8]
1229 xchg esi,edx
1230 call move_data
1231 mov esi,edx
1232 process_after_replaced:
1233 lods byte [esi]
1234 cmp al,1Ah
1235 je symbol_after_replaced
1236 stos byte [edi]
1237 cmp al,22h
1238 je string_after_replaced
1239 cmp al,'{'
1240 je brace_after_replaced
1241 or al,al
1242 jnz process_after_replaced
1243 mov ecx,edi
1244 sub ecx,esi
1245 mov edi,ebp
1246 call move_data
1247 mov esi,edi
1248 ret
1249 move_data:
1250 lea eax,[edi+ecx]
1251 cmp eax,[memory_end]
1252 jae out_of_memory
1253 shr ecx,1
1254 jnc movsb_ok
1255 movs byte [edi],[esi]
1256 movsb_ok:
1257 shr ecx,1
1258 jnc movsw_ok
1259 movs word [edi],[esi]
1260 movsw_ok:
1261 rep movs dword [edi],[esi]
1262 ret
1263 string_after_replaced:
1264 lods dword [esi]
1265 stos dword [edi]
1266 mov ecx,eax
1267 call move_data
1268 jmp process_after_replaced
1269 brace_after_replaced:
1270 test [value_type],80h
1271 jz process_after_replaced
1272 mov edx,edi
1273 mov ecx,[current_section]
1274 sub edx,ecx
1275 sub ecx,esi
1276 rep movs byte [edi],[esi]
1277 mov ecx,edi
1278 sub ecx,esi
1279 mov edi,ebp
1280 call move_data
1281 lea esi,[ebp+edx]
1282 ret
1283 symbol_after_replaced:
1284 mov cl,[esi]
1285 inc esi
1286 mov ch,[value_type]
1287 call get_preprocessor_symbol
1288 jnc replace_symbolic_constant
1289 movzx ecx,byte [esi-1]
1290 mov al,1Ah
1291 mov ah,cl
1292 stos word [edi]
1293 call move_data
1294 jmp process_after_replaced
1295 process_macro_operators:
1296 xor dl,dl
1297 mov ebp,edi
1298 before_macro_operators:
1299 mov edi,esi
1300 lods byte [esi]
1301 cmp al,'`'
1302 je symbol_conversion
1303 cmp al,'#'
1304 je concatenation
1305 cmp al,1Ah
1306 je symbol_before_macro_operators
1307 cmp al,3Bh
1308 je no_more_macro_operators
1309 cmp al,22h
1310 je string_before_macro_operators
1311 xor dl,dl
1312 or al,al
1313 jnz before_macro_operators
1314 mov edi,esi
1315 ret
1316 no_more_macro_operators:
1317 mov edi,ebp
1318 ret
1319 symbol_before_macro_operators:
1320 mov dl,1Ah
1321 mov ebx,esi
1322 lods byte [esi]
1323 movzx ecx,al
1324 jecxz symbol_before_macro_operators_ok
1325 mov edi,esi
1326 cmp byte [esi],'\'
1327 je escaped_symbol
1328 symbol_before_macro_operators_ok:
1329 add esi,ecx
1330 jmp before_macro_operators
1331 string_before_macro_operators:
1332 mov dl,22h
1333 mov ebx,esi
1334 lods dword [esi]
1335 add esi,eax
1336 jmp before_macro_operators
1337 escaped_symbol:
1338 dec byte [edi-1]
1339 dec ecx
1340 inc esi
1341 cmp ecx,1
1342 rep movs byte [edi],[esi]
1343 jne after_macro_operators
1344 mov al,[esi-1]
1345 mov ecx,ebx
1346 mov ebx,characters
1347 xlat byte [ebx]
1348 mov ebx,ecx
1349 or al,al
1350 jnz after_macro_operators
1351 sub edi,3
1352 mov al,[esi-1]
1353 stos byte [edi]
1354 xor dl,dl
1355 jmp after_macro_operators
1356 reduce_symbol_conversion:
1357 inc esi
1358 symbol_conversion:
1359 mov edx,esi
1360 mov al,[esi]
1361 cmp al,1Ah
1362 jne symbol_character_conversion
1363 lods word [esi]
1364 movzx ecx,ah
1365 lea ebx,[edi+3]
1366 jecxz convert_to_quoted_string
1367 cmp byte [esi],'\'
1368 jne convert_to_quoted_string
1369 inc esi
1370 dec ecx
1371 dec ebx
1372 jmp convert_to_quoted_string
1373 symbol_character_conversion:
1374 cmp al,22h
1375 je after_macro_operators
1376 cmp al,'`'
1377 je reduce_symbol_conversion
1378 lea ebx,[edi+5]
1379 xor ecx,ecx
1380 or al,al
1381 jz convert_to_quoted_string
1382 cmp al,'#'
1383 je convert_to_quoted_string
1384 inc ecx
1385 convert_to_quoted_string:
1386 sub ebx,edx
1387 ja shift_line_data
1388 mov al,22h
1389 mov dl,al
1390 stos byte [edi]
1391 mov ebx,edi
1392 mov eax,ecx
1393 stos dword [edi]
1394 rep movs byte [edi],[esi]
1395 cmp edi,esi
1396 je before_macro_operators
1397 jmp after_macro_operators
1398 shift_line_data:
1399 push ecx
1400 mov edx,esi
1401 lea esi,[ebp-1]
1402 add ebp,ebx
1403 lea edi,[ebp-1]
1404 lea ecx,[esi+1]
1405 sub ecx,edx
1406 std
1407 rep movs byte [edi],[esi]
1408 cld
1409 pop eax
1410 sub edi,3
1411 mov dl,22h
1412 mov [edi-1],dl
1413 mov ebx,edi
1414 mov [edi],eax
1415 lea esi,[edi+4+eax]
1416 jmp before_macro_operators
1417 concatenation:
1418 cmp dl,1Ah
1419 je symbol_concatenation
1420 cmp dl,22h
1421 je string_concatenation
1422 no_concatenation:
1423 cmp esi,edi
1424 je before_macro_operators
1425 jmp after_macro_operators
1426 symbol_concatenation:
1427 cmp byte [esi],1Ah
1428 jne no_concatenation
1429 inc esi
1430 lods byte [esi]
1431 movzx ecx,al
1432 jecxz do_symbol_concatenation
1433 cmp byte [esi],'\'
1434 je concatenate_escaped_symbol
1435 do_symbol_concatenation:
1436 add [ebx],cl
1437 jc name_too_long
1438 rep movs byte [edi],[esi]
1439 jmp after_macro_operators
1440 concatenate_escaped_symbol:
1441 inc esi
1442 dec ecx
1443 jz do_symbol_concatenation
1444 movzx eax,byte [esi]
1445 cmp byte [characters+eax],0
1446 jne do_symbol_concatenation
1447 sub esi,3
1448 jmp no_concatenation
1449 string_concatenation:
1450 cmp byte [esi],22h
1451 je do_string_concatenation
1452 cmp byte [esi],'`'
1453 jne no_concatenation
1454 concatenate_converted_symbol:
1455 inc esi
1456 mov al,[esi]
1457 cmp al,'`'
1458 je concatenate_converted_symbol
1459 cmp al,22h
1460 je do_string_concatenation
1461 cmp al,1Ah
1462 jne concatenate_converted_symbol_character
1463 inc esi
1464 lods byte [esi]
1465 movzx ecx,al
1466 jecxz finish_concatenating_converted_symbol
1467 cmp byte [esi],'\'
1468 jne finish_concatenating_converted_symbol
1469 inc esi
1470 dec ecx
1471 finish_concatenating_converted_symbol:
1472 add [ebx],ecx
1473 rep movs byte [edi],[esi]
1474 jmp after_macro_operators
1475 concatenate_converted_symbol_character:
1476 or al,al
1477 jz after_macro_operators
1478 cmp al,'#'
1479 je after_macro_operators
1480 inc dword [ebx]
1481 movs byte [edi],[esi]
1482 jmp after_macro_operators
1483 do_string_concatenation:
1484 inc esi
1485 lods dword [esi]
1486 mov ecx,eax
1487 add [ebx],eax
1488 rep movs byte [edi],[esi]
1489 after_macro_operators:
1490 lods byte [esi]
1491 cmp al,'`'
1492 je symbol_conversion
1493 cmp al,'#'
1494 je concatenation
1495 stos byte [edi]
1496 cmp al,1Ah
1497 je symbol_after_macro_operators
1498 cmp al,3Bh
1499 je no_more_macro_operators
1500 cmp al,22h
1501 je string_after_macro_operators
1502 xor dl,dl
1503 or al,al
1504 jnz after_macro_operators
1505 ret
1506 symbol_after_macro_operators:
1507 mov dl,1Ah
1508 mov ebx,edi
1509 lods byte [esi]
1510 stos byte [edi]
1511 movzx ecx,al
1512 jecxz symbol_after_macro_operatorss_ok
1513 cmp byte [esi],'\'
1514 je escaped_symbol
1515 symbol_after_macro_operatorss_ok:
1516 rep movs byte [edi],[esi]
1517 jmp after_macro_operators
1518 string_after_macro_operators:
1519 mov dl,22h
1520 mov ebx,edi
1521 lods dword [esi]
1522 stos dword [edi]
1523 mov ecx,eax
1524 rep movs byte [edi],[esi]
1525 jmp after_macro_operators
1526
1527 use_macro:
1528 push [free_additional_memory]
1529 push [macro_symbols]
1530 mov [macro_symbols],0
1531 push [counter_limit]
1532 push dword [edx+4]
1533 mov dword [edx+4],1
1534 push edx
1535 mov ebx,esi
1536 mov esi,[edx+8]
1537 mov eax,[edx+12]
1538 mov [macro_line],eax
1539 mov [counter_limit],0
1540 xor ebp,ebp
1541 process_macro_arguments:
1542 mov al,[esi]
1543 or al,al
1544 jz arguments_end
1545 cmp al,'{'
1546 je arguments_end
1547 inc esi
1548 cmp al,'['
1549 jne get_macro_arguments
1550 mov ebp,esi
1551 inc esi
1552 inc [counter_limit]
1553 get_macro_arguments:
1554 call get_macro_argument
1555 lods byte [esi]
1556 cmp al,','
1557 je next_argument
1558 cmp al,']'
1559 je next_arguments_group
1560 dec esi
1561 jmp arguments_end
1562 next_argument:
1563 cmp byte [ebx],','
1564 jne process_macro_arguments
1565 inc ebx
1566 jmp process_macro_arguments
1567 next_arguments_group:
1568 cmp byte [ebx],','
1569 jne arguments_end
1570 inc ebx
1571 inc [counter_limit]
1572 mov esi,ebp
1573 jmp process_macro_arguments
1574 get_macro_argument:
1575 lods byte [esi]
1576 movzx ecx,al
1577 mov eax,[counter_limit]
1578 call add_macro_symbol
1579 add esi,ecx
1580 xchg esi,ebx
1581 mov [edx+12],esi
1582 mov [default_argument_value],0
1583 call skip_macro_argument_value
1584 call finish_macro_argument
1585 xchg esi,ebx
1586 cmp byte [esi],'='
1587 je argument_with_default_value
1588 cmp byte [esi],'*'
1589 jne macro_argument_ok
1590 cmp dword [edx+8],0
1591 je invalid_macro_arguments
1592 inc esi
1593 macro_argument_ok:
1594 ret
1595 finish_macro_argument:
1596 mov eax,[edx+12]
1597 mov ecx,esi
1598 sub ecx,eax
1599 cmp byte [eax],'<'
1600 jne argument_value_length_ok
1601 inc dword [edx+12]
1602 sub ecx,2
1603 or ecx,80000000h
1604 argument_value_length_ok:
1605 mov [edx+8],ecx
1606 ret
1607 argument_with_default_value:
1608 inc esi
1609 push esi
1610 or [default_argument_value],-1
1611 call skip_macro_argument_value
1612 pop eax
1613 cmp dword [edx+8],0
1614 jne macro_argument_ok
1615 mov [edx+12],eax
1616 call finish_macro_argument
1617 jmp macro_argument_ok
1618 arguments_end:
1619 cmp byte [ebx],0
1620 jne invalid_macro_arguments
1621 mov eax,[esp+4]
1622 dec eax
1623 call process_macro
1624 pop edx
1625 pop dword [edx+4]
1626 pop [counter_limit]
1627 pop [macro_symbols]
1628 pop [free_additional_memory]
1629 jmp line_preprocessed
1630 use_instant_macro:
1631 push edi [current_line] esi
1632 mov eax,[error_line]
1633 mov [current_line],eax
1634 mov [macro_line],eax
1635 mov esi,[instant_macro_start]
1636 cmp [base_code],10h
1637 jae do_match
1638 cmp [base_code],0
1639 jne do_irp
1640 call precalculate_value
1641 cmp eax,0
1642 jl value_out_of_range
1643 push [free_additional_memory]
1644 push [macro_symbols]
1645 mov [macro_symbols],0
1646 push [counter_limit]
1647 mov [struc_name],0
1648 mov [counter_limit],eax
1649 lods byte [esi]
1650 or al,al
1651 jz rept_counters_ok
1652 cmp al,'{'
1653 je rept_counters_ok
1654 cmp al,1Ah
1655 jne invalid_macro_arguments
1656 add_rept_counter:
1657 lods byte [esi]
1658 movzx ecx,al
1659 xor eax,eax
1660 call add_macro_symbol
1661 add esi,ecx
1662 xor eax,eax
1663 mov dword [edx+12],eax
1664 inc eax
1665 mov dword [edx+8],eax
1666 lods byte [esi]
1667 cmp al,':'
1668 jne rept_counter_added
1669 push edx
1670 call precalculate_value
1671 mov edx,eax
1672 add edx,[counter_limit]
1673 jo value_out_of_range
1674 pop edx
1675 mov dword [edx+8],eax
1676 lods byte [esi]
1677 rept_counter_added:
1678 cmp al,','
1679 jne rept_counters_ok
1680 lods byte [esi]
1681 cmp al,1Ah
1682 jne invalid_macro_arguments
1683 jmp add_rept_counter
1684 rept_counters_ok:
1685 dec esi
1686 cmp [counter_limit],0
1687 je instant_macro_finish
1688 instant_macro_parameters_ok:
1689 xor eax,eax
1690 call process_macro
1691 instant_macro_finish:
1692 pop [counter_limit]
1693 pop [macro_symbols]
1694 pop [free_additional_memory]
1695 instant_macro_done:
1696 pop ebx esi edx
1697 cmp byte [ebx],0
1698 je line_preprocessed
1699 mov [current_line],edi
1700 mov ecx,4
1701 rep movs dword [edi],[esi]
1702 test [macro_status],0Fh
1703 jz instant_macro_attached_line
1704 mov ax,3Bh
1705 stos word [edi]
1706 instant_macro_attached_line:
1707 mov esi,ebx
1708 sub edx,ebx
1709 mov ecx,edx
1710 call move_data
1711 jmp initial_preprocessing_ok
1712 precalculate_value:
1713 push edi
1714 call convert_expression
1715 mov al,')'
1716 stosb
1717 push esi
1718 mov esi,[esp+4]
1719 mov [error_line],0
1720 mov [value_size],0
1721 call calculate_expression
1722 cmp [error_line],0
1723 je value_precalculated
1724 jmp [error]
1725 value_precalculated:
1726 mov eax,[edi]
1727 mov ecx,[edi+4]
1728 cdq
1729 cmp edx,ecx
1730 jne value_out_of_range
1731 cmp dl,[edi+13]
1732 jne value_out_of_range
1733 pop esi edi
1734 ret
1735 do_irp:
1736 cmp byte [esi],1Ah
1737 jne invalid_macro_arguments
1738 movzx eax,byte [esi+1]
1739 lea esi,[esi+2+eax]
1740 lods byte [esi]
1741 cmp [base_code],1
1742 ja irps_name_ok
1743 cmp al,'='
1744 je irp_with_default_value
1745 cmp al,'*'
1746 jne irp_name_ok
1747 lods byte [esi]
1748 irp_name_ok:
1749 cmp al,','
1750 jne invalid_macro_arguments
1751 jmp irp_parameters_start
1752 irp_with_default_value:
1753 xor ebp,ebp
1754 or [default_argument_value],-1
1755 call skip_macro_argument_value
1756 inc esi
1757 jmp irp_parameters_start
1758 irps_name_ok:
1759 cmp al,','
1760 jne invalid_macro_arguments
1761 cmp [base_code],3
1762 je irp_parameters_start
1763 mov al,[esi]
1764 or al,al
1765 jz instant_macro_done
1766 cmp al,'{'
1767 je instant_macro_done
1768 irp_parameters_start:
1769 xor eax,eax
1770 push [free_additional_memory]
1771 push [macro_symbols]
1772 mov [macro_symbols],eax
1773 push [counter_limit]
1774 mov [counter_limit],eax
1775 mov [struc_name],eax
1776 cmp [base_code],3
1777 je get_irpv_parameter
1778 mov ebx,esi
1779 cmp [base_code],2
1780 je get_irps_parameter
1781 mov edx,[parameters_end]
1782 mov al,[edx]
1783 push eax
1784 mov byte [edx],0
1785 get_irp_parameter:
1786 inc [counter_limit]
1787 mov esi,[instant_macro_start]
1788 inc esi
1789 call get_macro_argument
1790 cmp byte [ebx],','
1791 jne irp_parameters_end
1792 inc ebx
1793 jmp get_irp_parameter
1794 irp_parameters_end:
1795 mov esi,ebx
1796 pop eax
1797 mov [esi],al
1798 jmp instant_macro_parameters_ok
1799 get_irps_parameter:
1800 mov esi,[instant_macro_start]
1801 inc esi
1802 lods byte [esi]
1803 movzx ecx,al
1804 inc [counter_limit]
1805 mov eax,[counter_limit]
1806 call add_macro_symbol
1807 mov [edx+12],ebx
1808 cmp byte [ebx],1Ah
1809 je irps_symbol
1810 cmp byte [ebx],22h
1811 je irps_quoted_string
1812 mov eax,1
1813 jmp irps_parameter_ok
1814 irps_quoted_string:
1815 mov eax,[ebx+1]
1816 add eax,1+4
1817 jmp irps_parameter_ok
1818 irps_symbol:
1819 movzx eax,byte [ebx+1]
1820 add eax,1+1
1821 irps_parameter_ok:
1822 mov [edx+8],eax
1823 add ebx,eax
1824 cmp byte [ebx],0
1825 je irps_parameters_end
1826 cmp byte [ebx],'{'
1827 jne get_irps_parameter
1828 irps_parameters_end:
1829 mov esi,ebx
1830 jmp instant_macro_parameters_ok
1831 get_irpv_parameter:
1832 lods byte [esi]
1833 cmp al,1Ah
1834 jne invalid_macro_arguments
1835 lods byte [esi]
1836 mov ebp,esi
1837 mov cl,al
1838 mov ch,10b
1839 call get_preprocessor_symbol
1840 jc instant_macro_finish
1841 push edx
1842 mark_variable_value:
1843 inc [counter_limit]
1844 mov [edx+4],ebp
1845 next_variable_value:
1846 mov edx,[edx]
1847 or edx,edx
1848 jz variable_values_marked
1849 mov eax,[edx+4]
1850 cmp eax,1
1851 jbe next_variable_value
1852 mov esi,ebp
1853 movzx ecx,byte [esi-1]
1854 xchg edi,eax
1855 repe cmps byte [esi],[edi]
1856 xchg edi,eax
1857 je mark_variable_value
1858 jmp next_variable_value
1859 variable_values_marked:
1860 pop edx
1861 push [counter_limit]
1862 add_irpv_value:
1863 push edx
1864 mov esi,[instant_macro_start]
1865 inc esi
1866 lods byte [esi]
1867 movzx ecx,al
1868 mov eax,[esp+4]
1869 call add_macro_symbol
1870 mov ebx,edx
1871 pop edx
1872 mov ecx,[edx+12]
1873 mov eax,[edx+8]
1874 mov [ebx+12],eax
1875 mov [ebx+8],ecx
1876 collect_next_variable_value:
1877 mov edx,[edx]
1878 or edx,edx
1879 jz variable_values_collected
1880 cmp ebp,[edx+4]
1881 jne collect_next_variable_value
1882 dec dword [esp]
1883 jnz add_irpv_value
1884 variable_values_collected:
1885 pop eax
1886 mov esi,ebp
1887 movzx ecx,byte [esi-1]
1888 add esi,ecx
1889 cmp byte [esi],0
1890 je instant_macro_parameters_ok
1891 cmp byte [esi],'{'
1892 jne invalid_macro_arguments
1893 jmp instant_macro_parameters_ok
1894
1895 do_match:
1896 mov ebx,esi
1897 call skip_pattern
1898 call exact_match
1899 mov edx,edi
1900 mov al,[ebx]
1901 cmp al,1Ah
1902 je free_match
1903 cmp al,','
1904 jne instant_macro_done
1905 cmp esi,[parameters_end]
1906 je matched_pattern
1907 jmp instant_macro_done
1908 free_match:
1909 add edx,12
1910 cmp edx,[memory_end]
1911 ja out_of_memory
1912 mov [edx-12],ebx
1913 mov [edx-8],esi
1914 call skip_match_element
1915 jc try_different_matching
1916 mov [edx-4],esi
1917 movzx eax,byte [ebx+1]
1918 lea ebx,[ebx+2+eax]
1919 cmp byte [ebx],1Ah
1920 je free_match
1921 find_exact_match:
1922 call exact_match
1923 cmp esi,[parameters_end]
1924 je end_matching
1925 cmp byte [ebx],1Ah
1926 je free_match
1927 mov ebx,[edx-12]
1928 movzx eax,byte [ebx+1]
1929 lea ebx,[ebx+2+eax]
1930 mov esi,[edx-4]
1931 jmp match_more_elements
1932 try_different_matching:
1933 sub edx,12
1934 cmp edx,edi
1935 je instant_macro_done
1936 mov ebx,[edx-12]
1937 movzx eax,byte [ebx+1]
1938 lea ebx,[ebx+2+eax]
1939 cmp byte [ebx],1Ah
1940 je try_different_matching
1941 mov esi,[edx-4]
1942 match_more_elements:
1943 call skip_match_element
1944 jc try_different_matching
1945 mov [edx-4],esi
1946 jmp find_exact_match
1947 skip_match_element:
1948 cmp esi,[parameters_end]
1949 je cannot_match
1950 mov al,[esi]
1951 cmp al,1Ah
1952 je skip_match_symbol
1953 cmp al,22h
1954 je skip_match_quoted_string
1955 add esi,1
1956 ret
1957 skip_match_quoted_string:
1958 mov eax,[esi+1]
1959 add esi,5
1960 jmp skip_match_ok
1961 skip_match_symbol:
1962 movzx eax,byte [esi+1]
1963 add esi,2
1964 skip_match_ok:
1965 add esi,eax
1966 ret
1967 cannot_match:
1968 stc
1969 ret
1970 exact_match:
1971 cmp esi,[parameters_end]
1972 je exact_match_complete
1973 mov ah,[esi]
1974 mov al,[ebx]
1975 cmp al,','
1976 je exact_match_complete
1977 cmp al,1Ah
1978 je exact_match_complete
1979 cmp al,'='
1980 je match_verbatim
1981 call match_elements
1982 je exact_match
1983 exact_match_complete:
1984 ret
1985 match_verbatim:
1986 inc ebx
1987 call match_elements
1988 je exact_match
1989 dec ebx
1990 ret
1991 match_elements:
1992 mov al,[ebx]
1993 cmp al,1Ah
1994 je match_symbols
1995 cmp al,22h
1996 je match_quoted_strings
1997 cmp al,ah
1998 je symbol_characters_matched
1999 ret
2000 symbol_characters_matched:
2001 lea ebx,[ebx+1]
2002 lea esi,[esi+1]
2003 ret
2004 match_quoted_strings:
2005 mov ecx,[ebx+1]
2006 add ecx,5
2007 jmp compare_elements
2008 match_symbols:
2009 movzx ecx,byte [ebx+1]
2010 add ecx,2
2011 compare_elements:
2012 mov eax,esi
2013 mov ebp,edi
2014 mov edi,ebx
2015 repe cmps byte [esi],[edi]
2016 jne elements_mismatch
2017 mov ebx,edi
2018 mov edi,ebp
2019 ret
2020 elements_mismatch:
2021 mov esi,eax
2022 mov edi,ebp
2023 ret
2024 end_matching:
2025 cmp byte [ebx],','
2026 jne instant_macro_done
2027 matched_pattern:
2028 xor eax,eax
2029 push [free_additional_memory]
2030 push [macro_symbols]
2031 mov [macro_symbols],eax
2032 push [counter_limit]
2033 mov [counter_limit],eax
2034 mov [struc_name],eax
2035 push esi edi edx
2036 add_matched_symbol:
2037 cmp edi,[esp]
2038 je matched_symbols_ok
2039 mov esi,[edi]
2040 inc esi
2041 lods byte [esi]
2042 movzx ecx,al
2043 xor eax,eax
2044 call add_macro_symbol
2045 mov eax,[edi+4]
2046 mov dword [edx+12],eax
2047 mov ecx,[edi+8]
2048 sub ecx,eax
2049 mov dword [edx+8],ecx
2050 add edi,12
2051 jmp add_matched_symbol
2052 matched_symbols_ok:
2053 pop edx edi esi
2054 jmp instant_macro_parameters_ok
2055
2056 process_macro:
2057 push dword [macro_status]
2058 or [macro_status],10h
2059 push [counter]
2060 push [macro_block]
2061 push [macro_block_line]
2062 push [macro_block_line_number]
2063 push [struc_label]
2064 push [struc_name]
2065 push eax
2066 push [current_line]
2067 lods byte [esi]
2068 cmp al,'{'
2069 je macro_instructions_start
2070 or al,al
2071 jnz unexpected_characters
2072 find_macro_instructions:
2073 mov [macro_line],esi
2074 add esi,16+2
2075 lods byte [esi]
2076 or al,al
2077 jz find_macro_instructions
2078 cmp al,'{'
2079 je macro_instructions_start
2080 cmp al,3Bh
2081 jne unexpected_characters
2082 call skip_foreign_symbol
2083 jmp find_macro_instructions
2084 macro_instructions_start:
2085 mov ecx,80000000h
2086 mov [macro_block],esi
2087 mov eax,[macro_line]
2088 mov [macro_block_line],eax
2089 mov [macro_block_line_number],ecx
2090 xor eax,eax
2091 mov [counter],eax
2092 cmp [counter_limit],eax
2093 je process_macro_line
2094 inc [counter]
2095 process_macro_line:
2096 lods byte [esi]
2097 or al,al
2098 jz process_next_line
2099 cmp al,'}'
2100 je macro_block_processed
2101 dec esi
2102 mov [current_line],edi
2103 lea eax,[edi+10h]
2104 cmp eax,[memory_end]
2105 jae out_of_memory
2106 mov eax,[esp+4]
2107 or eax,eax
2108 jz instant_macro_line_header
2109 stos dword [edi]
2110 mov eax,ecx
2111 stos dword [edi]
2112 mov eax,[esp]
2113 stos dword [edi]
2114 mov eax,[macro_line]
2115 stos dword [edi]
2116 jmp macro_line_header_ok
2117 instant_macro_line_header:
2118 mov eax,[esp]
2119 add eax,16
2120 find_defining_directive:
2121 inc eax
2122 cmp byte [eax-1],3Bh
2123 je defining_directive_ok
2124 cmp byte [eax-1],1Ah
2125 jne find_defining_directive
2126 push eax
2127 movzx eax,byte [eax]
2128 inc eax
2129 add [esp],eax
2130 pop eax
2131 jmp find_defining_directive
2132 defining_directive_ok:
2133 stos dword [edi]
2134 mov eax,ecx
2135 stos dword [edi]
2136 mov eax,[macro_line]
2137 stos dword [edi]
2138 stos dword [edi]
2139 macro_line_header_ok:
2140 or [macro_status],20h
2141 push ebx ecx
2142 test [macro_status],0Fh
2143 jz process_macro_line_element
2144 mov ax,3Bh
2145 stos word [edi]
2146 process_macro_line_element:
2147 lea eax,[edi+100h]
2148 cmp eax,[memory_end]
2149 jae out_of_memory
2150 lods byte [esi]
2151 cmp al,'}'
2152 je macro_line_processed
2153 or al,al
2154 jz macro_line_processed
2155 cmp al,1Ah
2156 je process_macro_symbol
2157 cmp al,3Bh
2158 je macro_foreign_line
2159 and [macro_status],not 20h
2160 stos byte [edi]
2161 cmp al,22h
2162 jne process_macro_line_element
2163 copy_macro_string:
2164 mov ecx,[esi]
2165 add ecx,4
2166 call move_data
2167 jmp process_macro_line_element
2168 process_macro_symbol:
2169 push esi edi
2170 test [macro_status],20h
2171 jz not_macro_directive
2172 movzx ecx,byte [esi]
2173 inc esi
2174 mov edi,macro_directives
2175 call get_directive
2176 jnc process_macro_directive
2177 dec esi
2178 jmp not_macro_directive
2179 process_macro_directive:
2180 mov edx,eax
2181 pop edi eax
2182 mov byte [edi],0
2183 inc edi
2184 pop ecx ebx
2185 jmp near edx
2186 not_macro_directive:
2187 and [macro_status],not 20h
2188 movzx ecx,byte [esi]
2189 inc esi
2190 mov eax,[counter]
2191 call get_macro_symbol
2192 jnc group_macro_symbol
2193 xor eax,eax
2194 cmp [counter],eax
2195 je multiple_macro_symbol_values
2196 call get_macro_symbol
2197 jc not_macro_symbol
2198 replace_macro_symbol:
2199 pop edi eax
2200 mov ecx,[edx+8]
2201 mov edx,[edx+12]
2202 or edx,edx
2203 jz replace_macro_counter
2204 and ecx,not 80000000h
2205 xchg esi,edx
2206 call move_data
2207 mov esi,edx
2208 jmp process_macro_line_element
2209 group_macro_symbol:
2210 xor eax,eax
2211 cmp [counter],eax
2212 je replace_macro_symbol
2213 push esi edx
2214 sub esi,ecx
2215 call get_macro_symbol
2216 mov ebx,edx
2217 pop edx esi
2218 jc replace_macro_symbol
2219 cmp edx,ebx
2220 ja replace_macro_symbol
2221 mov edx,ebx
2222 jmp replace_macro_symbol
2223 multiple_macro_symbol_values:
2224 inc eax
2225 push eax
2226 call get_macro_symbol
2227 pop eax
2228 jc not_macro_symbol
2229 pop edi
2230 push ecx
2231 mov ecx,[edx+8]
2232 mov edx,[edx+12]
2233 xchg esi,edx
2234 btr ecx,31
2235 jc enclose_macro_symbol_value
2236 rep movs byte [edi],[esi]
2237 jmp macro_symbol_value_ok
2238 enclose_macro_symbol_value:
2239 mov byte [edi],'<'
2240 inc edi
2241 rep movs byte [edi],[esi]
2242 mov byte [edi],'>'
2243 inc edi
2244 macro_symbol_value_ok:
2245 cmp eax,[counter_limit]
2246 je multiple_macro_symbol_values_ok
2247 mov byte [edi],','
2248 inc edi
2249 mov esi,edx
2250 pop ecx
2251 push edi
2252 sub esi,ecx
2253 jmp multiple_macro_symbol_values
2254 multiple_macro_symbol_values_ok:
2255 pop ecx eax
2256 mov esi,edx
2257 jmp process_macro_line_element
2258 replace_macro_counter:
2259 mov eax,[counter]
2260 and eax,not 80000000h
2261 jz group_macro_counter
2262 add ecx,eax
2263 dec ecx
2264 call store_number_symbol
2265 jmp process_macro_line_element
2266 group_macro_counter:
2267 mov edx,ecx
2268 xor ecx,ecx
2269 multiple_macro_counter_values:
2270 push ecx edx
2271 add ecx,edx
2272 call store_number_symbol
2273 pop edx ecx
2274 inc ecx
2275 cmp ecx,[counter_limit]
2276 je process_macro_line_element
2277 mov byte [edi],','
2278 inc edi
2279 jmp multiple_macro_counter_values
2280 store_number_symbol:
2281 cmp ecx,0
2282 jge numer_symbol_sign_ok
2283 neg ecx
2284 mov al,'-'
2285 stos byte [edi]
2286 numer_symbol_sign_ok:
2287 mov ax,1Ah
2288 stos word [edi]
2289 push edi
2290 mov eax,ecx
2291 mov ecx,1000000000
2292 xor edx,edx
2293 xor bl,bl
2294 store_number_digits:
2295 div ecx
2296 push edx
2297 or bl,bl
2298 jnz store_number_digit
2299 cmp ecx,1
2300 je store_number_digit
2301 or al,al
2302 jz number_digit_ok
2303 not bl
2304 store_number_digit:
2305 add al,30h
2306 stos byte [edi]
2307 number_digit_ok:
2308 mov eax,ecx
2309 xor edx,edx
2310 mov ecx,10
2311 div ecx
2312 mov ecx,eax
2313 pop eax
2314 or ecx,ecx
2315 jnz store_number_digits
2316 pop ebx
2317 mov eax,edi
2318 sub eax,ebx
2319 mov [ebx-1],al
2320 ret
2321 not_macro_symbol:
2322 pop edi esi
2323 mov al,1Ah
2324 stos byte [edi]
2325 mov al,[esi]
2326 inc esi
2327 stos byte [edi]
2328 cmp byte [esi],'.'
2329 jne copy_raw_symbol
2330 mov ebx,[esp+8+8]
2331 or ebx,ebx
2332 jz copy_raw_symbol
2333 cmp al,1
2334 je copy_struc_name
2335 xchg esi,ebx
2336 movzx ecx,byte [esi-1]
2337 add [edi-1],cl
2338 jc name_too_long
2339 rep movs byte [edi],[esi]
2340 xchg esi,ebx
2341 copy_raw_symbol:
2342 movzx ecx,al
2343 rep movs byte [edi],[esi]
2344 jmp process_macro_line_element
2345 copy_struc_name:
2346 inc esi
2347 xchg esi,ebx
2348 movzx ecx,byte [esi-1]
2349 mov [edi-1],cl
2350 rep movs byte [edi],[esi]
2351 xchg esi,ebx
2352 mov eax,[esp+8+12]
2353 cmp byte [eax],3Bh
2354 je process_macro_line_element
2355 cmp byte [eax],1Ah
2356 jne disable_replaced_struc_name
2357 mov byte [eax],3Bh
2358 jmp process_macro_line_element
2359 disable_replaced_struc_name:
2360 mov ebx,[esp+8+8]
2361 push esi edi
2362 lea edi,[ebx-3]
2363 lea esi,[edi-2]
2364 lea ecx,[esi+1]
2365 sub ecx,eax
2366 std
2367 rep movs byte [edi],[esi]
2368 cld
2369 mov word [eax],3Bh
2370 pop edi esi
2371 jmp process_macro_line_element
2372 skip_foreign_symbol:
2373 lods byte [esi]
2374 movzx eax,al
2375 add esi,eax
2376 skip_foreign_line:
2377 lods byte [esi]
2378 cmp al,1Ah
2379 je skip_foreign_symbol
2380 cmp al,3Bh
2381 je skip_foreign_symbol
2382 cmp al,22h
2383 je skip_foreign_string
2384 or al,al
2385 jnz skip_foreign_line
2386 ret
2387 skip_foreign_string:
2388 lods dword [esi]
2389 add esi,eax
2390 jmp skip_foreign_line
2391 macro_foreign_line:
2392 call skip_foreign_symbol
2393 macro_line_processed:
2394 mov byte [edi],0
2395 inc edi
2396 push eax
2397 call preprocess_line
2398 pop eax
2399 pop ecx ebx
2400 cmp al,'}'
2401 je macro_block_processed
2402 process_next_line:
2403 inc ecx
2404 mov [macro_line],esi
2405 add esi,16+2
2406 jmp process_macro_line
2407 macro_block_processed:
2408 call close_macro_block
2409 jc process_macro_line
2410 pop [current_line]
2411 add esp,12
2412 pop [macro_block_line_number]
2413 pop [macro_block_line]
2414 pop [macro_block]
2415 pop [counter]
2416 pop eax
2417 and al,0F0h
2418 and [macro_status],0Fh
2419 or [macro_status],al
2420 ret
2421
2422 local_symbols:
2423 lods byte [esi]
2424 cmp al,1Ah
2425 jne invalid_argument
2426 mov byte [edi-1],3Bh
2427 xor al,al
2428 stos byte [edi]
2429 make_local_symbol:
2430 push ecx
2431 lods byte [esi]
2432 movzx ecx,al
2433 mov eax,[counter]
2434 call add_macro_symbol
2435 mov [edx+12],edi
2436 movzx eax,[locals_counter]
2437 add eax,ecx
2438 inc eax
2439 cmp eax,100h
2440 jae name_too_long
2441 lea ebp,[edi+2+eax]
2442 cmp ebp,[memory_end]
2443 jae out_of_memory
2444 mov ah,al
2445 mov al,1Ah
2446 stos word [edi]
2447 rep movs byte [edi],[esi]
2448 mov al,'?'
2449 stos byte [edi]
2450 push esi
2451 mov esi,locals_counter+1
2452 movzx ecx,[locals_counter]
2453 rep movs byte [edi],[esi]
2454 pop esi
2455 mov eax,edi
2456 sub eax,[edx+12]
2457 mov [edx+8],eax
2458 xor al,al
2459 stos byte [edi]
2460 mov eax,locals_counter
2461 movzx ecx,byte [eax]
2462 counter_loop:
2463 inc byte [eax+ecx]
2464 cmp byte [eax+ecx],'9'+1
2465 jb counter_ok
2466 jne letter_digit
2467 mov byte [eax+ecx],'A'
2468 jmp counter_ok
2469 letter_digit:
2470 cmp byte [eax+ecx],'Z'+1
2471 jb counter_ok
2472 jne small_letter_digit
2473 mov byte [eax+ecx],'a'
2474 jmp counter_ok
2475 small_letter_digit:
2476 cmp byte [eax+ecx],'z'+1
2477 jb counter_ok
2478 mov byte [eax+ecx],'0'
2479 loop counter_loop
2480 inc byte [eax]
2481 movzx ecx,byte [eax]
2482 mov byte [eax+ecx],'0'
2483 counter_ok:
2484 pop ecx
2485 lods byte [esi]
2486 cmp al,'}'
2487 je macro_block_processed
2488 or al,al
2489 jz process_next_line
2490 cmp al,','
2491 jne extra_characters_on_line
2492 dec edi
2493 lods byte [esi]
2494 cmp al,1Ah
2495 je make_local_symbol
2496 jmp invalid_argument
2497 common_block:
2498 call close_macro_block
2499 jc process_macro_line
2500 mov [counter],0
2501 jmp new_macro_block
2502 forward_block:
2503 cmp [counter_limit],0
2504 je common_block
2505 call close_macro_block
2506 jc process_macro_line
2507 mov [counter],1
2508 jmp new_macro_block
2509 reverse_block:
2510 cmp [counter_limit],0
2511 je common_block
2512 call close_macro_block
2513 jc process_macro_line
2514 mov eax,[counter_limit]
2515 or eax,80000000h
2516 mov [counter],eax
2517 new_macro_block:
2518 mov [macro_block],esi
2519 mov eax,[macro_line]
2520 mov [macro_block_line],eax
2521 mov [macro_block_line_number],ecx
2522 jmp process_macro_line
2523 close_macro_block:
2524 cmp esi,[macro_block]
2525 je block_closed
2526 cmp [counter],0
2527 je block_closed
2528 jl reverse_counter
2529 mov eax,[counter]
2530 cmp eax,[counter_limit]
2531 je block_closed
2532 inc [counter]
2533 jmp continue_block
2534 reverse_counter:
2535 mov eax,[counter]
2536 dec eax
2537 cmp eax,80000000h
2538 je block_closed
2539 mov [counter],eax
2540 continue_block:
2541 mov esi,[macro_block]
2542 mov eax,[macro_block_line]
2543 mov [macro_line],eax
2544 mov ecx,[macro_block_line_number]
2545 stc
2546 ret
2547 block_closed:
2548 clc
2549 ret
2550 get_macro_symbol:
2551 push ecx
2552 call find_macro_symbol_leaf
2553 jc macro_symbol_not_found
2554 mov edx,[ebx]
2555 mov ebx,esi
2556 try_macro_symbol:
2557 or edx,edx
2558 jz macro_symbol_not_found
2559 mov ecx,[esp]
2560 mov edi,[edx+4]
2561 repe cmps byte [esi],[edi]
2562 je macro_symbol_found
2563 mov esi,ebx
2564 mov edx,[edx]
2565 jmp try_macro_symbol
2566 macro_symbol_found:
2567 pop ecx
2568 clc
2569 ret
2570 macro_symbol_not_found:
2571 pop ecx
2572 stc
2573 ret
2574 find_macro_symbol_leaf:
2575 shl eax,8
2576 mov al,cl
2577 mov ebp,eax
2578 mov ebx,macro_symbols
2579 follow_macro_symbols_tree:
2580 mov edx,[ebx]
2581 or edx,edx
2582 jz no_such_macro_symbol
2583 xor eax,eax
2584 shr ebp,1
2585 adc eax,0
2586 lea ebx,[edx+eax*4]
2587 or ebp,ebp
2588 jnz follow_macro_symbols_tree
2589 add ebx,8
2590 clc
2591 ret
2592 no_such_macro_symbol:
2593 stc
2594 ret
2595 add_macro_symbol:
2596 push ebx ebp
2597 call find_macro_symbol_leaf
2598 jc extend_macro_symbol_tree
2599 mov eax,[ebx]
2600 make_macro_symbol:
2601 mov edx,[free_additional_memory]
2602 add edx,16
2603 cmp edx,[labels_list]
2604 ja out_of_memory
2605 xchg edx,[free_additional_memory]
2606 mov [ebx],edx
2607 mov [edx],eax
2608 mov [edx+4],esi
2609 pop ebp ebx
2610 ret
2611 extend_macro_symbol_tree:
2612 mov edx,[free_additional_memory]
2613 add edx,16
2614 cmp edx,[labels_list]
2615 ja out_of_memory
2616 xchg edx,[free_additional_memory]
2617 xor eax,eax
2618 mov [edx],eax
2619 mov [edx+4],eax
2620 mov [edx+8],eax
2621 mov [edx+12],eax
2622 shr ebp,1
2623 adc eax,0
2624 mov [ebx],edx
2625 lea ebx,[edx+eax*4]
2626 or ebp,ebp
2627 jnz extend_macro_symbol_tree
2628 add ebx,8
2629 xor eax,eax
2630 jmp make_macro_symbol
2631
2632 include_file:
2633 lods byte [esi]
2634 cmp al,22h
2635 jne invalid_argument
2636 lods dword [esi]
2637 cmp byte [esi+eax],0
2638 jne extra_characters_on_line
2639 push esi
2640 push edi
2641 mov ebx,[current_line]
2642 find_current_file_path:
2643 mov esi,[ebx]
2644 test byte [ebx+7],80h
2645 jz copy_current_file_path
2646 mov ebx,[ebx+8]
2647 jmp find_current_file_path
2648 copy_current_file_path:
2649 lods byte [esi]
2650 stos byte [edi]
2651 or al,al
2652 jnz copy_current_file_path
2653 cut_current_file_name:
2654 cmp edi,[esp]
2655 je current_file_path_ok
2656 cmp byte [edi-1],'\'
2657 je current_file_path_ok
2658 cmp byte [edi-1],'/'
2659 je current_file_path_ok
2660 dec edi
2661 jmp cut_current_file_name
2662 current_file_path_ok:
2663 mov esi,[esp+4]
2664 call expand_path
2665 pop edx
2666 mov esi,edx
2667 call open
2668 jnc include_path_ok
2669 mov ebp,[include_paths]
2670 try_include_directories:
2671 mov edi,esi
2672 mov esi,ebp
2673 cmp byte [esi],0
2674 je try_in_current_directory
2675 push ebp
2676 push edi
2677 call get_include_directory
2678 mov [esp+4],esi
2679 mov esi,[esp+8]
2680 call expand_path
2681 pop edx
2682 mov esi,edx
2683 call open
2684 pop ebp
2685 jnc include_path_ok
2686 jmp try_include_directories
2687 mov edi,esi
2688 try_in_current_directory:
2689 mov esi,[esp]
2690 push edi
2691 call expand_path
2692 pop edx
2693 mov esi,edx
2694 call open
2695 jc file_not_found
2696 include_path_ok:
2697 mov edi,[esp]
2698 copy_preprocessed_path:
2699 lods byte [esi]
2700 stos byte [edi]
2701 or al,al
2702 jnz copy_preprocessed_path
2703 pop esi
2704 lea ecx,[edi-1]
2705 sub ecx,esi
2706 mov [esi-4],ecx
2707 push dword [macro_status]
2708 and [macro_status],0Fh
2709 call preprocess_file
2710 pop eax
2711 and al,0F0h
2712 and [macro_status],0Fh
2713 or [macro_status],al
2714 jmp line_preprocessed
0
1 ; flat assembler core
2 ; Copyright (c) 1999-2014, Tomasz Grysztar.
3 ; All rights reserved.
4
5 dump_symbols:
6 mov edi,[code_start]
7 call setup_dump_header
8 mov esi,[input_file]
9 call copy_asciiz
10 cmp edi,[tagged_blocks]
11 jae out_of_memory
12 mov eax,edi
13 sub eax,ebx
14 mov [ebx-40h+0Ch],eax
15 mov esi,[output_file]
16 call copy_asciiz
17 cmp edi,[tagged_blocks]
18 jae out_of_memory
19 mov edx,[symbols_stream]
20 mov ebp,[free_additional_memory]
21 and [number_of_sections],0
22 cmp [output_format],4
23 je prepare_strings_table
24 cmp [output_format],5
25 jne strings_table_ready
26 bt [format_flags],0
27 jc strings_table_ready
28 prepare_strings_table:
29 cmp edx,ebp
30 je strings_table_ready
31 mov al,[edx]
32 test al,al
33 jz prepare_string
34 cmp al,80h
35 je prepare_string
36 add edx,0Ch
37 cmp al,0C0h
38 jb prepare_strings_table
39 add edx,4
40 jmp prepare_strings_table
41 prepare_string:
42 mov esi,edi
43 sub esi,ebx
44 xchg esi,[edx+4]
45 test al,al
46 jz prepare_section_string
47 or dword [edx+4],1 shl 31
48 add edx,0Ch
49 prepare_external_string:
50 mov ecx,[esi]
51 add esi,4
52 rep movs byte [edi],[esi]
53 mov byte [edi],0
54 inc edi
55 cmp edi,[tagged_blocks]
56 jae out_of_memory
57 jmp prepare_strings_table
58 prepare_section_string:
59 mov ecx,[number_of_sections]
60 mov eax,ecx
61 inc eax
62 mov [number_of_sections],eax
63 xchg eax,[edx+4]
64 shl ecx,2
65 add ecx,[free_additional_memory]
66 mov [ecx],eax
67 add edx,20h
68 test esi,esi
69 jz prepare_default_section_string
70 cmp [output_format],5
71 jne prepare_external_string
72 bt [format_flags],0
73 jc prepare_external_string
74 mov esi,[esi]
75 add esi,[resource_data]
76 copy_elf_section_name:
77 lods byte [esi]
78 cmp edi,[tagged_blocks]
79 jae out_of_memory
80 stos byte [edi]
81 test al,al
82 jnz copy_elf_section_name
83 jmp prepare_strings_table
84 prepare_default_section_string:
85 mov eax,'.fla'
86 stos dword [edi]
87 mov ax,'t'
88 stos word [edi]
89 cmp edi,[tagged_blocks]
90 jae out_of_memory
91 jmp prepare_strings_table
92 strings_table_ready:
93 mov edx,[tagged_blocks]
94 mov ebp,[memory_end]
95 sub ebp,[labels_list]
96 add ebp,edx
97 prepare_labels_dump:
98 cmp edx,ebp
99 je labels_dump_ok
100 mov eax,[edx+24]
101 test eax,eax
102 jz label_dump_name_ok
103 cmp eax,[memory_start]
104 jb label_name_outside_source
105 cmp eax,[source_start]
106 ja label_name_outside_source
107 sub eax,[memory_start]
108 dec eax
109 mov [edx+24],eax
110 jmp label_dump_name_ok
111 label_name_outside_source:
112 mov esi,eax
113 mov eax,edi
114 sub eax,ebx
115 or eax,1 shl 31
116 mov [edx+24],eax
117 movzx ecx,byte [esi-1]
118 lea eax,[edi+ecx+1]
119 cmp edi,[tagged_blocks]
120 jae out_of_memory
121 rep movsb
122 xor al,al
123 stosb
124 label_dump_name_ok:
125 mov eax,[edx+28]
126 test eax,eax
127 jz label_dump_line_ok
128 sub eax,[memory_start]
129 mov [edx+28],eax
130 label_dump_line_ok:
131 test byte [edx+9],4
132 jz convert_base_symbol_for_label
133 xor eax,eax
134 mov [edx],eax
135 mov [edx+4],eax
136 jmp base_symbol_for_label_ok
137 convert_base_symbol_for_label:
138 mov eax,[edx+20]
139 test eax,eax
140 jz base_symbol_for_label_ok
141 cmp eax,[symbols_stream]
142 mov eax,[eax+4]
143 jae base_symbol_for_label_ok
144 xor eax,eax
145 base_symbol_for_label_ok:
146 mov [edx+20],eax
147 mov ax,[current_pass]
148 cmp ax,[edx+16]
149 je label_defined_flag_ok
150 and byte [edx+8],not 1
151 label_defined_flag_ok:
152 cmp ax,[edx+18]
153 je label_used_flag_ok
154 and byte [edx+8],not 8
155 label_used_flag_ok:
156 add edx,LABEL_STRUCTURE_SIZE
157 jmp prepare_labels_dump
158 labels_dump_ok:
159 mov eax,edi
160 sub eax,ebx
161 mov [ebx-40h+14h],eax
162 add eax,40h
163 mov [ebx-40h+18h],eax
164 mov ecx,[memory_end]
165 sub ecx,[labels_list]
166 mov [ebx-40h+1Ch],ecx
167 add eax,ecx
168 mov [ebx-40h+20h],eax
169 mov ecx,[source_start]
170 sub ecx,[memory_start]
171 mov [ebx-40h+24h],ecx
172 add eax,ecx
173 mov [ebx-40h+28h],eax
174 mov eax,[number_of_sections]
175 shl eax,2
176 mov [ebx-40h+34h],eax
177 call prepare_preprocessed_source
178 mov esi,[labels_list]
179 mov ebp,edi
180 make_lines_dump:
181 cmp esi,[tagged_blocks]
182 je lines_dump_ok
183 mov eax,[esi-4]
184 mov ecx,[esi-8]
185 sub esi,8
186 sub esi,ecx
187 cmp eax,1
188 je process_line_dump
189 cmp eax,2
190 jne make_lines_dump
191 add dword [ebx-40h+3Ch],8
192 jmp make_lines_dump
193 process_line_dump:
194 push ebx
195 mov ebx,[esi+8]
196 mov eax,[esi+4]
197 sub eax,[code_start]
198 add eax,[headers_size]
199 test byte [ebx+0Ah],1
200 jz store_offset
201 xor eax,eax
202 store_offset:
203 stos dword [edi]
204 mov eax,[esi]
205 sub eax,[memory_start]
206 stos dword [edi]
207 mov eax,[esi+4]
208 xor edx,edx
209 xor cl,cl
210 sub eax,[ebx]
211 sbb edx,[ebx+4]
212 sbb cl,[ebx+8]
213 stos dword [edi]
214 mov eax,edx
215 stos dword [edi]
216 mov eax,[ebx+10h]
217 stos dword [edi]
218 mov eax,[ebx+14h]
219 test eax,eax
220 jz base_symbol_for_line_ok
221 cmp eax,[symbols_stream]
222 mov eax,[eax+4]
223 jae base_symbol_for_line_ok
224 xor eax,eax
225 base_symbol_for_line_ok:
226 stos dword [edi]
227 mov al,[ebx+9]
228 stos byte [edi]
229 mov al,[esi+10h]
230 stos byte [edi]
231 mov al,[ebx+0Ah]
232 and al,1
233 stos byte [edi]
234 mov al,cl
235 stos byte [edi]
236 pop ebx
237 cmp edi,[tagged_blocks]
238 jae out_of_memory
239 mov eax,edi
240 sub eax,1Ch
241 sub eax,ebp
242 mov [esi],eax
243 jmp make_lines_dump
244 lines_dump_ok:
245 mov edx,edi
246 mov eax,[current_offset]
247 sub eax,[code_start]
248 add eax,[headers_size]
249 stos dword [edi]
250 mov ecx,edi
251 sub ecx,ebx
252 sub ecx,[ebx-40h+14h]
253 mov [ebx-40h+2Ch],ecx
254 add ecx,[ebx-40h+28h]
255 mov [ebx-40h+30h],ecx
256 add ecx,[ebx-40h+34h]
257 mov [ebx-40h+38h],ecx
258 find_inexisting_offsets:
259 sub edx,1Ch
260 cmp edx,ebp
261 jb write_symbols
262 test byte [edx+1Ah],1
263 jnz find_inexisting_offsets
264 cmp eax,[edx]
265 jb correct_inexisting_offset
266 mov eax,[edx]
267 jmp find_inexisting_offsets
268 correct_inexisting_offset:
269 and dword [edx],0
270 or byte [edx+1Ah],2
271 jmp find_inexisting_offsets
272 write_symbols:
273 mov edx,[symbols_file]
274 call create
275 jc write_failed
276 mov edx,[code_start]
277 mov ecx,[edx+14h]
278 add ecx,40h
279 call write
280 jc write_failed
281 mov edx,[tagged_blocks]
282 mov ecx,[memory_end]
283 sub ecx,[labels_list]
284 call write
285 jc write_failed
286 mov edx,[memory_start]
287 mov ecx,[source_start]
288 sub ecx,edx
289 call write
290 jc write_failed
291 mov edx,ebp
292 mov ecx,edi
293 sub ecx,edx
294 call write
295 jc write_failed
296 mov edx,[free_additional_memory]
297 mov ecx,[number_of_sections]
298 shl ecx,2
299 call write
300 jc write_failed
301 mov esi,[labels_list]
302 mov edi,[memory_start]
303 make_references_dump:
304 cmp esi,[tagged_blocks]
305 je references_dump_ok
306 mov eax,[esi-4]
307 mov ecx,[esi-8]
308 sub esi,8
309 sub esi,ecx
310 cmp eax,2
311 je dump_reference
312 cmp eax,1
313 jne make_references_dump
314 mov edx,[esi]
315 jmp make_references_dump
316 dump_reference:
317 mov eax,[memory_end]
318 sub eax,[esi]
319 sub eax,LABEL_STRUCTURE_SIZE
320 stosd
321 mov eax,edx
322 stosd
323 cmp edi,[tagged_blocks]
324 jb make_references_dump
325 jmp out_of_memory
326 references_dump_ok:
327 mov edx,[memory_start]
328 mov ecx,edi
329 sub ecx,edx
330 call write
331 jc write_failed
332 call close
333 ret
334 setup_dump_header:
335 xor eax,eax
336 mov ecx,40h shr 2
337 rep stos dword [edi]
338 mov ebx,edi
339 mov dword [ebx-40h],'fas'+1Ah shl 24
340 mov dword [ebx-40h+4],VERSION_MAJOR + VERSION_MINOR shl 8 + 40h shl 16
341 mov dword [ebx-40h+10h],40h
342 ret
343 prepare_preprocessed_source:
344 mov esi,[memory_start]
345 mov ebp,[source_start]
346 test ebp,ebp
347 jnz prepare_preprocessed_line
348 mov ebp,[current_line]
349 inc ebp
350 prepare_preprocessed_line:
351 cmp esi,ebp
352 jae preprocessed_source_ok
353 mov eax,[memory_start]
354 mov edx,[input_file]
355 cmp [esi],edx
356 jne line_not_from_main_input
357 mov [esi],eax
358 line_not_from_main_input:
359 sub [esi],eax
360 test byte [esi+7],1 shl 7
361 jz prepare_next_preprocessed_line
362 sub [esi+8],eax
363 sub [esi+12],eax
364 prepare_next_preprocessed_line:
365 call skip_preprocessed_line
366 jmp prepare_preprocessed_line
367 preprocessed_source_ok:
368 ret
369 skip_preprocessed_line:
370 add esi,16
371 skip_preprocessed_line_content:
372 lods byte [esi]
373 cmp al,1Ah
374 je skip_preprocessed_symbol
375 cmp al,3Bh
376 je skip_preprocessed_symbol
377 cmp al,22h
378 je skip_preprocessed_string
379 or al,al
380 jnz skip_preprocessed_line_content
381 ret
382 skip_preprocessed_string:
383 lods dword [esi]
384 add esi,eax
385 jmp skip_preprocessed_line_content
386 skip_preprocessed_symbol:
387 lods byte [esi]
388 movzx eax,al
389 add esi,eax
390 jmp skip_preprocessed_line_content
391 restore_preprocessed_source:
392 mov esi,[memory_start]
393 mov ebp,[source_start]
394 test ebp,ebp
395 jnz restore_preprocessed_line
396 mov ebp,[current_line]
397 inc ebp
398 restore_preprocessed_line:
399 cmp esi,ebp
400 jae preprocessed_source_restored
401 mov eax,[memory_start]
402 add [esi],eax
403 cmp [esi],eax
404 jne preprocessed_line_source_restored
405 mov edx,[input_file]
406 mov [esi],edx
407 preprocessed_line_source_restored:
408 test byte [esi+7],1 shl 7
409 jz restore_next_preprocessed_line
410 add [esi+8],eax
411 add [esi+12],eax
412 restore_next_preprocessed_line:
413 call skip_preprocessed_line
414 jmp restore_preprocessed_line
415 preprocessed_source_restored:
416 ret
417 dump_preprocessed_source:
418 mov edi,[free_additional_memory]
419 call setup_dump_header
420 mov esi,[input_file]
421 call copy_asciiz
422 cmp edi,[additional_memory_end]
423 jae out_of_memory
424 mov eax,edi
425 sub eax,ebx
426 dec eax
427 mov [ebx-40h+0Ch],eax
428 mov eax,edi
429 sub eax,ebx
430 mov [ebx-40h+14h],eax
431 add eax,40h
432 mov [ebx-40h+20h],eax
433 call prepare_preprocessed_source
434 sub esi,[memory_start]
435 mov [ebx-40h+24h],esi
436 mov edx,[symbols_file]
437 call create
438 jc write_failed
439 mov edx,[free_additional_memory]
440 mov ecx,[edx+14h]
441 add ecx,40h
442 call write
443 jc write_failed
444 mov edx,[memory_start]
445 mov ecx,esi
446 call write
447 jc write_failed
448 call close
449 ret
0
1 ; flat assembler core
2 ; Copyright (c) 1999-2014, Tomasz Grysztar.
3 ; All rights reserved.
4
5 include_variable db 'INCLUDE',0
6
7 symbol_characters db 27
8 db 9,0Ah,0Dh,1Ah,20h,'+-/*=<>()[]{}:,|&~#`;\'
9
10 preprocessor_directives:
11 db 6,'define'
12 dw define_symbolic_constant-directive_handler
13 db 7,'include'
14 dw include_file-directive_handler
15 db 3,'irp'
16 dw irp_directive-directive_handler
17 db 4,'irps'
18 dw irps_directive-directive_handler
19 db 4,'irpv'
20 dw irpv_directive-directive_handler
21 db 5,'macro'
22 dw define_macro-directive_handler
23 db 5,'match'
24 dw match_directive-directive_handler
25 db 8,'postpone'
26 dw postpone_directive-directive_handler
27 db 5,'purge'
28 dw purge_macro-directive_handler
29 db 4,'rept'
30 dw rept_directive-directive_handler
31 db 7,'restore'
32 dw restore_equ_constant-directive_handler
33 db 7,'restruc'
34 dw purge_struc-directive_handler
35 db 5,'struc'
36 dw define_struc-directive_handler
37 db 0
38
39 macro_directives:
40 db 6,'common'
41 dw common_block-directive_handler
42 db 7,'forward'
43 dw forward_block-directive_handler
44 db 5,'local'
45 dw local_symbols-directive_handler
46 db 7,'reverse'
47 dw reverse_block-directive_handler
48 db 0
49
50 operators:
51 db 1,'+',80h
52 db 1,'-',81h
53 db 1,'*',90h
54 db 1,'/',91h
55 db 3,'and',0B0h
56 db 3,'mod',0A0h
57 db 2,'or',0B1h
58 db 3,'shl',0C0h
59 db 3,'shr',0C1h
60 db 3,'xor',0B2h
61 db 0
62
63 single_operand_operators:
64 db 1,'+',82h
65 db 1,'-',83h
66 db 3,'not',0D0h
67 db 3,'plt',0E1h
68 db 3,'rva',0E0h
69 db 0
70
71 directive_operators:
72 db 5,'align',8Ch
73 db 2,'as',86h
74 db 2,'at',80h
75 db 7,'defined',88h
76 db 3,'dup',81h
77 db 2,'eq',0F0h
78 db 6,'eqtype',0F7h
79 db 4,'from',82h
80 db 2,'in',0F6h
81 db 2,'on',84h
82 db 3,'ptr',85h
83 db 10,'relativeto',0F8h
84 db 4,'used',89h
85 db 0
86
87 address_sizes:
88 db 4,'byte',1
89 db 5,'dword',4
90 db 5,'qword',8
91 db 4,'word',2
92 db 0
93
94 symbols:
95 dw symbols_2-symbols,(symbols_3-symbols_2)/(2+2)
96 dw symbols_3-symbols,(symbols_4-symbols_3)/(3+2)
97 dw symbols_4-symbols,(symbols_5-symbols_4)/(4+2)
98 dw symbols_5-symbols,(symbols_6-symbols_5)/(5+2)
99 dw symbols_6-symbols,(symbols_7-symbols_6)/(6+2)
100 dw symbols_7-symbols,(symbols_8-symbols_7)/(7+2)
101 dw symbols_8-symbols,(symbols_9-symbols_8)/(8+2)
102 dw symbols_9-symbols,(symbols_10-symbols_9)/(9+2)
103 dw symbols_10-symbols,(symbols_11-symbols_10)/(10+2)
104 dw symbols_11-symbols,(symbols_end-symbols_11)/(11+2)
105
106 symbols_2:
107 db 'ah',10h,04h
108 db 'al',10h,10h
109 db 'ax',10h,20h
110 db 'bh',10h,07h
111 db 'bl',10h,13h
112 db 'bp',10h,25h
113 db 'bx',10h,23h
114 db 'ch',10h,05h
115 db 'cl',10h,11h
116 db 'cs',10h,62h
117 db 'cx',10h,21h
118 db 'dh',10h,06h
119 db 'di',10h,27h
120 db 'dl',10h,12h
121 db 'ds',10h,64h
122 db 'dx',10h,22h
123 db 'es',10h,61h
124 db 'fs',10h,65h
125 db 'gs',10h,66h
126 db 'ms',1Ch,41h
127 db 'mz',18h,20h
128 db 'nx',1Bh,83h
129 db 'pe',18h,30h
130 db 'r8',10h,88h
131 db 'r9',10h,89h
132 db 'si',10h,26h
133 db 'sp',10h,24h
134 db 'ss',10h,63h
135 db 'st',10h,0A0h
136 symbols_3:
137 db 'bpl',10h,15h
138 db 'cr0',10h,50h
139 db 'cr1',10h,51h
140 db 'cr2',10h,52h
141 db 'cr3',10h,53h
142 db 'cr4',10h,54h
143 db 'cr5',10h,55h
144 db 'cr6',10h,56h
145 db 'cr7',10h,57h
146 db 'cr8',10h,58h
147 db 'cr9',10h,59h
148 db 'dil',10h,17h
149 db 'dll',1Bh,80h
150 db 'dr0',10h,70h
151 db 'dr1',10h,71h
152 db 'dr2',10h,72h
153 db 'dr3',10h,73h
154 db 'dr4',10h,74h
155 db 'dr5',10h,75h
156 db 'dr6',10h,76h
157 db 'dr7',10h,77h
158 db 'dr8',10h,78h
159 db 'dr9',10h,79h
160 db 'eax',10h,40h
161 db 'ebp',10h,45h
162 db 'ebx',10h,43h
163 db 'ecx',10h,41h
164 db 'edi',10h,47h
165 db 'edx',10h,42h
166 db 'efi',1Bh,10
167 db 'eip',10h,0F4h
168 db 'elf',18h,50h
169 db 'esi',10h,46h
170 db 'esp',10h,44h
171 db 'far',12h,3
172 db 'gui',1Bh,2
173 db 'mm0',10h,0B0h
174 db 'mm1',10h,0B1h
175 db 'mm2',10h,0B2h
176 db 'mm3',10h,0B3h
177 db 'mm4',10h,0B4h
178 db 'mm5',10h,0B5h
179 db 'mm6',10h,0B6h
180 db 'mm7',10h,0B7h
181 db 'r10',10h,8Ah
182 db 'r11',10h,8Bh
183 db 'r12',10h,8Ch
184 db 'r13',10h,8Dh
185 db 'r14',10h,8Eh
186 db 'r15',10h,8Fh
187 db 'r8b',10h,18h
188 db 'r8d',10h,48h
189 db 'r8l',10h,18h
190 db 'r8w',10h,28h
191 db 'r9b',10h,19h
192 db 'r9d',10h,49h
193 db 'r9l',10h,19h
194 db 'r9w',10h,29h
195 db 'rax',10h,80h
196 db 'rbp',10h,85h
197 db 'rbx',10h,83h
198 db 'rcx',10h,81h
199 db 'rdi',10h,87h
200 db 'rdx',10h,82h
201 db 'rip',10h,0F8h
202 db 'rsi',10h,86h
203 db 'rsp',10h,84h
204 db 'sil',10h,16h
205 db 'spl',10h,14h
206 db 'st0',10h,0A0h
207 db 'st1',10h,0A1h
208 db 'st2',10h,0A2h
209 db 'st3',10h,0A3h
210 db 'st4',10h,0A4h
211 db 'st5',10h,0A5h
212 db 'st6',10h,0A6h
213 db 'st7',10h,0A7h
214 db 'tr0',10h,90h
215 db 'tr1',10h,91h
216 db 'tr2',10h,92h
217 db 'tr3',10h,93h
218 db 'tr4',10h,94h
219 db 'tr5',10h,95h
220 db 'tr6',10h,96h
221 db 'tr7',10h,97h
222 db 'wdm',1Bh,81h
223 symbols_4:
224 db 'byte',11h,1
225 db 'code',19h,5
226 db 'coff',18h,40h
227 db 'cr10',10h,5Ah
228 db 'cr11',10h,5Bh
229 db 'cr12',10h,5Ch
230 db 'cr13',10h,5Dh
231 db 'cr14',10h,5Eh
232 db 'cr15',10h,5Fh
233 db 'data',19h,6
234 db 'dr10',10h,7Ah
235 db 'dr11',10h,7Bh
236 db 'dr12',10h,7Ch
237 db 'dr13',10h,7Dh
238 db 'dr14',10h,7Eh
239 db 'dr15',10h,7Fh
240 db 'ms64',1Ch,49h
241 db 'near',12h,2
242 db 'note',1Eh,4
243 db 'pe64',18h,3Ch
244 db 'r10b',10h,1Ah
245 db 'r10d',10h,4Ah
246 db 'r10l',10h,1Ah
247 db 'r10w',10h,2Ah
248 db 'r11b',10h,1Bh
249 db 'r11d',10h,4Bh
250 db 'r11l',10h,1Bh
251 db 'r11w',10h,2Bh
252 db 'r12b',10h,1Ch
253 db 'r12d',10h,4Ch
254 db 'r12l',10h,1Ch
255 db 'r12w',10h,2Ch
256 db 'r13b',10h,1Dh
257 db 'r13d',10h,4Dh
258 db 'r13l',10h,1Dh
259 db 'r13w',10h,2Dh
260 db 'r14b',10h,1Eh
261 db 'r14d',10h,4Eh
262 db 'r14l',10h,1Eh
263 db 'r14w',10h,2Eh
264 db 'r15b',10h,1Fh
265 db 'r15d',10h,4Fh
266 db 'r15l',10h,1Fh
267 db 'r15w',10h,2Fh
268 db 'word',11h,2
269 db 'xmm0',10h,0C0h
270 db 'xmm1',10h,0C1h
271 db 'xmm2',10h,0C2h
272 db 'xmm3',10h,0C3h
273 db 'xmm4',10h,0C4h
274 db 'xmm5',10h,0C5h
275 db 'xmm6',10h,0C6h
276 db 'xmm7',10h,0C7h
277 db 'xmm8',10h,0C8h
278 db 'xmm9',10h,0C9h
279 db 'ymm0',10h,0D0h
280 db 'ymm1',10h,0D1h
281 db 'ymm2',10h,0D2h
282 db 'ymm3',10h,0D3h
283 db 'ymm4',10h,0D4h
284 db 'ymm5',10h,0D5h
285 db 'ymm6',10h,0D6h
286 db 'ymm7',10h,0D7h
287 db 'ymm8',10h,0D8h
288 db 'ymm9',10h,0D9h
289 symbols_5:
290 db 'dword',11h,4
291 db 'elf64',18h,58h
292 db 'fword',11h,6
293 db 'large',1Bh,82h
294 db 'pword',11h,6
295 db 'qword',11h,8
296 db 'short',12h,1
297 db 'tbyte',11h,0Ah
298 db 'tword',11h,0Ah
299 db 'use16',13h,16
300 db 'use32',13h,32
301 db 'use64',13h,64
302 db 'xmm10',10h,0CAh
303 db 'xmm11',10h,0CBh
304 db 'xmm12',10h,0CCh
305 db 'xmm13',10h,0CDh
306 db 'xmm14',10h,0CEh
307 db 'xmm15',10h,0CFh
308 db 'xword',11h,16
309 db 'ymm10',10h,0DAh
310 db 'ymm11',10h,0DBh
311 db 'ymm12',10h,0DCh
312 db 'ymm13',10h,0DDh
313 db 'ymm14',10h,0DEh
314 db 'ymm15',10h,0DFh
315 db 'yword',11h,32
316 symbols_6:
317 db 'binary',18h,10h
318 db 'dqword',11h,16
319 db 'export',1Ah,0
320 db 'fixups',1Ah,5
321 db 'import',1Ah,1
322 db 'native',1Bh,1
323 db 'qqword',11h,32
324 db 'static',1Dh,1
325 symbols_7:
326 db 'console',1Bh,3
327 db 'dynamic',1Eh,2
328 db 'efiboot',1Bh,11
329 symbols_8:
330 db 'linkinfo',19h,9
331 db 'readable',19h,30
332 db 'resource',1Ah,2
333 db 'writable',19h,31
334 symbols_9:
335 db 'shareable',19h,28
336 db 'writeable',19h,31
337 symbols_10:
338 db 'efiruntime',1Bh,12
339 db 'executable',19h,29
340 db 'linkremove',19h,11
341 symbols_11:
342 db 'discardable',19h,25
343 db 'interpreter',1Eh,3
344 db 'notpageable',19h,27
345 symbols_end:
346
347 instructions:
348 dw instructions_2-instructions,(instructions_3-instructions_2)/(2+3)
349 dw instructions_3-instructions,(instructions_4-instructions_3)/(3+3)
350 dw instructions_4-instructions,(instructions_5-instructions_4)/(4+3)
351 dw instructions_5-instructions,(instructions_6-instructions_5)/(5+3)
352 dw instructions_6-instructions,(instructions_7-instructions_6)/(6+3)
353 dw instructions_7-instructions,(instructions_8-instructions_7)/(7+3)
354 dw instructions_8-instructions,(instructions_9-instructions_8)/(8+3)
355 dw instructions_9-instructions,(instructions_10-instructions_9)/(9+3)
356 dw instructions_10-instructions,(instructions_11-instructions_10)/(10+3)
357 dw instructions_11-instructions,(instructions_12-instructions_11)/(11+3)
358 dw instructions_12-instructions,(instructions_13-instructions_12)/(12+3)
359 dw instructions_13-instructions,(instructions_14-instructions_13)/(13+3)
360 dw instructions_14-instructions,(instructions_15-instructions_14)/(14+3)
361 dw instructions_15-instructions,(instructions_16-instructions_15)/(15+3)
362 dw instructions_16-instructions,(instructions_end-instructions_16)/(16+3)
363
364 instructions_2:
365 db 'bt',4
366 dw bt_instruction-instruction_handler
367 db 'if',0
368 dw if_directive-instruction_handler
369 db 'in',0
370 dw in_instruction-instruction_handler
371 db 'ja',77h
372 dw conditional_jump-instruction_handler
373 db 'jb',72h
374 dw conditional_jump-instruction_handler
375 db 'jc',72h
376 dw conditional_jump-instruction_handler
377 db 'je',74h
378 dw conditional_jump-instruction_handler
379 db 'jg',7Fh
380 dw conditional_jump-instruction_handler
381 db 'jl',7Ch
382 dw conditional_jump-instruction_handler
383 db 'jo',70h
384 dw conditional_jump-instruction_handler
385 db 'jp',7Ah
386 dw conditional_jump-instruction_handler
387 db 'js',78h
388 dw conditional_jump-instruction_handler
389 db 'jz',74h
390 dw conditional_jump-instruction_handler
391 db 'or',08h
392 dw basic_instruction-instruction_handler
393 instructions_3:
394 db 'aaa',37h
395 dw simple_instruction_except64-instruction_handler
396 db 'aad',0D5h
397 dw aa_instruction-instruction_handler
398 db 'aam',0D4h
399 dw aa_instruction-instruction_handler
400 db 'aas',3Fh
401 dw simple_instruction_except64-instruction_handler
402 db 'adc',10h
403 dw basic_instruction-instruction_handler
404 db 'add',00h
405 dw basic_instruction-instruction_handler
406 db 'and',20h
407 dw basic_instruction-instruction_handler
408 db 'bsf',0BCh
409 dw bs_instruction-instruction_handler
410 db 'bsr',0BDh
411 dw bs_instruction-instruction_handler
412 db 'btc',7
413 dw bt_instruction-instruction_handler
414 db 'btr',6
415 dw bt_instruction-instruction_handler
416 db 'bts',5
417 dw bt_instruction-instruction_handler
418 db 'cbw',98h
419 dw simple_instruction_16bit-instruction_handler
420 db 'cdq',99h
421 dw simple_instruction_32bit-instruction_handler
422 db 'clc',0F8h
423 dw simple_instruction-instruction_handler
424 db 'cld',0FCh
425 dw simple_instruction-instruction_handler
426 db 'cli',0FAh
427 dw simple_instruction-instruction_handler
428 db 'cmc',0F5h
429 dw simple_instruction-instruction_handler
430 db 'cmp',38h
431 dw basic_instruction-instruction_handler
432 db 'cqo',99h
433 dw simple_instruction_64bit-instruction_handler
434 db 'cwd',99h
435 dw simple_instruction_16bit-instruction_handler
436 db 'daa',27h
437 dw simple_instruction_except64-instruction_handler
438 db 'das',2Fh
439 dw simple_instruction_except64-instruction_handler
440 db 'dec',1
441 dw inc_instruction-instruction_handler
442 db 'div',6
443 dw single_operand_instruction-instruction_handler
444 db 'end',0
445 dw end_directive-instruction_handler
446 db 'err',0
447 dw err_directive-instruction_handler
448 db 'fld',0
449 dw fld_instruction-instruction_handler
450 db 'fst',2
451 dw fld_instruction-instruction_handler
452 db 'hlt',0F4h
453 dw simple_instruction-instruction_handler
454 db 'inc',0
455 dw inc_instruction-instruction_handler
456 db 'ins',6Ch
457 dw ins_instruction-instruction_handler
458 db 'int',0CDh
459 dw int_instruction-instruction_handler
460 db 'jae',73h
461 dw conditional_jump-instruction_handler
462 db 'jbe',76h
463 dw conditional_jump-instruction_handler
464 db 'jge',7Dh
465 dw conditional_jump-instruction_handler
466 db 'jle',7Eh
467 dw conditional_jump-instruction_handler
468 db 'jmp',0
469 dw jmp_instruction-instruction_handler
470 db 'jna',76h
471 dw conditional_jump-instruction_handler
472 db 'jnb',73h
473 dw conditional_jump-instruction_handler
474 db 'jnc',73h
475 dw conditional_jump-instruction_handler
476 db 'jne',75h
477 dw conditional_jump-instruction_handler
478 db 'jng',7Eh
479 dw conditional_jump-instruction_handler
480 db 'jnl',7Dh
481 dw conditional_jump-instruction_handler
482 db 'jno',71h
483 dw conditional_jump-instruction_handler
484 db 'jnp',7Bh
485 dw conditional_jump-instruction_handler
486 db 'jns',79h
487 dw conditional_jump-instruction_handler
488 db 'jnz',75h
489 dw conditional_jump-instruction_handler
490 db 'jpe',7Ah
491 dw conditional_jump-instruction_handler
492 db 'jpo',7Bh
493 dw conditional_jump-instruction_handler
494 db 'lar',2
495 dw lar_instruction-instruction_handler
496 db 'lds',3
497 dw ls_instruction-instruction_handler
498 db 'lea',0
499 dw lea_instruction-instruction_handler
500 db 'les',0
501 dw ls_instruction-instruction_handler
502 db 'lfs',4
503 dw ls_instruction-instruction_handler
504 db 'lgs',5
505 dw ls_instruction-instruction_handler
506 db 'lsl',3
507 dw lar_instruction-instruction_handler
508 db 'lss',2
509 dw ls_instruction-instruction_handler
510 db 'ltr',3
511 dw pm_word_instruction-instruction_handler
512 db 'mov',0
513 dw mov_instruction-instruction_handler
514 db 'mul',4
515 dw single_operand_instruction-instruction_handler
516 db 'neg',3
517 dw single_operand_instruction-instruction_handler
518 db 'nop',90h
519 dw nop_instruction-instruction_handler
520 db 'not',2
521 dw single_operand_instruction-instruction_handler
522 db 'org',0
523 dw org_directive-instruction_handler
524 db 'out',0
525 dw out_instruction-instruction_handler
526 db 'pop',0
527 dw pop_instruction-instruction_handler
528 db 'por',0EBh
529 dw basic_mmx_instruction-instruction_handler
530 db 'rcl',2
531 dw sh_instruction-instruction_handler
532 db 'rcr',3
533 dw sh_instruction-instruction_handler
534 db 'rep',0F3h
535 dw prefix_instruction-instruction_handler
536 db 'ret',0C2h
537 dw ret_instruction-instruction_handler
538 db 'rol',0
539 dw sh_instruction-instruction_handler
540 db 'ror',1
541 dw sh_instruction-instruction_handler
542 db 'rsm',0AAh
543 dw simple_extended_instruction-instruction_handler
544 db 'sal',4
545 dw sh_instruction-instruction_handler
546 db 'sar',7
547 dw sh_instruction-instruction_handler
548 db 'sbb',18h
549 dw basic_instruction-instruction_handler
550 db 'shl',4
551 dw sh_instruction-instruction_handler
552 db 'shr',5
553 dw sh_instruction-instruction_handler
554 db 'stc',0F9h
555 dw simple_instruction-instruction_handler
556 db 'std',0FDh
557 dw simple_instruction-instruction_handler
558 db 'sti',0FBh
559 dw simple_instruction-instruction_handler
560 db 'str',1
561 dw pm_store_word_instruction-instruction_handler
562 db 'sub',28h
563 dw basic_instruction-instruction_handler
564 db 'ud2',0Bh
565 dw simple_extended_instruction-instruction_handler
566 db 'xor',30h
567 dw basic_instruction-instruction_handler
568 instructions_4:
569 db 'adcx',66h
570 dw adx_instruction-instruction_handler
571 db 'adox',0F3h
572 dw adx_instruction-instruction_handler
573 db 'andn',0F2h
574 dw andn_instruction-instruction_handler
575 db 'arpl',0
576 dw arpl_instruction-instruction_handler
577 db 'blci',26h
578 dw tbm_instruction-instruction_handler
579 db 'blcs',13h
580 dw tbm_instruction-instruction_handler
581 db 'blsi',3
582 dw bmi_instruction-instruction_handler
583 db 'blsr',1
584 dw bmi_instruction-instruction_handler
585 db 'bzhi',0F5h
586 dw bzhi_instruction-instruction_handler
587 db 'call',0
588 dw call_instruction-instruction_handler
589 db 'cdqe',98h
590 dw simple_instruction_64bit-instruction_handler
591 db 'clac',0CAh
592 dw simple_vmx_instruction-instruction_handler
593 db 'clgi',0DDh
594 dw simple_vmx_instruction-instruction_handler
595 db 'clts',6
596 dw simple_extended_instruction-instruction_handler
597 db 'cmps',0A6h
598 dw cmps_instruction-instruction_handler
599 db 'cwde',98h
600 dw simple_instruction_32bit-instruction_handler
601 db 'data',0
602 dw data_directive-instruction_handler
603 db 'dppd',41h
604 dw sse4_instruction_3a_imm8-instruction_handler
605 db 'dpps',40h
606 dw sse4_instruction_3a_imm8-instruction_handler
607 db 'else',0
608 dw else_directive-instruction_handler
609 db 'emms',77h
610 dw simple_extended_instruction-instruction_handler
611 db 'fabs',100001b
612 dw simple_fpu_instruction-instruction_handler
613 db 'fadd',0
614 dw basic_fpu_instruction-instruction_handler
615 db 'fbld',4
616 dw fbld_instruction-instruction_handler
617 db 'fchs',100000b
618 dw simple_fpu_instruction-instruction_handler
619 db 'fcom',2
620 dw basic_fpu_instruction-instruction_handler
621 db 'fcos',111111b
622 dw simple_fpu_instruction-instruction_handler
623 db 'fdiv',6
624 dw basic_fpu_instruction-instruction_handler
625 db 'feni',0E0h
626 dw finit_instruction-instruction_handler
627 db 'fild',0
628 dw fild_instruction-instruction_handler
629 db 'fist',2
630 dw fild_instruction-instruction_handler
631 db 'fld1',101000b
632 dw simple_fpu_instruction-instruction_handler
633 db 'fldz',101110b
634 dw simple_fpu_instruction-instruction_handler
635 db 'fmul',1
636 dw basic_fpu_instruction-instruction_handler
637 db 'fnop',010000b
638 dw simple_fpu_instruction-instruction_handler
639 db 'fsin',111110b
640 dw simple_fpu_instruction-instruction_handler
641 db 'fstp',3
642 dw fld_instruction-instruction_handler
643 db 'fsub',4
644 dw basic_fpu_instruction-instruction_handler
645 db 'ftst',100100b
646 dw simple_fpu_instruction-instruction_handler
647 db 'fxam',100101b
648 dw simple_fpu_instruction-instruction_handler
649 db 'fxch',0
650 dw fxch_instruction-instruction_handler
651 db 'heap',0
652 dw heap_directive-instruction_handler
653 db 'idiv',7
654 dw single_operand_instruction-instruction_handler
655 db 'imul',0
656 dw imul_instruction-instruction_handler
657 db 'insb',6Ch
658 dw simple_instruction-instruction_handler
659 db 'insd',6Dh
660 dw simple_instruction_32bit-instruction_handler
661 db 'insw',6Dh
662 dw simple_instruction_16bit-instruction_handler
663 db 'int1',0F1h
664 dw simple_instruction-instruction_handler
665 db 'int3',0CCh
666 dw simple_instruction-instruction_handler
667 db 'into',0CEh
668 dw simple_instruction_except64-instruction_handler
669 db 'invd',8
670 dw simple_extended_instruction-instruction_handler
671 db 'iret',0CFh
672 dw iret_instruction-instruction_handler
673 db 'jcxz',0E3h
674 dw loop_instruction_16bit-instruction_handler
675 db 'jnae',72h
676 dw conditional_jump-instruction_handler
677 db 'jnbe',77h
678 dw conditional_jump-instruction_handler
679 db 'jnge',7Ch
680 dw conditional_jump-instruction_handler
681 db 'jnle',7Fh
682 dw conditional_jump-instruction_handler
683 db 'lahf',9Fh
684 dw simple_instruction-instruction_handler
685 db 'lgdt',2
686 dw lgdt_instruction-instruction_handler
687 db 'lidt',3
688 dw lgdt_instruction-instruction_handler
689 db 'lldt',2
690 dw pm_word_instruction-instruction_handler
691 db 'lmsw',16h
692 dw pm_word_instruction-instruction_handler
693 db 'load',0
694 dw load_directive-instruction_handler
695 db 'lock',0F0h
696 dw prefix_instruction-instruction_handler
697 db 'lods',0ACh
698 dw lods_instruction-instruction_handler
699 db 'loop',0E2h
700 dw loop_instruction-instruction_handler
701 db 'movd',0
702 dw movd_instruction-instruction_handler
703 db 'movq',0
704 dw movq_instruction-instruction_handler
705 db 'movs',0A4h
706 dw movs_instruction-instruction_handler
707 db 'mulx',0F6h
708 dw pdep_instruction-instruction_handler
709 db 'orpd',56h
710 dw sse_pd_instruction-instruction_handler
711 db 'orps',56h
712 dw sse_ps_instruction-instruction_handler
713 db 'outs',6Eh
714 dw outs_instruction-instruction_handler
715 db 'pand',0DBh
716 dw basic_mmx_instruction-instruction_handler
717 db 'pdep',0F5h
718 dw pdep_instruction-instruction_handler
719 db 'pext',0F5h
720 dw pext_instruction-instruction_handler
721 db 'popa',61h
722 dw simple_instruction_except64-instruction_handler
723 db 'popd',4
724 dw pop_instruction-instruction_handler
725 db 'popf',9Dh
726 dw simple_instruction-instruction_handler
727 db 'popq',8
728 dw pop_instruction-instruction_handler
729 db 'popw',2
730 dw pop_instruction-instruction_handler
731 db 'push',0
732 dw push_instruction-instruction_handler
733 db 'pxor',0EFh
734 dw basic_mmx_instruction-instruction_handler
735 db 'repe',0F3h
736 dw prefix_instruction-instruction_handler
737 db 'repz',0F3h
738 dw prefix_instruction-instruction_handler
739 db 'retd',0C2h
740 dw ret_instruction_32bit_except64-instruction_handler
741 db 'retf',0CAh
742 dw retf_instruction-instruction_handler
743 db 'retn',0C2h
744 dw ret_instruction-instruction_handler
745 db 'retq',0C2h
746 dw ret_instruction_only64-instruction_handler
747 db 'retw',0C2h
748 dw ret_instruction_16bit-instruction_handler
749 db 'rorx',0F0h
750 dw rorx_instruction-instruction_handler
751 db 'sahf',9Eh
752 dw simple_instruction-instruction_handler
753 db 'salc',0D6h
754 dw simple_instruction_except64-instruction_handler
755 db 'sarx',0F7h
756 dw sarx_instruction-instruction_handler
757 db 'scas',0AEh
758 dw stos_instruction-instruction_handler
759 db 'seta',97h
760 dw set_instruction-instruction_handler
761 db 'setb',92h
762 dw set_instruction-instruction_handler
763 db 'setc',92h
764 dw set_instruction-instruction_handler
765 db 'sete',94h
766 dw set_instruction-instruction_handler
767 db 'setg',9Fh
768 dw set_instruction-instruction_handler
769 db 'setl',9Ch
770 dw set_instruction-instruction_handler
771 db 'seto',90h
772 dw set_instruction-instruction_handler
773 db 'setp',9Ah
774 dw set_instruction-instruction_handler
775 db 'sets',98h
776 dw set_instruction-instruction_handler
777 db 'setz',94h
778 dw set_instruction-instruction_handler
779 db 'sgdt',0
780 dw lgdt_instruction-instruction_handler
781 db 'shld',0A4h
782 dw shd_instruction-instruction_handler
783 db 'shlx',0F7h
784 dw shlx_instruction-instruction_handler
785 db 'shrd',0ACh
786 dw shd_instruction-instruction_handler
787 db 'shrx',0F7h
788 dw shrx_instruction-instruction_handler
789 db 'sidt',1
790 dw lgdt_instruction-instruction_handler
791 db 'sldt',0
792 dw pm_store_word_instruction-instruction_handler
793 db 'smsw',14h
794 dw pm_store_word_instruction-instruction_handler
795 db 'stac',0CBh
796 dw simple_vmx_instruction-instruction_handler
797 db 'stgi',0DCh
798 dw simple_vmx_instruction-instruction_handler
799 db 'stos',0AAh
800 dw stos_instruction-instruction_handler
801 db 'test',0
802 dw test_instruction-instruction_handler
803 db 'verr',4
804 dw pm_word_instruction-instruction_handler
805 db 'verw',5
806 dw pm_word_instruction-instruction_handler
807 db 'vpor',0EBh
808 dw avx_pd_instruction-instruction_handler
809 db 'wait',9Bh
810 dw simple_instruction-instruction_handler
811 db 'xadd',0C0h
812 dw basic_486_instruction-instruction_handler
813 db 'xchg',0
814 dw xchg_instruction-instruction_handler
815 db 'xend',0D5h
816 dw simple_vmx_instruction-instruction_handler
817 db 'xlat',0D7h
818 dw xlat_instruction-instruction_handler
819 instructions_5:
820 db 'addpd',58h
821 dw sse_pd_instruction-instruction_handler
822 db 'addps',58h
823 dw sse_ps_instruction-instruction_handler
824 db 'addsd',58h
825 dw sse_sd_instruction-instruction_handler
826 db 'addss',58h
827 dw sse_ss_instruction-instruction_handler
828 db 'align',0
829 dw align_directive-instruction_handler
830 db 'andpd',54h
831 dw sse_pd_instruction-instruction_handler
832 db 'andps',54h
833 dw sse_ps_instruction-instruction_handler
834 db 'bextr',0F7h
835 dw bextr_instruction-instruction_handler
836 db 'blcic',15h
837 dw tbm_instruction-instruction_handler
838 db 'blsic',16h
839 dw tbm_instruction-instruction_handler
840 db 'bound',0
841 dw bound_instruction-instruction_handler
842 db 'break',0
843 dw break_directive-instruction_handler
844 db 'bswap',0
845 dw bswap_instruction-instruction_handler
846 db 'cmova',47h
847 dw bs_instruction-instruction_handler
848 db 'cmovb',42h
849 dw bs_instruction-instruction_handler
850 db 'cmovc',42h
851 dw bs_instruction-instruction_handler
852 db 'cmove',44h
853 dw bs_instruction-instruction_handler
854 db 'cmovg',4Fh
855 dw bs_instruction-instruction_handler
856 db 'cmovl',4Ch
857 dw bs_instruction-instruction_handler
858 db 'cmovo',40h
859 dw bs_instruction-instruction_handler
860 db 'cmovp',4Ah
861 dw bs_instruction-instruction_handler
862 db 'cmovs',48h
863 dw bs_instruction-instruction_handler
864 db 'cmovz',44h
865 dw bs_instruction-instruction_handler
866 db 'cmppd',-1
867 dw cmp_pd_instruction-instruction_handler
868 db 'cmpps',-1
869 dw cmp_ps_instruction-instruction_handler
870 db 'cmpsb',0A6h
871 dw simple_instruction-instruction_handler
872 db 'cmpsd',-1
873 dw cmpsd_instruction-instruction_handler
874 db 'cmpsq',0A7h
875 dw simple_instruction_64bit-instruction_handler
876 db 'cmpss',-1
877 dw cmp_ss_instruction-instruction_handler
878 db 'cmpsw',0A7h
879 dw simple_instruction_16bit-instruction_handler
880 db 'cpuid',0A2h
881 dw simple_extended_instruction-instruction_handler
882 db 'crc32',0
883 dw crc32_instruction-instruction_handler
884 db 'divpd',5Eh
885 dw sse_pd_instruction-instruction_handler
886 db 'divps',5Eh
887 dw sse_ps_instruction-instruction_handler
888 db 'divsd',5Eh
889 dw sse_sd_instruction-instruction_handler
890 db 'divss',5Eh
891 dw sse_ss_instruction-instruction_handler
892 db 'enter',0
893 dw enter_instruction-instruction_handler
894 db 'entry',0
895 dw entry_directive-instruction_handler
896 db 'extrn',0
897 dw extrn_directive-instruction_handler
898 db 'extrq',0
899 dw extrq_instruction-instruction_handler
900 db 'f2xm1',110000b
901 dw simple_fpu_instruction-instruction_handler
902 db 'faddp',0
903 dw faddp_instruction-instruction_handler
904 db 'fbstp',6
905 dw fbld_instruction-instruction_handler
906 db 'fclex',0E2h
907 dw finit_instruction-instruction_handler
908 db 'fcomi',0F0h
909 dw fcomi_instruction-instruction_handler
910 db 'fcomp',3
911 dw basic_fpu_instruction-instruction_handler
912 db 'fdisi',0E1h
913 dw finit_instruction-instruction_handler
914 db 'fdivp',7
915 dw faddp_instruction-instruction_handler
916 db 'fdivr',7
917 dw basic_fpu_instruction-instruction_handler
918 db 'femms',0Eh
919 dw simple_extended_instruction-instruction_handler
920 db 'ffree',0
921 dw ffree_instruction-instruction_handler
922 db 'fiadd',0
923 dw fi_instruction-instruction_handler
924 db 'ficom',2
925 dw fi_instruction-instruction_handler
926 db 'fidiv',6
927 dw fi_instruction-instruction_handler
928 db 'fimul',1
929 dw fi_instruction-instruction_handler
930 db 'finit',0E3h
931 dw finit_instruction-instruction_handler
932 db 'fistp',3
933 dw fild_instruction-instruction_handler
934 db 'fisub',4
935 dw fi_instruction-instruction_handler
936 db 'fldcw',5
937 dw fldcw_instruction-instruction_handler
938 db 'fldpi',101011b
939 dw simple_fpu_instruction-instruction_handler
940 db 'fmulp',1
941 dw faddp_instruction-instruction_handler
942 db 'fneni',0E0h
943 dw fninit_instruction-instruction_handler
944 db 'fprem',111000b
945 dw simple_fpu_instruction-instruction_handler
946 db 'fptan',110010b
947 dw simple_fpu_instruction-instruction_handler
948 db 'fsave',6
949 dw fsave_instruction-instruction_handler
950 db 'fsqrt',111010b
951 dw simple_fpu_instruction-instruction_handler
952 db 'fstcw',7
953 dw fstcw_instruction-instruction_handler
954 db 'fstsw',0
955 dw fstsw_instruction-instruction_handler
956 db 'fsubp',5
957 dw faddp_instruction-instruction_handler
958 db 'fsubr',5
959 dw basic_fpu_instruction-instruction_handler
960 db 'fucom',4
961 dw ffree_instruction-instruction_handler
962 db 'fwait',9Bh
963 dw simple_instruction-instruction_handler
964 db 'fyl2x',110001b
965 dw simple_fpu_instruction-instruction_handler
966 db 'icebp',0F1h
967 dw simple_instruction-instruction_handler
968 db 'iretd',0CFh
969 dw simple_instruction_32bit-instruction_handler
970 db 'iretq',0CFh
971 dw simple_instruction_64bit-instruction_handler
972 db 'iretw',0CFh
973 dw simple_instruction_16bit-instruction_handler
974 db 'jecxz',0E3h
975 dw loop_instruction_32bit-instruction_handler
976 db 'jrcxz',0E3h
977 dw loop_instruction_64bit-instruction_handler
978 db 'label',0
979 dw label_directive-instruction_handler
980 db 'lddqu',0
981 dw lddqu_instruction-instruction_handler
982 db 'leave',0C9h
983 dw simple_instruction-instruction_handler
984 db 'lodsb',0ACh
985 dw simple_instruction-instruction_handler
986 db 'lodsd',0ADh
987 dw simple_instruction_32bit-instruction_handler
988 db 'lodsq',0ADh
989 dw simple_instruction_64bit-instruction_handler
990 db 'lodsw',0ADh
991 dw simple_instruction_16bit-instruction_handler
992 db 'loopd',0E2h
993 dw loop_instruction_32bit-instruction_handler
994 db 'loope',0E1h
995 dw loop_instruction-instruction_handler
996 db 'loopq',0E2h
997 dw loop_instruction_64bit-instruction_handler
998 db 'loopw',0E2h
999 dw loop_instruction_16bit-instruction_handler
1000 db 'loopz',0E1h
1001 dw loop_instruction-instruction_handler
1002 db 'lzcnt',0BDh
1003 dw popcnt_instruction-instruction_handler
1004 db 'maxpd',5Fh
1005 dw sse_pd_instruction-instruction_handler
1006 db 'maxps',5Fh
1007 dw sse_ps_instruction-instruction_handler
1008 db 'maxsd',5Fh
1009 dw sse_sd_instruction-instruction_handler
1010 db 'maxss',5Fh
1011 dw sse_ss_instruction-instruction_handler
1012 db 'minpd',5Dh
1013 dw sse_pd_instruction-instruction_handler
1014 db 'minps',5Dh
1015 dw sse_ps_instruction-instruction_handler
1016 db 'minsd',5Dh
1017 dw sse_sd_instruction-instruction_handler
1018 db 'minss',5Dh
1019 dw sse_ss_instruction-instruction_handler
1020 db 'movbe',0F0h
1021 dw movbe_instruction-instruction_handler
1022 db 'movsb',0A4h
1023 dw simple_instruction-instruction_handler
1024 db 'movsd',0
1025 dw movsd_instruction-instruction_handler
1026 db 'movsq',0A5h
1027 dw simple_instruction_64bit-instruction_handler
1028 db 'movss',0
1029 dw movss_instruction-instruction_handler
1030 db 'movsw',0A5h
1031 dw simple_instruction_16bit-instruction_handler
1032 db 'movsx',0BEh
1033 dw movx_instruction-instruction_handler
1034 db 'movzx',0B6h
1035 dw movx_instruction-instruction_handler
1036 db 'mulpd',59h
1037 dw sse_pd_instruction-instruction_handler
1038 db 'mulps',59h
1039 dw sse_ps_instruction-instruction_handler
1040 db 'mulsd',59h
1041 dw sse_sd_instruction-instruction_handler
1042 db 'mulss',59h
1043 dw sse_ss_instruction-instruction_handler
1044 db 'mwait',0C9h
1045 dw monitor_instruction-instruction_handler
1046 db 'outsb',6Eh
1047 dw simple_instruction-instruction_handler
1048 db 'outsd',6Fh
1049 dw simple_instruction_32bit-instruction_handler
1050 db 'outsw',6Fh
1051 dw simple_instruction_16bit-instruction_handler
1052 db 'pabsb',1Ch
1053 dw ssse3_instruction-instruction_handler
1054 db 'pabsd',1Eh
1055 dw ssse3_instruction-instruction_handler
1056 db 'pabsw',1Dh
1057 dw ssse3_instruction-instruction_handler
1058 db 'paddb',0FCh
1059 dw basic_mmx_instruction-instruction_handler
1060 db 'paddd',0FEh
1061 dw basic_mmx_instruction-instruction_handler
1062 db 'paddq',0D4h
1063 dw basic_mmx_instruction-instruction_handler
1064 db 'paddw',0FDh
1065 dw basic_mmx_instruction-instruction_handler
1066 db 'pandn',0DFh
1067 dw basic_mmx_instruction-instruction_handler
1068 db 'pause',0
1069 dw pause_instruction-instruction_handler
1070 db 'pavgb',0E0h
1071 dw basic_mmx_instruction-instruction_handler
1072 db 'pavgw',0E3h
1073 dw basic_mmx_instruction-instruction_handler
1074 db 'pf2id',1Dh
1075 dw amd3dnow_instruction-instruction_handler
1076 db 'pf2iw',1Ch
1077 dw amd3dnow_instruction-instruction_handler
1078 db 'pfacc',0AEh
1079 dw amd3dnow_instruction-instruction_handler
1080 db 'pfadd',9Eh
1081 dw amd3dnow_instruction-instruction_handler
1082 db 'pfmax',0A4h
1083 dw amd3dnow_instruction-instruction_handler
1084 db 'pfmin',94h
1085 dw amd3dnow_instruction-instruction_handler
1086 db 'pfmul',0B4h
1087 dw amd3dnow_instruction-instruction_handler
1088 db 'pfrcp',96h
1089 dw amd3dnow_instruction-instruction_handler
1090 db 'pfsub',9Ah
1091 dw amd3dnow_instruction-instruction_handler
1092 db 'pi2fd',0Dh
1093 dw amd3dnow_instruction-instruction_handler
1094 db 'pi2fw',0Ch
1095 dw amd3dnow_instruction-instruction_handler
1096 db 'popad',61h
1097 dw simple_instruction_32bit_except64-instruction_handler
1098 db 'popaw',61h
1099 dw simple_instruction_16bit_except64-instruction_handler
1100 db 'popfd',9Dh
1101 dw simple_instruction_32bit_except64-instruction_handler
1102 db 'popfq',9Dh
1103 dw simple_instruction_only64-instruction_handler
1104 db 'popfw',9Dh
1105 dw simple_instruction_16bit-instruction_handler
1106 db 'pslld',0F2h
1107 dw mmx_bit_shift_instruction-instruction_handler
1108 db 'psllq',0F3h
1109 dw mmx_bit_shift_instruction-instruction_handler
1110 db 'psllw',0F1h
1111 dw mmx_bit_shift_instruction-instruction_handler
1112 db 'psrad',0E2h
1113 dw mmx_bit_shift_instruction-instruction_handler
1114 db 'psraw',0E1h
1115 dw mmx_bit_shift_instruction-instruction_handler
1116 db 'psrld',0D2h
1117 dw mmx_bit_shift_instruction-instruction_handler
1118 db 'psrlq',0D3h
1119 dw mmx_bit_shift_instruction-instruction_handler
1120 db 'psrlw',0D1h
1121 dw mmx_bit_shift_instruction-instruction_handler
1122 db 'psubb',0F8h
1123 dw basic_mmx_instruction-instruction_handler
1124 db 'psubd',0FAh
1125 dw basic_mmx_instruction-instruction_handler
1126 db 'psubq',0FBh
1127 dw basic_mmx_instruction-instruction_handler
1128 db 'psubw',0F9h
1129 dw basic_mmx_instruction-instruction_handler
1130 db 'ptest',17h
1131 dw sse4_instruction_38-instruction_handler
1132 db 'pusha',60h
1133 dw simple_instruction_except64-instruction_handler
1134 db 'pushd',4
1135 dw push_instruction-instruction_handler
1136 db 'pushf',9Ch
1137 dw simple_instruction-instruction_handler
1138 db 'pushq',8
1139 dw push_instruction-instruction_handler
1140 db 'pushw',2
1141 dw push_instruction-instruction_handler
1142 db 'rcpps',53h
1143 dw sse_ps_instruction-instruction_handler
1144 db 'rcpss',53h
1145 dw sse_ss_instruction-instruction_handler
1146 db 'rdmsr',32h
1147 dw simple_extended_instruction-instruction_handler
1148 db 'rdpmc',33h
1149 dw simple_extended_instruction-instruction_handler
1150 db 'rdtsc',31h
1151 dw simple_extended_instruction-instruction_handler
1152 db 'repne',0F2h
1153 dw prefix_instruction-instruction_handler
1154 db 'repnz',0F2h
1155 dw prefix_instruction-instruction_handler
1156 db 'retfd',0CAh
1157 dw ret_instruction_32bit-instruction_handler
1158 db 'retfq',0CAh
1159 dw ret_instruction_64bit-instruction_handler
1160 db 'retfw',0CAh
1161 dw ret_instruction_16bit-instruction_handler
1162 db 'retnd',0C2h
1163 dw ret_instruction_32bit_except64-instruction_handler
1164 db 'retnq',0C2h
1165 dw ret_instruction_only64-instruction_handler
1166 db 'retnw',0C2h
1167 dw ret_instruction_16bit-instruction_handler
1168 db 'scasb',0AEh
1169 dw simple_instruction-instruction_handler
1170 db 'scasd',0AFh
1171 dw simple_instruction_32bit-instruction_handler
1172 db 'scasq',0AFh
1173 dw simple_instruction_64bit-instruction_handler
1174 db 'scasw',0AFh
1175 dw simple_instruction_16bit-instruction_handler
1176 db 'setae',93h
1177 dw set_instruction-instruction_handler
1178 db 'setbe',96h
1179 dw set_instruction-instruction_handler
1180 db 'setge',9Dh
1181 dw set_instruction-instruction_handler
1182 db 'setle',9Eh
1183 dw set_instruction-instruction_handler
1184 db 'setna',96h
1185 dw set_instruction-instruction_handler
1186 db 'setnb',93h
1187 dw set_instruction-instruction_handler
1188 db 'setnc',93h
1189 dw set_instruction-instruction_handler
1190 db 'setne',95h
1191 dw set_instruction-instruction_handler
1192 db 'setng',9Eh
1193 dw set_instruction-instruction_handler
1194 db 'setnl',9Dh
1195 dw set_instruction-instruction_handler
1196 db 'setno',91h
1197 dw set_instruction-instruction_handler
1198 db 'setnp',9Bh
1199 dw set_instruction-instruction_handler
1200 db 'setns',99h
1201 dw set_instruction-instruction_handler
1202 db 'setnz',95h
1203 dw set_instruction-instruction_handler
1204 db 'setpe',9Ah
1205 dw set_instruction-instruction_handler
1206 db 'setpo',9Bh
1207 dw set_instruction-instruction_handler
1208 db 'stack',0
1209 dw stack_directive-instruction_handler
1210 db 'store',0
1211 dw store_directive-instruction_handler
1212 db 'stosb',0AAh
1213 dw simple_instruction-instruction_handler
1214 db 'stosd',0ABh
1215 dw simple_instruction_32bit-instruction_handler
1216 db 'stosq',0ABh
1217 dw simple_instruction_64bit-instruction_handler
1218 db 'stosw',0ABh
1219 dw simple_instruction_16bit-instruction_handler
1220 db 'subpd',5Ch
1221 dw sse_pd_instruction-instruction_handler
1222 db 'subps',5Ch
1223 dw sse_ps_instruction-instruction_handler
1224 db 'subsd',5Ch
1225 dw sse_sd_instruction-instruction_handler
1226 db 'subss',5Ch
1227 dw sse_ss_instruction-instruction_handler
1228 db 'times',0
1229 dw times_directive-instruction_handler
1230 db 'tzcnt',0BCh
1231 dw popcnt_instruction-instruction_handler
1232 db 'tzmsk',14h
1233 dw tbm_instruction-instruction_handler
1234 db 'vdppd',41h
1235 dw avx_128bit_instruction_3a_imm8-instruction_handler
1236 db 'vdpps',40h
1237 dw avx_instruction_3a_imm8-instruction_handler
1238 db 'vmovd',0
1239 dw avx_movd_instruction-instruction_handler
1240 db 'vmovq',0
1241 dw avx_movq_instruction-instruction_handler
1242 db 'vmrun',0D8h
1243 dw simple_svm_instruction-instruction_handler
1244 db 'vmxon',6
1245 dw vmxon_instruction-instruction_handler
1246 db 'vorpd',56h
1247 dw avx_pd_instruction-instruction_handler
1248 db 'vorps',56h
1249 dw avx_ps_instruction-instruction_handler
1250 db 'vpand',0DBh
1251 dw avx_pd_instruction-instruction_handler
1252 db 'vpxor',0EFh
1253 dw avx_pd_instruction-instruction_handler
1254 db 'while',0
1255 dw while_directive-instruction_handler
1256 db 'wrmsr',30h
1257 dw simple_extended_instruction-instruction_handler
1258 db 'xlatb',0D7h
1259 dw simple_instruction-instruction_handler
1260 db 'xorpd',57h
1261 dw sse_pd_instruction-instruction_handler
1262 db 'xorps',57h
1263 dw sse_ps_instruction-instruction_handler
1264 db 'xsave',100b
1265 dw fxsave_instruction-instruction_handler
1266 db 'xtest',0D6h
1267 dw simple_vmx_instruction-instruction_handler
1268 instructions_6:
1269 db 'aesdec',0DEh
1270 dw sse4_instruction_38-instruction_handler
1271 db 'aesenc',0DCh
1272 dw sse4_instruction_38-instruction_handler
1273 db 'aesimc',0DBh
1274 dw sse4_instruction_38-instruction_handler
1275 db 'andnpd',55h
1276 dw sse_pd_instruction-instruction_handler
1277 db 'andnps',55h
1278 dw sse_ps_instruction-instruction_handler
1279 db 'assert',0
1280 dw assert_directive-instruction_handler
1281 db 'blcmsk',21h
1282 dw tbm_instruction-instruction_handler
1283 db 'blsmsk',2
1284 dw bmi_instruction-instruction_handler
1285 db 'cmovae',43h
1286 dw bs_instruction-instruction_handler
1287 db 'cmovbe',46h
1288 dw bs_instruction-instruction_handler
1289 db 'cmovge',4Dh
1290 dw bs_instruction-instruction_handler
1291 db 'cmovle',4Eh
1292 dw bs_instruction-instruction_handler
1293 db 'cmovna',46h
1294 dw bs_instruction-instruction_handler
1295 db 'cmovnb',43h
1296 dw bs_instruction-instruction_handler
1297 db 'cmovnc',43h
1298 dw bs_instruction-instruction_handler
1299 db 'cmovne',45h
1300 dw bs_instruction-instruction_handler
1301 db 'cmovng',4Eh
1302 dw bs_instruction-instruction_handler
1303 db 'cmovnl',4Dh
1304 dw bs_instruction-instruction_handler
1305 db 'cmovno',41h
1306 dw bs_instruction-instruction_handler
1307 db 'cmovnp',4Bh
1308 dw bs_instruction-instruction_handler
1309 db 'cmovns',49h
1310 dw bs_instruction-instruction_handler
1311 db 'cmovnz',45h
1312 dw bs_instruction-instruction_handler
1313 db 'cmovpe',4Ah
1314 dw bs_instruction-instruction_handler
1315 db 'cmovpo',4Bh
1316 dw bs_instruction-instruction_handler
1317 db 'comisd',2Fh
1318 dw comisd_instruction-instruction_handler
1319 db 'comiss',2Fh
1320 dw comiss_instruction-instruction_handler
1321 db 'fcmovb',0C0h
1322 dw fcmov_instruction-instruction_handler
1323 db 'fcmove',0C8h
1324 dw fcmov_instruction-instruction_handler
1325 db 'fcmovu',0D8h
1326 dw fcmov_instruction-instruction_handler
1327 db 'fcomip',0F0h
1328 dw fcomip_instruction-instruction_handler
1329 db 'fcompp',0
1330 dw fcompp_instruction-instruction_handler
1331 db 'fdivrp',6
1332 dw faddp_instruction-instruction_handler
1333 db 'ffreep',0
1334 dw ffreep_instruction-instruction_handler
1335 db 'ficomp',3
1336 dw fi_instruction-instruction_handler
1337 db 'fidivr',7
1338 dw fi_instruction-instruction_handler
1339 db 'fisttp',1
1340 dw fild_instruction-instruction_handler
1341 db 'fisubr',5
1342 dw fi_instruction-instruction_handler
1343 db 'fldenv',4
1344 dw fldenv_instruction-instruction_handler
1345 db 'fldl2e',101010b
1346 dw simple_fpu_instruction-instruction_handler
1347 db 'fldl2t',101001b
1348 dw simple_fpu_instruction-instruction_handler
1349 db 'fldlg2',101100b
1350 dw simple_fpu_instruction-instruction_handler
1351 db 'fldln2',101101b
1352 dw simple_fpu_instruction-instruction_handler
1353 db 'fnclex',0E2h
1354 dw fninit_instruction-instruction_handler
1355 db 'fndisi',0E1h
1356 dw fninit_instruction-instruction_handler
1357 db 'fninit',0E3h
1358 dw fninit_instruction-instruction_handler
1359 db 'fnsave',6
1360 dw fnsave_instruction-instruction_handler
1361 db 'fnstcw',7
1362 dw fldcw_instruction-instruction_handler
1363 db 'fnstsw',0
1364 dw fnstsw_instruction-instruction_handler
1365 db 'format',0
1366 dw format_directive-instruction_handler
1367 db 'fpatan',110011b
1368 dw simple_fpu_instruction-instruction_handler
1369 db 'fprem1',110101b
1370 dw simple_fpu_instruction-instruction_handler
1371 db 'frstor',4
1372 dw fnsave_instruction-instruction_handler
1373 db 'frstpm',0E5h
1374 dw fninit_instruction-instruction_handler
1375 db 'fsaved',6
1376 dw fsave_instruction_32bit-instruction_handler
1377 db 'fsavew',6
1378 dw fsave_instruction_16bit-instruction_handler
1379 db 'fscale',111101b
1380 dw simple_fpu_instruction-instruction_handler
1381 db 'fsetpm',0E4h
1382 dw fninit_instruction-instruction_handler
1383 db 'fstenv',6
1384 dw fstenv_instruction-instruction_handler
1385 db 'fsubrp',4
1386 dw faddp_instruction-instruction_handler
1387 db 'fucomi',0E8h
1388 dw fcomi_instruction-instruction_handler
1389 db 'fucomp',5
1390 dw ffree_instruction-instruction_handler
1391 db 'fxsave',0
1392 dw fxsave_instruction-instruction_handler
1393 db 'getsec',37h
1394 dw simple_extended_instruction-instruction_handler
1395 db 'haddpd',07Ch
1396 dw sse_pd_instruction-instruction_handler
1397 db 'haddps',07Ch
1398 dw cvtpd2dq_instruction-instruction_handler
1399 db 'hsubpd',07Dh
1400 dw sse_pd_instruction-instruction_handler
1401 db 'hsubps',07Dh
1402 dw cvtpd2dq_instruction-instruction_handler
1403 db 'invept',80h
1404 dw vmx_inv_instruction-instruction_handler
1405 db 'invlpg',0
1406 dw invlpg_instruction-instruction_handler
1407 db 'lfence',0E8h
1408 dw fence_instruction-instruction_handler
1409 db 'llwpcb',0
1410 dw llwpcb_instruction-instruction_handler
1411 db 'looped',0E1h
1412 dw loop_instruction_32bit-instruction_handler
1413 db 'loopeq',0E1h
1414 dw loop_instruction_64bit-instruction_handler
1415 db 'loopew',0E1h
1416 dw loop_instruction_16bit-instruction_handler
1417 db 'loopne',0E0h
1418 dw loop_instruction-instruction_handler
1419 db 'loopnz',0E0h
1420 dw loop_instruction-instruction_handler
1421 db 'loopzd',0E1h
1422 dw loop_instruction_32bit-instruction_handler
1423 db 'loopzq',0E1h
1424 dw loop_instruction_64bit-instruction_handler
1425 db 'loopzw',0E1h
1426 dw loop_instruction_16bit-instruction_handler
1427 db 'lwpins',0
1428 dw lwpins_instruction-instruction_handler
1429 db 'lwpval',1
1430 dw lwpins_instruction-instruction_handler
1431 db 'mfence',0F0h
1432 dw fence_instruction-instruction_handler
1433 db 'movapd',28h
1434 dw movpd_instruction-instruction_handler
1435 db 'movaps',28h
1436 dw movps_instruction-instruction_handler
1437 db 'movdqa',66h
1438 dw movdq_instruction-instruction_handler
1439 db 'movdqu',0F3h
1440 dw movdq_instruction-instruction_handler
1441 db 'movhpd',16h
1442 dw movlpd_instruction-instruction_handler
1443 db 'movhps',16h
1444 dw movlps_instruction-instruction_handler
1445 db 'movlpd',12h
1446 dw movlpd_instruction-instruction_handler
1447 db 'movlps',12h
1448 dw movlps_instruction-instruction_handler
1449 db 'movnti',0C3h
1450 dw movnti_instruction-instruction_handler
1451 db 'movntq',0E7h
1452 dw movntq_instruction-instruction_handler
1453 db 'movsxd',63h
1454 dw movsxd_instruction-instruction_handler
1455 db 'movupd',10h
1456 dw movpd_instruction-instruction_handler
1457 db 'movups',10h
1458 dw movps_instruction-instruction_handler
1459 db 'paddsb',0ECh
1460 dw basic_mmx_instruction-instruction_handler
1461 db 'paddsw',0EDh
1462 dw basic_mmx_instruction-instruction_handler
1463 db 'pextrb',14h
1464 dw pextrb_instruction-instruction_handler
1465 db 'pextrd',16h
1466 dw pextrd_instruction-instruction_handler
1467 db 'pextrq',16h
1468 dw pextrq_instruction-instruction_handler
1469 db 'pextrw',15h
1470 dw pextrw_instruction-instruction_handler
1471 db 'pfnacc',8Ah
1472 dw amd3dnow_instruction-instruction_handler
1473 db 'pfsubr',0AAh
1474 dw amd3dnow_instruction-instruction_handler
1475 db 'phaddd',2
1476 dw ssse3_instruction-instruction_handler
1477 db 'phaddw',1
1478 dw ssse3_instruction-instruction_handler
1479 db 'phsubd',6
1480 dw ssse3_instruction-instruction_handler
1481 db 'phsubw',5
1482 dw ssse3_instruction-instruction_handler
1483 db 'pinsrb',20h
1484 dw pinsrb_instruction-instruction_handler
1485 db 'pinsrd',22h
1486 dw pinsrd_instruction-instruction_handler
1487 db 'pinsrq',22h
1488 dw pinsrq_instruction-instruction_handler
1489 db 'pinsrw',0C4h
1490 dw pinsrw_instruction-instruction_handler
1491 db 'pmaxsb',3Ch
1492 dw sse4_instruction_38-instruction_handler
1493 db 'pmaxsd',3Dh
1494 dw sse4_instruction_38-instruction_handler
1495 db 'pmaxsw',0EEh
1496 dw basic_mmx_instruction-instruction_handler
1497 db 'pmaxub',0DEh
1498 dw basic_mmx_instruction-instruction_handler
1499 db 'pmaxud',3Fh
1500 dw sse4_instruction_38-instruction_handler
1501 db 'pmaxuw',3Eh
1502 dw sse4_instruction_38-instruction_handler
1503 db 'pminsb',38h
1504 dw sse4_instruction_38-instruction_handler
1505 db 'pminsd',39h
1506 dw sse4_instruction_38-instruction_handler
1507 db 'pminsw',0EAh
1508 dw basic_mmx_instruction-instruction_handler
1509 db 'pminub',0DAh
1510 dw basic_mmx_instruction-instruction_handler
1511 db 'pminud',3Bh
1512 dw sse4_instruction_38-instruction_handler
1513 db 'pminuw',3Ah
1514 dw sse4_instruction_38-instruction_handler
1515 db 'pmuldq',28h
1516 dw sse4_instruction_38-instruction_handler
1517 db 'pmulhw',0E5h
1518 dw basic_mmx_instruction-instruction_handler
1519 db 'pmulld',40h
1520 dw sse4_instruction_38-instruction_handler
1521 db 'pmullw',0D5h
1522 dw basic_mmx_instruction-instruction_handler
1523 db 'popcnt',0B8h
1524 dw popcnt_instruction-instruction_handler
1525 db 'psadbw',0F6h
1526 dw basic_mmx_instruction-instruction_handler
1527 db 'pshufb',0
1528 dw ssse3_instruction-instruction_handler
1529 db 'pshufd',66h
1530 dw pshufd_instruction-instruction_handler
1531 db 'pshufw',0
1532 dw pshufw_instruction-instruction_handler
1533 db 'psignb',8
1534 dw ssse3_instruction-instruction_handler
1535 db 'psignd',0Ah
1536 dw ssse3_instruction-instruction_handler
1537 db 'psignw',9
1538 dw ssse3_instruction-instruction_handler
1539 db 'pslldq',111b
1540 dw pslldq_instruction-instruction_handler
1541 db 'psrldq',011b
1542 dw pslldq_instruction-instruction_handler
1543 db 'psubsb',0E8h
1544 dw basic_mmx_instruction-instruction_handler
1545 db 'psubsw',0E9h
1546 dw basic_mmx_instruction-instruction_handler
1547 db 'pswapd',0BBh
1548 dw amd3dnow_instruction-instruction_handler
1549 db 'public',0
1550 dw public_directive-instruction_handler
1551 db 'pushad',60h
1552 dw simple_instruction_32bit_except64-instruction_handler
1553 db 'pushaw',60h
1554 dw simple_instruction_16bit_except64-instruction_handler
1555 db 'pushfd',9Ch
1556 dw simple_instruction_32bit_except64-instruction_handler
1557 db 'pushfq',9Ch
1558 dw simple_instruction_only64-instruction_handler
1559 db 'pushfw',9Ch
1560 dw simple_instruction_16bit-instruction_handler
1561 db 'rdmsrq',32h
1562 dw simple_extended_instruction_64bit-instruction_handler
1563 db 'rdrand',110b
1564 dw rdrand_instruction-instruction_handler
1565 db 'rdseed',111b
1566 dw rdrand_instruction-instruction_handler
1567 db 'rdtscp',1
1568 dw rdtscp_instruction-instruction_handler
1569 db 'repeat',0
1570 dw repeat_directive-instruction_handler
1571 db 'setalc',0D6h
1572 dw simple_instruction_except64-instruction_handler
1573 db 'setnae',92h
1574 dw set_instruction-instruction_handler
1575 db 'setnbe',97h
1576 dw set_instruction-instruction_handler
1577 db 'setnge',9Ch
1578 dw set_instruction-instruction_handler
1579 db 'setnle',9Fh
1580 dw set_instruction-instruction_handler
1581 db 'sfence',0F8h
1582 dw fence_instruction-instruction_handler
1583 db 'shufpd',0C6h
1584 dw sse_pd_instruction_imm8-instruction_handler
1585 db 'shufps',0C6h
1586 dw sse_ps_instruction_imm8-instruction_handler
1587 db 'skinit',0
1588 dw skinit_instruction-instruction_handler
1589 db 'slwpcb',1
1590 dw llwpcb_instruction-instruction_handler
1591 db 'sqrtpd',51h
1592 dw sse_pd_instruction-instruction_handler
1593 db 'sqrtps',51h
1594 dw sse_ps_instruction-instruction_handler
1595 db 'sqrtsd',51h
1596 dw sse_sd_instruction-instruction_handler
1597 db 'sqrtss',51h
1598 dw sse_ss_instruction-instruction_handler
1599 db 'swapgs',0
1600 dw swapgs_instruction-instruction_handler
1601 db 'sysret',07h
1602 dw simple_extended_instruction-instruction_handler
1603 db 't1mskc',17h
1604 dw tbm_instruction-instruction_handler
1605 db 'vaddpd',58h
1606 dw avx_pd_instruction-instruction_handler
1607 db 'vaddps',58h
1608 dw avx_ps_instruction-instruction_handler
1609 db 'vaddsd',58h
1610 dw avx_sd_instruction-instruction_handler
1611 db 'vaddss',58h
1612 dw avx_ss_instruction-instruction_handler
1613 db 'vandpd',54h
1614 dw avx_pd_instruction-instruction_handler
1615 db 'vandps',54h
1616 dw avx_ps_instruction-instruction_handler
1617 db 'vcmppd',-1
1618 dw avx_cmp_pd_instruction-instruction_handler
1619 db 'vcmpps',-1
1620 dw avx_cmp_ps_instruction-instruction_handler
1621 db 'vcmpsd',-1
1622 dw avx_cmp_sd_instruction-instruction_handler
1623 db 'vcmpss',-1
1624 dw avx_cmp_ss_instruction-instruction_handler
1625 db 'vdivpd',5Eh
1626 dw avx_pd_instruction-instruction_handler
1627 db 'vdivps',5Eh
1628 dw avx_ps_instruction-instruction_handler
1629 db 'vdivsd',5Eh
1630 dw avx_sd_instruction-instruction_handler
1631 db 'vdivss',5Eh
1632 dw avx_ss_instruction-instruction_handler
1633 db 'vlddqu',0F0h
1634 dw avx_lddqu_instruction-instruction_handler
1635 db 'vmaxpd',5Fh
1636 dw avx_pd_instruction-instruction_handler
1637 db 'vmaxps',5Fh
1638 dw avx_ps_instruction-instruction_handler
1639 db 'vmaxsd',5Fh
1640 dw avx_sd_instruction-instruction_handler
1641 db 'vmaxss',5Fh
1642 dw avx_ss_instruction-instruction_handler
1643 db 'vmcall',0C1h
1644 dw simple_vmx_instruction-instruction_handler
1645 db 'vminpd',5Dh
1646 dw avx_pd_instruction-instruction_handler
1647 db 'vminps',5Dh
1648 dw avx_ps_instruction-instruction_handler
1649 db 'vminsd',5Dh
1650 dw avx_sd_instruction-instruction_handler
1651 db 'vminss',5Dh
1652 dw avx_ss_instruction-instruction_handler
1653 db 'vmload',0DAh
1654 dw simple_svm_instruction-instruction_handler
1655 db 'vmovsd',0
1656 dw avx_movsd_instruction-instruction_handler
1657 db 'vmovss',0
1658 dw avx_movss_instruction-instruction_handler
1659 db 'vmread',0
1660 dw vmread_instruction-instruction_handler
1661 db 'vmsave',0DBh
1662 dw simple_svm_instruction-instruction_handler
1663 db 'vmulpd',59h
1664 dw avx_pd_instruction-instruction_handler
1665 db 'vmulps',59h
1666 dw avx_ps_instruction-instruction_handler
1667 db 'vmulsd',59h
1668 dw avx_sd_instruction-instruction_handler
1669 db 'vmulss',59h
1670 dw avx_ss_instruction-instruction_handler
1671 db 'vmxoff',0C4h
1672 dw simple_vmx_instruction-instruction_handler
1673 db 'vpabsb',1Ch
1674 dw avx_single_source_instruction_38-instruction_handler
1675 db 'vpabsd',1Eh
1676 dw avx_single_source_instruction_38-instruction_handler
1677 db 'vpabsw',1Dh
1678 dw avx_single_source_instruction_38-instruction_handler
1679 db 'vpaddb',0FCh
1680 dw avx_pd_instruction-instruction_handler
1681 db 'vpaddd',0FEh
1682 dw avx_pd_instruction-instruction_handler
1683 db 'vpaddq',0D4h
1684 dw avx_pd_instruction-instruction_handler
1685 db 'vpaddw',0FDh
1686 dw avx_pd_instruction-instruction_handler
1687 db 'vpandn',0DFh
1688 dw avx_pd_instruction-instruction_handler
1689 db 'vpavgb',0E0h
1690 dw avx_pd_instruction-instruction_handler
1691 db 'vpavgw',0E3h
1692 dw avx_pd_instruction-instruction_handler
1693 db 'vpcmov',0A2h
1694 dw vpcmov_instruction-instruction_handler
1695 db 'vpcomb',-1
1696 dw xop_pcom_b_instruction-instruction_handler
1697 db 'vpcomd',-1
1698 dw xop_pcom_d_instruction-instruction_handler
1699 db 'vpcomq',-1
1700 dw xop_pcom_q_instruction-instruction_handler
1701 db 'vpcomw',-1
1702 dw xop_pcom_w_instruction-instruction_handler
1703 db 'vpermd',36h
1704 dw avx_permd_instruction-instruction_handler
1705 db 'vpermq',0
1706 dw avx_permq_instruction-instruction_handler
1707 db 'vpperm',0A3h
1708 dw xop_128bit_instruction-instruction_handler
1709 db 'vprotb',90h
1710 dw xop_shift_instruction-instruction_handler
1711 db 'vprotd',92h
1712 dw xop_shift_instruction-instruction_handler
1713 db 'vprotq',93h
1714 dw xop_shift_instruction-instruction_handler
1715 db 'vprotw',91h
1716 dw xop_shift_instruction-instruction_handler
1717 db 'vpshab',98h
1718 dw xop_shift_instruction-instruction_handler
1719 db 'vpshad',9Ah
1720 dw xop_shift_instruction-instruction_handler
1721 db 'vpshaq',9Bh
1722 dw xop_shift_instruction-instruction_handler
1723 db 'vpshaw',99h
1724 dw xop_shift_instruction-instruction_handler
1725 db 'vpshlb',94h
1726 dw xop_shift_instruction-instruction_handler
1727 db 'vpshld',96h
1728 dw xop_shift_instruction-instruction_handler
1729 db 'vpshlq',97h
1730 dw xop_shift_instruction-instruction_handler
1731 db 'vpshlw',95h
1732 dw xop_shift_instruction-instruction_handler
1733 db 'vpslld',0F2h
1734 dw avx_bit_shift_instruction-instruction_handler
1735 db 'vpsllq',0F3h
1736 dw avx_bit_shift_instruction-instruction_handler
1737 db 'vpsllw',0F1h
1738 dw avx_bit_shift_instruction-instruction_handler
1739 db 'vpsrad',0E2h
1740 dw avx_bit_shift_instruction-instruction_handler
1741 db 'vpsraw',0E1h
1742 dw avx_bit_shift_instruction-instruction_handler
1743 db 'vpsrld',0D2h
1744 dw avx_bit_shift_instruction-instruction_handler
1745 db 'vpsrlq',0D3h
1746 dw avx_bit_shift_instruction-instruction_handler
1747 db 'vpsrlw',0D1h
1748 dw avx_bit_shift_instruction-instruction_handler
1749 db 'vpsubb',0F8h
1750 dw avx_pd_instruction-instruction_handler
1751 db 'vpsubd',0FAh
1752 dw avx_pd_instruction-instruction_handler
1753 db 'vpsubq',0FBh
1754 dw avx_pd_instruction-instruction_handler
1755 db 'vpsubw',0F9h
1756 dw avx_pd_instruction-instruction_handler
1757 db 'vptest',17h
1758 dw avx_single_source_instruction_38-instruction_handler
1759 db 'vrcpps',53h
1760 dw avx_single_source_ps_instruction-instruction_handler
1761 db 'vrcpss',53h
1762 dw avx_ss_instruction-instruction_handler
1763 db 'vsubpd',5Ch
1764 dw avx_pd_instruction-instruction_handler
1765 db 'vsubps',5Ch
1766 dw avx_ps_instruction-instruction_handler
1767 db 'vsubsd',5Ch
1768 dw avx_sd_instruction-instruction_handler
1769 db 'vsubss',5Ch
1770 dw avx_ss_instruction-instruction_handler
1771 db 'vxorpd',57h
1772 dw avx_pd_instruction-instruction_handler
1773 db 'vxorps',57h
1774 dw avx_ps_instruction-instruction_handler
1775 db 'wbinvd',9
1776 dw simple_extended_instruction-instruction_handler
1777 db 'wrmsrq',30h
1778 dw simple_extended_instruction_64bit-instruction_handler
1779 db 'xabort',0
1780 dw xabort_instruction-instruction_handler
1781 db 'xbegin',0
1782 dw xbegin_instruction-instruction_handler
1783 db 'xgetbv',0D0h
1784 dw simple_vmx_instruction-instruction_handler
1785 db 'xrstor',101b
1786 dw fxsave_instruction-instruction_handler
1787 db 'xsetbv',0D1h
1788 dw simple_vmx_instruction-instruction_handler
1789 instructions_7:
1790 db 'blcfill',11h
1791 dw tbm_instruction-instruction_handler
1792 db 'blendpd',0Dh
1793 dw sse4_instruction_3a_imm8-instruction_handler
1794 db 'blendps',0Ch
1795 dw sse4_instruction_3a_imm8-instruction_handler
1796 db 'blsfill',12h
1797 dw tbm_instruction-instruction_handler
1798 db 'clflush',111b
1799 dw fxsave_instruction-instruction_handler
1800 db 'cmovnae',42h
1801 dw bs_instruction-instruction_handler
1802 db 'cmovnbe',47h
1803 dw bs_instruction-instruction_handler
1804 db 'cmovnge',4Ch
1805 dw bs_instruction-instruction_handler
1806 db 'cmovnle',4Fh
1807 dw bs_instruction-instruction_handler
1808 db 'cmpeqpd',0
1809 dw cmp_pd_instruction-instruction_handler
1810 db 'cmpeqps',0
1811 dw cmp_ps_instruction-instruction_handler
1812 db 'cmpeqsd',0
1813 dw cmp_sd_instruction-instruction_handler
1814 db 'cmpeqss',0
1815 dw cmp_ss_instruction-instruction_handler
1816 db 'cmplepd',2
1817 dw cmp_pd_instruction-instruction_handler
1818 db 'cmpleps',2
1819 dw cmp_ps_instruction-instruction_handler
1820 db 'cmplesd',2
1821 dw cmp_sd_instruction-instruction_handler
1822 db 'cmpless',2
1823 dw cmp_ss_instruction-instruction_handler
1824 db 'cmpltpd',1
1825 dw cmp_pd_instruction-instruction_handler
1826 db 'cmpltps',1
1827 dw cmp_ps_instruction-instruction_handler
1828 db 'cmpltsd',1
1829 dw cmp_sd_instruction-instruction_handler
1830 db 'cmpltss',1
1831 dw cmp_ss_instruction-instruction_handler
1832 db 'cmpxchg',0B0h
1833 dw basic_486_instruction-instruction_handler
1834 db 'display',0
1835 dw display_directive-instruction_handler
1836 db 'fcmovbe',0D0h
1837 dw fcmov_instruction-instruction_handler
1838 db 'fcmovnb',0C0h
1839 dw fcomi_instruction-instruction_handler
1840 db 'fcmovne',0C8h
1841 dw fcomi_instruction-instruction_handler
1842 db 'fcmovnu',0D8h
1843 dw fcomi_instruction-instruction_handler
1844 db 'fdecstp',110110b
1845 dw simple_fpu_instruction-instruction_handler
1846 db 'fincstp',110111b
1847 dw simple_fpu_instruction-instruction_handler
1848 db 'fldenvd',4
1849 dw fldenv_instruction_32bit-instruction_handler
1850 db 'fldenvw',4
1851 dw fldenv_instruction_16bit-instruction_handler
1852 db 'fnsaved',6
1853 dw fnsave_instruction_32bit-instruction_handler
1854 db 'fnsavew',6
1855 dw fnsave_instruction_16bit-instruction_handler
1856 db 'fnstenv',6
1857 dw fldenv_instruction-instruction_handler
1858 db 'frndint',111100b
1859 dw simple_fpu_instruction-instruction_handler
1860 db 'frstord',4
1861 dw fnsave_instruction_32bit-instruction_handler
1862 db 'frstorw',4
1863 dw fnsave_instruction_16bit-instruction_handler
1864 db 'fsincos',111011b
1865 dw simple_fpu_instruction-instruction_handler
1866 db 'fstenvd',6
1867 dw fstenv_instruction_32bit-instruction_handler
1868 db 'fstenvw',6
1869 dw fstenv_instruction_16bit-instruction_handler
1870 db 'fucomip',0E8h
1871 dw fcomip_instruction-instruction_handler
1872 db 'fucompp',0
1873 dw fucompp_instruction-instruction_handler
1874 db 'fxrstor',1
1875 dw fxsave_instruction-instruction_handler
1876 db 'fxtract',110100b
1877 dw simple_fpu_instruction-instruction_handler
1878 db 'fyl2xp1',111001b
1879 dw simple_fpu_instruction-instruction_handler
1880 db 'insertq',0
1881 dw insertq_instruction-instruction_handler
1882 db 'invlpga',0DFh
1883 dw invlpga_instruction-instruction_handler
1884 db 'invpcid',82h
1885 dw vmx_inv_instruction-instruction_handler
1886 db 'invvpid',81h
1887 dw vmx_inv_instruction-instruction_handler
1888 db 'ldmxcsr',10b
1889 dw fxsave_instruction-instruction_handler
1890 db 'loopned',0E0h
1891 dw loop_instruction_32bit-instruction_handler
1892 db 'loopneq',0E0h
1893 dw loop_instruction_64bit-instruction_handler
1894 db 'loopnew',0E0h
1895 dw loop_instruction_16bit-instruction_handler
1896 db 'loopnzd',0E0h
1897 dw loop_instruction_32bit-instruction_handler
1898 db 'loopnzq',0E0h
1899 dw loop_instruction_64bit-instruction_handler
1900 db 'loopnzw',0E0h
1901 dw loop_instruction_16bit-instruction_handler
1902 db 'monitor',0C8h
1903 dw monitor_instruction-instruction_handler
1904 db 'movddup',12h
1905 dw sse_sd_instruction-instruction_handler
1906 db 'movdq2q',0
1907 dw movdq2q_instruction-instruction_handler
1908 db 'movhlps',12h
1909 dw movhlps_instruction-instruction_handler
1910 db 'movlhps',16h
1911 dw movhlps_instruction-instruction_handler
1912 db 'movntdq',0E7h
1913 dw movntpd_instruction-instruction_handler
1914 db 'movntpd',2Bh
1915 dw movntpd_instruction-instruction_handler
1916 db 'movntps',2Bh
1917 dw movntps_instruction-instruction_handler
1918 db 'movntsd',2Bh
1919 dw movntsd_instruction-instruction_handler
1920 db 'movntss',2Bh
1921 dw movntss_instruction-instruction_handler
1922 db 'movq2dq',0
1923 dw movq2dq_instruction-instruction_handler
1924 db 'mpsadbw',42h
1925 dw sse4_instruction_3a_imm8-instruction_handler
1926 db 'paddusb',0DCh
1927 dw basic_mmx_instruction-instruction_handler
1928 db 'paddusw',0DDh
1929 dw basic_mmx_instruction-instruction_handler
1930 db 'palignr',0
1931 dw palignr_instruction-instruction_handler
1932 db 'pavgusb',0BFh
1933 dw amd3dnow_instruction-instruction_handler
1934 db 'pblendw',0Eh
1935 dw sse4_instruction_3a_imm8-instruction_handler
1936 db 'pcmpeqb',74h
1937 dw basic_mmx_instruction-instruction_handler
1938 db 'pcmpeqd',76h
1939 dw basic_mmx_instruction-instruction_handler
1940 db 'pcmpeqq',29h
1941 dw sse4_instruction_38-instruction_handler
1942 db 'pcmpeqw',75h
1943 dw basic_mmx_instruction-instruction_handler
1944 db 'pcmpgtb',64h
1945 dw basic_mmx_instruction-instruction_handler
1946 db 'pcmpgtd',66h
1947 dw basic_mmx_instruction-instruction_handler
1948 db 'pcmpgtq',37h
1949 dw sse4_instruction_38-instruction_handler
1950 db 'pcmpgtw',65h
1951 dw basic_mmx_instruction-instruction_handler
1952 db 'pfcmpeq',0B0h
1953 dw amd3dnow_instruction-instruction_handler
1954 db 'pfcmpge',90h
1955 dw amd3dnow_instruction-instruction_handler
1956 db 'pfcmpgt',0A0h
1957 dw amd3dnow_instruction-instruction_handler
1958 db 'pfpnacc',8Eh
1959 dw amd3dnow_instruction-instruction_handler
1960 db 'pfrsqrt',97h
1961 dw amd3dnow_instruction-instruction_handler
1962 db 'phaddsw',3
1963 dw ssse3_instruction-instruction_handler
1964 db 'phsubsw',7
1965 dw ssse3_instruction-instruction_handler
1966 db 'pmaddwd',0F5h
1967 dw basic_mmx_instruction-instruction_handler
1968 db 'pmulhrw',0B7h
1969 dw amd3dnow_instruction-instruction_handler
1970 db 'pmulhuw',0E4h
1971 dw basic_mmx_instruction-instruction_handler
1972 db 'pmuludq',0F4h
1973 dw basic_mmx_instruction-instruction_handler
1974 db 'pshufhw',0F3h
1975 dw pshufd_instruction-instruction_handler
1976 db 'pshuflw',0F2h
1977 dw pshufd_instruction-instruction_handler
1978 db 'psubusb',0D8h
1979 dw basic_mmx_instruction-instruction_handler
1980 db 'psubusw',0D9h
1981 dw basic_mmx_instruction-instruction_handler
1982 db 'roundpd',9
1983 dw sse4_instruction_3a_imm8-instruction_handler
1984 db 'roundps',8
1985 dw sse4_instruction_3a_imm8-instruction_handler
1986 db 'roundsd',0Bh
1987 dw sse4_sd_instruction_3a_imm8-instruction_handler
1988 db 'roundss',0Ah
1989 dw sse4_ss_instruction_3a_imm8-instruction_handler
1990 db 'rsqrtps',52h
1991 dw sse_ps_instruction-instruction_handler
1992 db 'rsqrtss',52h
1993 dw sse_ss_instruction-instruction_handler
1994 db 'section',0
1995 dw section_directive-instruction_handler
1996 db 'segment',0
1997 dw segment_directive-instruction_handler
1998 db 'stmxcsr',11b
1999 dw fxsave_instruction-instruction_handler
2000 db 'syscall',05h
2001 dw simple_extended_instruction-instruction_handler
2002 db 'sysexit',35h
2003 dw simple_extended_instruction-instruction_handler
2004 db 'sysretq',07h
2005 dw simple_extended_instruction_64bit-instruction_handler
2006 db 'ucomisd',2Eh
2007 dw comisd_instruction-instruction_handler
2008 db 'ucomiss',2Eh
2009 dw comiss_instruction-instruction_handler
2010 db 'vaesdec',0DEh
2011 dw avx_128bit_instruction_38-instruction_handler
2012 db 'vaesenc',0DCh
2013 dw avx_128bit_instruction_38-instruction_handler
2014 db 'vaesimc',0DBh
2015 dw avx_single_source_128bit_instruction_38-instruction_handler
2016 db 'vandnpd',55h
2017 dw avx_pd_instruction-instruction_handler
2018 db 'vandnps',55h
2019 dw avx_ps_instruction-instruction_handler
2020 db 'vcomisd',2Fh
2021 dw avx_comisd_instruction-instruction_handler
2022 db 'vcomiss',2Fh
2023 dw avx_comiss_instruction-instruction_handler
2024 db 'vfrczpd',81h
2025 dw xop_single_source_instruction-instruction_handler
2026 db 'vfrczps',80h
2027 dw xop_single_source_instruction-instruction_handler
2028 db 'vfrczsd',83h
2029 dw xop_single_source_sd_instruction-instruction_handler
2030 db 'vfrczss',82h
2031 dw xop_single_source_ss_instruction-instruction_handler
2032 db 'vhaddpd',07Ch
2033 dw avx_pd_instruction-instruction_handler
2034 db 'vhaddps',07Ch
2035 dw avx_haddps_instruction-instruction_handler
2036 db 'vhsubpd',07Dh
2037 dw avx_pd_instruction-instruction_handler
2038 db 'vhsubps',07Dh
2039 dw avx_haddps_instruction-instruction_handler
2040 db 'virtual',0
2041 dw virtual_directive-instruction_handler
2042 db 'vmclear',6
2043 dw vmclear_instruction-instruction_handler
2044 db 'vmmcall',0D9h
2045 dw simple_vmx_instruction-instruction_handler
2046 db 'vmovapd',28h
2047 dw avx_movpd_instruction-instruction_handler
2048 db 'vmovaps',28h
2049 dw avx_movps_instruction-instruction_handler
2050 db 'vmovdqa',6Fh
2051 dw avx_movpd_instruction-instruction_handler
2052 db 'vmovdqu',6Fh
2053 dw avx_movdqu_instruction-instruction_handler
2054 db 'vmovhpd',16h
2055 dw avx_movlpd_instruction-instruction_handler
2056 db 'vmovhps',16h
2057 dw avx_movlps_instruction-instruction_handler
2058 db 'vmovlpd',12h
2059 dw avx_movlpd_instruction-instruction_handler
2060 db 'vmovlps',12h
2061 dw avx_movlps_instruction-instruction_handler
2062 db 'vmovupd',10h
2063 dw avx_movpd_instruction-instruction_handler
2064 db 'vmovups',10h
2065 dw avx_movps_instruction-instruction_handler
2066 db 'vmptrld',6
2067 dw vmx_instruction-instruction_handler
2068 db 'vmptrst',7
2069 dw vmx_instruction-instruction_handler
2070 db 'vmwrite',0
2071 dw vmwrite_instruction-instruction_handler
2072 db 'vpaddsb',0ECh
2073 dw avx_pd_instruction-instruction_handler
2074 db 'vpaddsw',0EDh
2075 dw avx_pd_instruction-instruction_handler
2076 db 'vpcomub',-1
2077 dw xop_pcom_ub_instruction-instruction_handler
2078 db 'vpcomud',-1
2079 dw xop_pcom_ud_instruction-instruction_handler
2080 db 'vpcomuq',-1
2081 dw xop_pcom_uq_instruction-instruction_handler
2082 db 'vpcomuw',-1
2083 dw xop_pcom_uw_instruction-instruction_handler
2084 db 'vpermpd',1
2085 dw avx_permq_instruction-instruction_handler
2086 db 'vpermps',16h
2087 dw avx_permd_instruction-instruction_handler
2088 db 'vpextrb',14h
2089 dw avx_pextrb_instruction-instruction_handler
2090 db 'vpextrd',16h
2091 dw avx_pextrd_instruction-instruction_handler
2092 db 'vpextrq',16h
2093 dw avx_pextrq_instruction-instruction_handler
2094 db 'vpextrw',15h
2095 dw avx_pextrw_instruction-instruction_handler
2096 db 'vphaddd',2
2097 dw avx_instruction_38-instruction_handler
2098 db 'vphaddw',1
2099 dw avx_instruction_38-instruction_handler
2100 db 'vphsubd',6
2101 dw avx_instruction_38-instruction_handler
2102 db 'vphsubw',5
2103 dw avx_instruction_38-instruction_handler
2104 db 'vpinsrb',20h
2105 dw avx_pinsrb_instruction-instruction_handler
2106 db 'vpinsrd',22h
2107 dw avx_pinsrd_instruction-instruction_handler
2108 db 'vpinsrq',22h
2109 dw avx_pinsrq_instruction-instruction_handler
2110 db 'vpinsrw',0C4h
2111 dw avx_pinsrw_instruction-instruction_handler
2112 db 'vpmaxsb',3Ch
2113 dw avx_instruction_38-instruction_handler
2114 db 'vpmaxsd',3Dh
2115 dw avx_instruction_38-instruction_handler
2116 db 'vpmaxsw',0EEh
2117 dw avx_pd_instruction-instruction_handler
2118 db 'vpmaxub',0DEh
2119 dw avx_pd_instruction-instruction_handler
2120 db 'vpmaxud',3Fh
2121 dw avx_instruction_38-instruction_handler
2122 db 'vpmaxuw',3Eh
2123 dw avx_instruction_38-instruction_handler
2124 db 'vpminsb',38h
2125 dw avx_instruction_38-instruction_handler
2126 db 'vpminsd',39h
2127 dw avx_instruction_38-instruction_handler
2128 db 'vpminsw',0EAh
2129 dw avx_pd_instruction-instruction_handler
2130 db 'vpminub',0DAh
2131 dw avx_pd_instruction-instruction_handler
2132 db 'vpminud',3Bh
2133 dw avx_instruction_38-instruction_handler
2134 db 'vpminuw',3Ah
2135 dw avx_instruction_38-instruction_handler
2136 db 'vpmuldq',28h
2137 dw avx_instruction_38-instruction_handler
2138 db 'vpmulhw',0E5h
2139 dw avx_pd_instruction-instruction_handler
2140 db 'vpmulld',40h
2141 dw avx_instruction_38-instruction_handler
2142 db 'vpmullw',0D5h
2143 dw avx_pd_instruction-instruction_handler
2144 db 'vpsadbw',0F6h
2145 dw avx_pd_instruction-instruction_handler
2146 db 'vpshufb',0
2147 dw avx_instruction_38-instruction_handler
2148 db 'vpshufd',66h
2149 dw avx_pshufd_instruction-instruction_handler
2150 db 'vpsignb',8
2151 dw avx_instruction_38-instruction_handler
2152 db 'vpsignd',0Ah
2153 dw avx_instruction_38-instruction_handler
2154 db 'vpsignw',9
2155 dw avx_instruction_38-instruction_handler
2156 db 'vpslldq',111b
2157 dw avx_pslldq_instruction-instruction_handler
2158 db 'vpsllvd',47h
2159 dw avx_instruction_38-instruction_handler
2160 db 'vpsllvq',47h
2161 dw avx_instruction_38_w1-instruction_handler
2162 db 'vpsravd',46h
2163 dw avx_instruction_38-instruction_handler
2164 db 'vpsrldq',011b
2165 dw avx_pslldq_instruction-instruction_handler
2166 db 'vpsrlvd',45h
2167 dw avx_instruction_38-instruction_handler
2168 db 'vpsrlvq',45h
2169 dw avx_instruction_38_w1-instruction_handler
2170 db 'vpsubsb',0E8h
2171 dw avx_pd_instruction-instruction_handler
2172 db 'vpsubsw',0E9h
2173 dw avx_pd_instruction-instruction_handler
2174 db 'vshufpd',0C6h
2175 dw avx_pd_instruction_imm8-instruction_handler
2176 db 'vshufps',0C6h
2177 dw avx_ps_instruction_imm8-instruction_handler
2178 db 'vsqrtpd',51h
2179 dw avx_single_source_pd_instruction-instruction_handler
2180 db 'vsqrtps',51h
2181 dw avx_single_source_ps_instruction-instruction_handler
2182 db 'vsqrtsd',51h
2183 dw avx_sd_instruction-instruction_handler
2184 db 'vsqrtss',51h
2185 dw avx_ss_instruction-instruction_handler
2186 db 'vtestpd',0Fh
2187 dw avx_single_source_instruction_38-instruction_handler
2188 db 'vtestps',0Eh
2189 dw avx_single_source_instruction_38-instruction_handler
2190 db 'xsave64',100b
2191 dw fxsave_instruction_64bit-instruction_handler
2192 instructions_8:
2193 db 'addsubpd',0D0h
2194 dw sse_pd_instruction-instruction_handler
2195 db 'addsubps',0D0h
2196 dw cvtpd2dq_instruction-instruction_handler
2197 db 'blendvpd',15h
2198 dw sse4_instruction_38_xmm0-instruction_handler
2199 db 'blendvps',14h
2200 dw sse4_instruction_38_xmm0-instruction_handler
2201 db 'cmpneqpd',4
2202 dw cmp_pd_instruction-instruction_handler
2203 db 'cmpneqps',4
2204 dw cmp_ps_instruction-instruction_handler
2205 db 'cmpneqsd',4
2206 dw cmp_sd_instruction-instruction_handler
2207 db 'cmpneqss',4
2208 dw cmp_ss_instruction-instruction_handler
2209 db 'cmpnlepd',6
2210 dw cmp_pd_instruction-instruction_handler
2211 db 'cmpnleps',6
2212 dw cmp_ps_instruction-instruction_handler
2213 db 'cmpnlesd',6
2214 dw cmp_sd_instruction-instruction_handler
2215 db 'cmpnless',6
2216 dw cmp_ss_instruction-instruction_handler
2217 db 'cmpnltpd',5
2218 dw cmp_pd_instruction-instruction_handler
2219 db 'cmpnltps',5
2220 dw cmp_ps_instruction-instruction_handler
2221 db 'cmpnltsd',5
2222 dw cmp_sd_instruction-instruction_handler
2223 db 'cmpnltss',5
2224 dw cmp_ss_instruction-instruction_handler
2225 db 'cmpordpd',7
2226 dw cmp_pd_instruction-instruction_handler
2227 db 'cmpordps',7
2228 dw cmp_ps_instruction-instruction_handler
2229 db 'cmpordsd',7
2230 dw cmp_sd_instruction-instruction_handler
2231 db 'cmpordss',7
2232 dw cmp_ss_instruction-instruction_handler
2233 db 'cvtdq2pd',0E6h
2234 dw cvtdq2pd_instruction-instruction_handler
2235 db 'cvtdq2ps',5Bh
2236 dw sse_ps_instruction-instruction_handler
2237 db 'cvtpd2dq',0E6h
2238 dw cvtpd2dq_instruction-instruction_handler
2239 db 'cvtpd2pi',2Dh
2240 dw cvtpd2pi_instruction-instruction_handler
2241 db 'cvtpd2ps',5Ah
2242 dw sse_pd_instruction-instruction_handler
2243 db 'cvtpi2pd',2Ah
2244 dw cvtpi2pd_instruction-instruction_handler
2245 db 'cvtpi2ps',2Ah
2246 dw cvtpi2ps_instruction-instruction_handler
2247 db 'cvtps2dq',5Bh
2248 dw sse_pd_instruction-instruction_handler
2249 db 'cvtps2pd',5Ah
2250 dw cvtps2pd_instruction-instruction_handler
2251 db 'cvtps2pi',2Dh
2252 dw cvtps2pi_instruction-instruction_handler
2253 db 'cvtsd2si',2Dh
2254 dw cvtsd2si_instruction-instruction_handler
2255 db 'cvtsd2ss',5Ah
2256 dw sse_sd_instruction-instruction_handler
2257 db 'cvtsi2sd',2Ah
2258 dw cvtsi2sd_instruction-instruction_handler
2259 db 'cvtsi2ss',2Ah
2260 dw cvtsi2ss_instruction-instruction_handler
2261 db 'cvtss2sd',5Ah
2262 dw sse_ss_instruction-instruction_handler
2263 db 'cvtss2si',2Dh
2264 dw cvtss2si_instruction-instruction_handler
2265 db 'fcmovnbe',0D0h
2266 dw fcomi_instruction-instruction_handler
2267 db 'fnstenvd',6
2268 dw fldenv_instruction_32bit-instruction_handler
2269 db 'fnstenvw',6
2270 dw fldenv_instruction_16bit-instruction_handler
2271 db 'fxsave64',0
2272 dw fxsave_instruction_64bit-instruction_handler
2273 db 'insertps',0
2274 dw insertps_instruction-instruction_handler
2275 db 'maskmovq',0
2276 dw maskmovq_instruction-instruction_handler
2277 db 'movmskpd',0
2278 dw movmskpd_instruction-instruction_handler
2279 db 'movmskps',0
2280 dw movmskps_instruction-instruction_handler
2281 db 'movntdqa',2Ah
2282 dw movntdqa_instruction-instruction_handler
2283 db 'movshdup',16h
2284 dw movshdup_instruction-instruction_handler
2285 db 'movsldup',12h
2286 dw movshdup_instruction-instruction_handler
2287 db 'packssdw',6Bh
2288 dw basic_mmx_instruction-instruction_handler
2289 db 'packsswb',63h
2290 dw basic_mmx_instruction-instruction_handler
2291 db 'packusdw',2Bh
2292 dw sse4_instruction_38-instruction_handler
2293 db 'packuswb',67h
2294 dw basic_mmx_instruction-instruction_handler
2295 db 'pblendvb',10h
2296 dw sse4_instruction_38_xmm0-instruction_handler
2297 db 'pfrcpit1',0A6h
2298 dw amd3dnow_instruction-instruction_handler
2299 db 'pfrcpit2',0B6h
2300 dw amd3dnow_instruction-instruction_handler
2301 db 'pfrsqit1',0A7h
2302 dw amd3dnow_instruction-instruction_handler
2303 db 'pmovmskb',0D7h
2304 dw pmovmskb_instruction-instruction_handler
2305 db 'pmovsxbd',21h
2306 dw pmovsxbd_instruction-instruction_handler
2307 db 'pmovsxbq',22h
2308 dw pmovsxbq_instruction-instruction_handler
2309 db 'pmovsxbw',20h
2310 dw pmovsxbw_instruction-instruction_handler
2311 db 'pmovsxdq',25h
2312 dw pmovsxdq_instruction-instruction_handler
2313 db 'pmovsxwd',23h
2314 dw pmovsxwd_instruction-instruction_handler
2315 db 'pmovsxwq',24h
2316 dw pmovsxwq_instruction-instruction_handler
2317 db 'pmovzxbd',31h
2318 dw pmovsxbd_instruction-instruction_handler
2319 db 'pmovzxbq',32h
2320 dw pmovsxbq_instruction-instruction_handler
2321 db 'pmovzxbw',30h
2322 dw pmovsxbw_instruction-instruction_handler
2323 db 'pmovzxdq',35h
2324 dw pmovsxdq_instruction-instruction_handler
2325 db 'pmovzxwd',33h
2326 dw pmovsxwd_instruction-instruction_handler
2327 db 'pmovzxwq',34h
2328 dw pmovsxwq_instruction-instruction_handler
2329 db 'pmulhrsw',0Bh
2330 dw ssse3_instruction-instruction_handler
2331 db 'prefetch',0
2332 dw amd_prefetch_instruction-instruction_handler
2333 db 'rdfsbase',0
2334 dw rdfsbase_instruction-instruction_handler
2335 db 'rdgsbase',1
2336 dw rdfsbase_instruction-instruction_handler
2337 db 'sysenter',34h
2338 dw simple_extended_instruction-instruction_handler
2339 db 'sysexitq',35h
2340 dw simple_extended_instruction_64bit-instruction_handler
2341 db 'unpckhpd',15h
2342 dw sse_pd_instruction-instruction_handler
2343 db 'unpckhps',15h
2344 dw sse_ps_instruction-instruction_handler
2345 db 'unpcklpd',14h
2346 dw sse_pd_instruction-instruction_handler
2347 db 'unpcklps',14h
2348 dw sse_ps_instruction-instruction_handler
2349 db 'vblendpd',0Dh
2350 dw avx_instruction_3a_imm8-instruction_handler
2351 db 'vblendps',0Ch
2352 dw avx_instruction_3a_imm8-instruction_handler
2353 db 'vcmpeqpd',0
2354 dw avx_cmp_pd_instruction-instruction_handler
2355 db 'vcmpeqps',0
2356 dw avx_cmp_ps_instruction-instruction_handler
2357 db 'vcmpeqsd',0
2358 dw avx_cmp_sd_instruction-instruction_handler
2359 db 'vcmpeqss',0
2360 dw avx_cmp_ss_instruction-instruction_handler
2361 db 'vcmpgepd',0Dh
2362 dw avx_cmp_pd_instruction-instruction_handler
2363 db 'vcmpgeps',0Dh
2364 dw avx_cmp_ps_instruction-instruction_handler
2365 db 'vcmpgesd',0Dh
2366 dw avx_cmp_sd_instruction-instruction_handler
2367 db 'vcmpgess',0Dh
2368 dw avx_cmp_ss_instruction-instruction_handler
2369 db 'vcmpgtpd',0Eh
2370 dw avx_cmp_pd_instruction-instruction_handler
2371 db 'vcmpgtps',0Eh
2372 dw avx_cmp_ps_instruction-instruction_handler
2373 db 'vcmpgtsd',0Eh
2374 dw avx_cmp_sd_instruction-instruction_handler
2375 db 'vcmpgtss',0Eh
2376 dw avx_cmp_ss_instruction-instruction_handler
2377 db 'vcmplepd',2
2378 dw avx_cmp_pd_instruction-instruction_handler
2379 db 'vcmpleps',2
2380 dw avx_cmp_ps_instruction-instruction_handler
2381 db 'vcmplesd',2
2382 dw avx_cmp_sd_instruction-instruction_handler
2383 db 'vcmpless',2
2384 dw avx_cmp_ss_instruction-instruction_handler
2385 db 'vcmpltpd',1
2386 dw avx_cmp_pd_instruction-instruction_handler
2387 db 'vcmpltps',1
2388 dw avx_cmp_ps_instruction-instruction_handler
2389 db 'vcmpltsd',1
2390 dw avx_cmp_sd_instruction-instruction_handler
2391 db 'vcmpltss',1
2392 dw avx_cmp_ss_instruction-instruction_handler
2393 db 'vfmaddpd',69h
2394 dw fma4_instruction_p-instruction_handler
2395 db 'vfmaddps',68h
2396 dw fma4_instruction_p-instruction_handler
2397 db 'vfmaddsd',6Bh
2398 dw fma4_instruction_sd-instruction_handler
2399 db 'vfmaddss',6Ah
2400 dw fma4_instruction_ss-instruction_handler
2401 db 'vfmsubpd',6Dh
2402 dw fma4_instruction_p-instruction_handler
2403 db 'vfmsubps',6Ch
2404 dw fma4_instruction_p-instruction_handler
2405 db 'vfmsubsd',6Fh
2406 dw fma4_instruction_sd-instruction_handler
2407 db 'vfmsubss',6Eh
2408 dw fma4_instruction_ss-instruction_handler
2409 db 'vldmxcsr',10b
2410 dw vldmxcsr_instruction-instruction_handler
2411 db 'vmlaunch',0C2h
2412 dw simple_vmx_instruction-instruction_handler
2413 db 'vmovddup',12h
2414 dw avx_movddup_instruction-instruction_handler
2415 db 'vmovhlps',12h
2416 dw avx_movhlps_instruction-instruction_handler
2417 db 'vmovlhps',16h
2418 dw avx_movhlps_instruction-instruction_handler
2419 db 'vmovntdq',0E7h
2420 dw avx_movntpd_instruction-instruction_handler
2421 db 'vmovntpd',2Bh
2422 dw avx_movntpd_instruction-instruction_handler
2423 db 'vmovntps',2Bh
2424 dw avx_movntps_instruction-instruction_handler
2425 db 'vmpsadbw',42h
2426 dw avx_instruction_3a_imm8-instruction_handler
2427 db 'vmresume',0C3h
2428 dw simple_vmx_instruction-instruction_handler
2429 db 'vpaddusb',0DCh
2430 dw avx_pd_instruction-instruction_handler
2431 db 'vpaddusw',0DDh
2432 dw avx_pd_instruction-instruction_handler
2433 db 'vpalignr',0Fh
2434 dw avx_instruction_3a_imm8-instruction_handler
2435 db 'vpblendd',2
2436 dw avx_instruction_3a_imm8-instruction_handler
2437 db 'vpblendw',0Eh
2438 dw avx_instruction_3a_imm8-instruction_handler
2439 db 'vpcmpeqb',74h
2440 dw avx_pd_instruction-instruction_handler
2441 db 'vpcmpeqd',76h
2442 dw avx_pd_instruction-instruction_handler
2443 db 'vpcmpeqq',29h
2444 dw avx_instruction_38-instruction_handler
2445 db 'vpcmpeqw',75h
2446 dw avx_pd_instruction-instruction_handler
2447 db 'vpcmpgtb',64h
2448 dw avx_pd_instruction-instruction_handler
2449 db 'vpcmpgtd',66h
2450 dw avx_pd_instruction-instruction_handler
2451 db 'vpcmpgtq',37h
2452 dw avx_instruction_38-instruction_handler
2453 db 'vpcmpgtw',65h
2454 dw avx_pd_instruction-instruction_handler
2455 db 'vpcomeqb',4
2456 dw xop_pcom_b_instruction-instruction_handler
2457 db 'vpcomeqd',4
2458 dw xop_pcom_d_instruction-instruction_handler
2459 db 'vpcomeqq',4
2460 dw xop_pcom_q_instruction-instruction_handler
2461 db 'vpcomeqw',4
2462 dw xop_pcom_w_instruction-instruction_handler
2463 db 'vpcomgeb',3
2464 dw xop_pcom_b_instruction-instruction_handler
2465 db 'vpcomged',3
2466 dw xop_pcom_d_instruction-instruction_handler
2467 db 'vpcomgeq',3
2468 dw xop_pcom_q_instruction-instruction_handler
2469 db 'vpcomgew',3
2470 dw xop_pcom_w_instruction-instruction_handler
2471 db 'vpcomgtb',2
2472 dw xop_pcom_b_instruction-instruction_handler
2473 db 'vpcomgtd',2
2474 dw xop_pcom_d_instruction-instruction_handler
2475 db 'vpcomgtq',2
2476 dw xop_pcom_q_instruction-instruction_handler
2477 db 'vpcomgtw',2
2478 dw xop_pcom_w_instruction-instruction_handler
2479 db 'vpcomleb',1
2480 dw xop_pcom_b_instruction-instruction_handler
2481 db 'vpcomled',1
2482 dw xop_pcom_d_instruction-instruction_handler
2483 db 'vpcomleq',1
2484 dw xop_pcom_q_instruction-instruction_handler
2485 db 'vpcomlew',1
2486 dw xop_pcom_w_instruction-instruction_handler
2487 db 'vpcomltb',0
2488 dw xop_pcom_b_instruction-instruction_handler
2489 db 'vpcomltd',0
2490 dw xop_pcom_d_instruction-instruction_handler
2491 db 'vpcomltq',0
2492 dw xop_pcom_q_instruction-instruction_handler
2493 db 'vpcomltw',0
2494 dw xop_pcom_w_instruction-instruction_handler
2495 db 'vphaddbd',0C2h
2496 dw xop_single_source_128bit_instruction-instruction_handler
2497 db 'vphaddbq',0C3h
2498 dw xop_single_source_128bit_instruction-instruction_handler
2499 db 'vphaddbw',0C1h
2500 dw xop_single_source_128bit_instruction-instruction_handler
2501 db 'vphadddq',0CBh
2502 dw xop_single_source_128bit_instruction-instruction_handler
2503 db 'vphaddsw',3
2504 dw avx_instruction_38-instruction_handler
2505 db 'vphaddwd',0C6h
2506 dw xop_single_source_128bit_instruction-instruction_handler
2507 db 'vphaddwq',0C7h
2508 dw xop_single_source_128bit_instruction-instruction_handler
2509 db 'vphsubbw',0E1h
2510 dw xop_single_source_128bit_instruction-instruction_handler
2511 db 'vphsubdq',0E3h
2512 dw xop_single_source_128bit_instruction-instruction_handler
2513 db 'vphsubsw',7
2514 dw avx_instruction_38-instruction_handler
2515 db 'vphsubwd',0E2h
2516 dw xop_single_source_128bit_instruction-instruction_handler
2517 db 'vpmacsdd',9Eh
2518 dw xop_triple_source_128bit_instruction-instruction_handler
2519 db 'vpmacswd',96h
2520 dw xop_triple_source_128bit_instruction-instruction_handler
2521 db 'vpmacsww',95h
2522 dw xop_triple_source_128bit_instruction-instruction_handler
2523 db 'vpmaddwd',0F5h
2524 dw avx_pd_instruction-instruction_handler
2525 db 'vpmulhuw',0E4h
2526 dw avx_pd_instruction-instruction_handler
2527 db 'vpmuludq',0F4h
2528 dw avx_pd_instruction-instruction_handler
2529 db 'vpshufhw',0F3h
2530 dw avx_pshufd_instruction-instruction_handler
2531 db 'vpshuflw',0F2h
2532 dw avx_pshufd_instruction-instruction_handler
2533 db 'vpsubusb',0D8h
2534 dw avx_pd_instruction-instruction_handler
2535 db 'vpsubusw',0D9h
2536 dw avx_pd_instruction-instruction_handler
2537 db 'vroundpd',9
2538 dw avx_single_source_instruction_3a_imm8-instruction_handler
2539 db 'vroundps',8
2540 dw avx_single_source_instruction_3a_imm8-instruction_handler
2541 db 'vroundsd',0Bh
2542 dw avx_sd_instruction_3a_imm8-instruction_handler
2543 db 'vroundss',0Ah
2544 dw avx_ss_instruction_3a_imm8-instruction_handler
2545 db 'vrsqrtps',52h
2546 dw avx_single_source_ps_instruction-instruction_handler
2547 db 'vrsqrtss',52h
2548 dw avx_ss_instruction-instruction_handler
2549 db 'vstmxcsr',11b
2550 dw vldmxcsr_instruction-instruction_handler
2551 db 'vucomisd',2Eh
2552 dw avx_comisd_instruction-instruction_handler
2553 db 'vucomiss',2Eh
2554 dw avx_comiss_instruction-instruction_handler
2555 db 'vzeroall',77h
2556 dw vzeroall_instruction-instruction_handler
2557 db 'wrfsbase',2
2558 dw rdfsbase_instruction-instruction_handler
2559 db 'wrgsbase',3
2560 dw rdfsbase_instruction-instruction_handler
2561 db 'xacquire',0F2h
2562 dw prefix_instruction-instruction_handler
2563 db 'xrelease',0F3h
2564 dw prefix_instruction-instruction_handler
2565 db 'xrstor64',101b
2566 dw fxsave_instruction_64bit-instruction_handler
2567 db 'xsaveopt',110b
2568 dw fxsave_instruction-instruction_handler
2569 instructions_9:
2570 db 'cmpxchg8b',8
2571 dw cmpxchgx_instruction-instruction_handler
2572 db 'cvttpd2dq',0E6h
2573 dw sse_pd_instruction-instruction_handler
2574 db 'cvttpd2pi',2Ch
2575 dw cvtpd2pi_instruction-instruction_handler
2576 db 'cvttps2dq',5Bh
2577 dw movshdup_instruction-instruction_handler
2578 db 'cvttps2pi',2Ch
2579 dw cvtps2pi_instruction-instruction_handler
2580 db 'cvttsd2si',2Ch
2581 dw cvtsd2si_instruction-instruction_handler
2582 db 'cvttss2si',2Ch
2583 dw cvtss2si_instruction-instruction_handler
2584 db 'extractps',0
2585 dw extractps_instruction-instruction_handler
2586 db 'fxrstor64',1
2587 dw fxsave_instruction_64bit-instruction_handler
2588 db 'pclmulqdq',-1
2589 dw pclmulqdq_instruction-instruction_handler
2590 db 'pcmpestri',61h
2591 dw sse4_instruction_3a_imm8-instruction_handler
2592 db 'pcmpestrm',60h
2593 dw sse4_instruction_3a_imm8-instruction_handler
2594 db 'pcmpistri',63h
2595 dw sse4_instruction_3a_imm8-instruction_handler
2596 db 'pcmpistrm',62h
2597 dw sse4_instruction_3a_imm8-instruction_handler
2598 db 'pmaddubsw',4
2599 dw ssse3_instruction-instruction_handler
2600 db 'prefetchw',1
2601 dw amd_prefetch_instruction-instruction_handler
2602 db 'punpckhbw',68h
2603 dw basic_mmx_instruction-instruction_handler
2604 db 'punpckhdq',6Ah
2605 dw basic_mmx_instruction-instruction_handler
2606 db 'punpckhwd',69h
2607 dw basic_mmx_instruction-instruction_handler
2608 db 'punpcklbw',60h
2609 dw basic_mmx_instruction-instruction_handler
2610 db 'punpckldq',62h
2611 dw basic_mmx_instruction-instruction_handler
2612 db 'punpcklwd',61h
2613 dw basic_mmx_instruction-instruction_handler
2614 db 'vaddsubpd',0D0h
2615 dw avx_pd_instruction-instruction_handler
2616 db 'vaddsubps',0D0h
2617 dw avx_haddps_instruction-instruction_handler
2618 db 'vblendvpd',4Bh
2619 dw avx_triple_source_instruction_3a-instruction_handler
2620 db 'vblendvps',4Ah
2621 dw avx_triple_source_instruction_3a-instruction_handler
2622 db 'vcmpneqpd',4
2623 dw avx_cmp_pd_instruction-instruction_handler
2624 db 'vcmpneqps',4
2625 dw avx_cmp_ps_instruction-instruction_handler
2626 db 'vcmpneqsd',4
2627 dw avx_cmp_sd_instruction-instruction_handler
2628 db 'vcmpneqss',4
2629 dw avx_cmp_ss_instruction-instruction_handler
2630 db 'vcmpngepd',9
2631 dw avx_cmp_pd_instruction-instruction_handler
2632 db 'vcmpngeps',9
2633 dw avx_cmp_ps_instruction-instruction_handler
2634 db 'vcmpngesd',9
2635 dw avx_cmp_sd_instruction-instruction_handler
2636 db 'vcmpngess',9
2637 dw avx_cmp_ss_instruction-instruction_handler
2638 db 'vcmpngtpd',0Ah
2639 dw avx_cmp_pd_instruction-instruction_handler
2640 db 'vcmpngtps',0Ah
2641 dw avx_cmp_ps_instruction-instruction_handler
2642 db 'vcmpngtsd',0Ah
2643 dw avx_cmp_sd_instruction-instruction_handler
2644 db 'vcmpngtss',0Ah
2645 dw avx_cmp_ss_instruction-instruction_handler
2646 db 'vcmpnlepd',6
2647 dw avx_cmp_pd_instruction-instruction_handler
2648 db 'vcmpnleps',6
2649 dw avx_cmp_ps_instruction-instruction_handler
2650 db 'vcmpnlesd',6
2651 dw avx_cmp_sd_instruction-instruction_handler
2652 db 'vcmpnless',6
2653 dw avx_cmp_ss_instruction-instruction_handler
2654 db 'vcmpnltpd',5
2655 dw avx_cmp_pd_instruction-instruction_handler
2656 db 'vcmpnltps',5
2657 dw avx_cmp_ps_instruction-instruction_handler
2658 db 'vcmpnltsd',5
2659 dw avx_cmp_sd_instruction-instruction_handler
2660 db 'vcmpnltss',5
2661 dw avx_cmp_ss_instruction-instruction_handler
2662 db 'vcmpordpd',7
2663 dw avx_cmp_pd_instruction-instruction_handler
2664 db 'vcmpordps',7
2665 dw avx_cmp_ps_instruction-instruction_handler
2666 db 'vcmpordsd',7
2667 dw avx_cmp_sd_instruction-instruction_handler
2668 db 'vcmpordss',7
2669 dw avx_cmp_ss_instruction-instruction_handler
2670 db 'vcvtdq2pd',0E6h
2671 dw avx_cvtdq2pd_instruction-instruction_handler
2672 db 'vcvtdq2ps',5Bh
2673 dw avx_single_source_ps_instruction-instruction_handler
2674 db 'vcvtpd2dq',0E6h
2675 dw avx_cvtpd2dq_instruction-instruction_handler
2676 db 'vcvtpd2ps',5Ah
2677 dw avx_cvtpd2ps_instruction-instruction_handler
2678 db 'vcvtph2ps',13h
2679 dw vcvtph2ps_instruction-instruction_handler
2680 db 'vcvtps2dq',5Bh
2681 dw avx_single_source_pd_instruction-instruction_handler
2682 db 'vcvtps2pd',5Ah
2683 dw avx_cvtps2pd_instruction-instruction_handler
2684 db 'vcvtps2ph',1Dh
2685 dw vcvtps2ph_instruction-instruction_handler
2686 db 'vcvtsd2si',2Dh
2687 dw avx_cvtsd2si_instruction-instruction_handler
2688 db 'vcvtsd2ss',5Ah
2689 dw avx_sd_instruction-instruction_handler
2690 db 'vcvtsi2sd',2Ah
2691 dw avx_cvtsi2sd_instruction-instruction_handler
2692 db 'vcvtsi2ss',2Ah
2693 dw avx_cvtsi2ss_instruction-instruction_handler
2694 db 'vcvtss2sd',5Ah
2695 dw avx_ss_instruction-instruction_handler
2696 db 'vcvtss2si',2Dh
2697 dw avx_cvtss2si_instruction-instruction_handler
2698 db 'vfnmaddpd',79h
2699 dw fma4_instruction_p-instruction_handler
2700 db 'vfnmaddps',78h
2701 dw fma4_instruction_p-instruction_handler
2702 db 'vfnmaddsd',7Bh
2703 dw fma4_instruction_sd-instruction_handler
2704 db 'vfnmaddss',7Ah
2705 dw fma4_instruction_ss-instruction_handler
2706 db 'vfnmsubpd',7Dh
2707 dw fma4_instruction_p-instruction_handler
2708 db 'vfnmsubps',7Ch
2709 dw fma4_instruction_p-instruction_handler
2710 db 'vfnmsubsd',7Fh
2711 dw fma4_instruction_sd-instruction_handler
2712 db 'vfnmsubss',7Eh
2713 dw fma4_instruction_ss-instruction_handler
2714 db 'vinsertps',0
2715 dw avx_insertps_instruction-instruction_handler
2716 db 'vmovmskpd',0
2717 dw avx_movmskpd_instruction-instruction_handler
2718 db 'vmovmskps',0
2719 dw avx_movmskps_instruction-instruction_handler
2720 db 'vmovntdqa',2Ah
2721 dw avx_movntdqa_instruction-instruction_handler
2722 db 'vmovshdup',16h
2723 dw avx_movshdup_instruction-instruction_handler
2724 db 'vmovsldup',12h
2725 dw avx_movshdup_instruction-instruction_handler
2726 db 'vpackssdw',6Bh
2727 dw avx_pd_instruction-instruction_handler
2728 db 'vpacksswb',63h
2729 dw avx_pd_instruction-instruction_handler
2730 db 'vpackusdw',2Bh
2731 dw avx_instruction_38-instruction_handler
2732 db 'vpackuswb',67h
2733 dw avx_pd_instruction-instruction_handler
2734 db 'vpblendvb',4Ch
2735 dw avx_triple_source_instruction_3a-instruction_handler
2736 db 'vpcomequb',4
2737 dw xop_pcom_ub_instruction-instruction_handler
2738 db 'vpcomequd',4
2739 dw xop_pcom_ud_instruction-instruction_handler
2740 db 'vpcomequq',4
2741 dw xop_pcom_uq_instruction-instruction_handler
2742 db 'vpcomequw',4
2743 dw xop_pcom_uw_instruction-instruction_handler
2744 db 'vpcomgeub',3
2745 dw xop_pcom_ub_instruction-instruction_handler
2746 db 'vpcomgeud',3
2747 dw xop_pcom_ud_instruction-instruction_handler
2748 db 'vpcomgeuq',3
2749 dw xop_pcom_uq_instruction-instruction_handler
2750 db 'vpcomgeuw',3
2751 dw xop_pcom_uw_instruction-instruction_handler
2752 db 'vpcomgtub',2
2753 dw xop_pcom_ub_instruction-instruction_handler
2754 db 'vpcomgtud',2
2755 dw xop_pcom_ud_instruction-instruction_handler
2756 db 'vpcomgtuq',2
2757 dw xop_pcom_uq_instruction-instruction_handler
2758 db 'vpcomgtuw',2
2759 dw xop_pcom_uw_instruction-instruction_handler
2760 db 'vpcomleub',1
2761 dw xop_pcom_ub_instruction-instruction_handler
2762 db 'vpcomleud',1
2763 dw xop_pcom_ud_instruction-instruction_handler
2764 db 'vpcomleuq',1
2765 dw xop_pcom_uq_instruction-instruction_handler
2766 db 'vpcomleuw',1
2767 dw xop_pcom_uw_instruction-instruction_handler
2768 db 'vpcomltub',0
2769 dw xop_pcom_ub_instruction-instruction_handler
2770 db 'vpcomltud',0
2771 dw xop_pcom_ud_instruction-instruction_handler
2772 db 'vpcomltuq',0
2773 dw xop_pcom_uq_instruction-instruction_handler
2774 db 'vpcomltuw',0
2775 dw xop_pcom_uw_instruction-instruction_handler
2776 db 'vpcomneqb',5
2777 dw xop_pcom_b_instruction-instruction_handler
2778 db 'vpcomneqd',5
2779 dw xop_pcom_d_instruction-instruction_handler
2780 db 'vpcomneqq',5
2781 dw xop_pcom_q_instruction-instruction_handler
2782 db 'vpcomneqw',5
2783 dw xop_pcom_w_instruction-instruction_handler
2784 db 'vpermilpd',5
2785 dw avx_permil_instruction-instruction_handler
2786 db 'vpermilps',4
2787 dw avx_permil_instruction-instruction_handler
2788 db 'vphaddubd',0D2h
2789 dw xop_single_source_128bit_instruction-instruction_handler
2790 db 'vphaddubq',0D3h
2791 dw xop_single_source_128bit_instruction-instruction_handler
2792 db 'vphaddubw',0D1h
2793 dw xop_single_source_128bit_instruction-instruction_handler
2794 db 'vphaddudq',0DBh
2795 dw xop_single_source_128bit_instruction-instruction_handler
2796 db 'vphadduwd',0D6h
2797 dw xop_single_source_128bit_instruction-instruction_handler
2798 db 'vphadduwq',0D7h
2799 dw xop_single_source_128bit_instruction-instruction_handler
2800 db 'vpmacsdqh',9Fh
2801 dw xop_triple_source_128bit_instruction-instruction_handler
2802 db 'vpmacsdql',97h
2803 dw xop_triple_source_128bit_instruction-instruction_handler
2804 db 'vpmacssdd',8Eh
2805 dw xop_triple_source_128bit_instruction-instruction_handler
2806 db 'vpmacsswd',86h
2807 dw xop_triple_source_128bit_instruction-instruction_handler
2808 db 'vpmacssww',85h
2809 dw xop_triple_source_128bit_instruction-instruction_handler
2810 db 'vpmadcswd',0B6h
2811 dw xop_triple_source_128bit_instruction-instruction_handler
2812 db 'vpmovmskb',0D7h
2813 dw avx_pmovmskb_instruction-instruction_handler
2814 db 'vpmovsxbd',21h
2815 dw avx_pmovsxbd_instruction-instruction_handler
2816 db 'vpmovsxbq',22h
2817 dw avx_pmovsxbq_instruction-instruction_handler
2818 db 'vpmovsxbw',20h
2819 dw avx_pmovsxbw_instruction-instruction_handler
2820 db 'vpmovsxdq',25h
2821 dw avx_pmovsxdq_instruction-instruction_handler
2822 db 'vpmovsxwd',23h
2823 dw avx_pmovsxwd_instruction-instruction_handler
2824 db 'vpmovsxwq',24h
2825 dw avx_pmovsxwq_instruction-instruction_handler
2826 db 'vpmovzxbd',31h
2827 dw avx_pmovsxbd_instruction-instruction_handler
2828 db 'vpmovzxbq',32h
2829 dw avx_pmovsxbq_instruction-instruction_handler
2830 db 'vpmovzxbw',30h
2831 dw avx_pmovsxbw_instruction-instruction_handler
2832 db 'vpmovzxdq',35h
2833 dw avx_pmovsxdq_instruction-instruction_handler
2834 db 'vpmovzxwd',33h
2835 dw avx_pmovsxwd_instruction-instruction_handler
2836 db 'vpmovzxwq',34h
2837 dw avx_pmovsxwq_instruction-instruction_handler
2838 db 'vpmulhrsw',0Bh
2839 dw avx_instruction_38-instruction_handler
2840 db 'vunpckhpd',15h
2841 dw avx_pd_instruction-instruction_handler
2842 db 'vunpckhps',15h
2843 dw avx_ps_instruction-instruction_handler
2844 db 'vunpcklpd',14h
2845 dw avx_pd_instruction-instruction_handler
2846 db 'vunpcklps',14h
2847 dw avx_ps_instruction-instruction_handler
2848 instructions_10:
2849 db 'aesdeclast',0DFh
2850 dw sse4_instruction_38-instruction_handler
2851 db 'aesenclast',0DDh
2852 dw sse4_instruction_38-instruction_handler
2853 db 'cmpunordpd',3
2854 dw cmp_pd_instruction-instruction_handler
2855 db 'cmpunordps',3
2856 dw cmp_ps_instruction-instruction_handler
2857 db 'cmpunordsd',3
2858 dw cmp_sd_instruction-instruction_handler
2859 db 'cmpunordss',3
2860 dw cmp_ss_instruction-instruction_handler
2861 db 'cmpxchg16b',16
2862 dw cmpxchgx_instruction-instruction_handler
2863 db 'loadall286',5
2864 dw simple_extended_instruction-instruction_handler
2865 db 'loadall386',7
2866 dw simple_extended_instruction-instruction_handler
2867 db 'maskmovdqu',0
2868 dw maskmovdqu_instruction-instruction_handler
2869 db 'phminposuw',41h
2870 dw sse4_instruction_38-instruction_handler
2871 db 'prefetcht0',1
2872 dw prefetch_instruction-instruction_handler
2873 db 'prefetcht1',2
2874 dw prefetch_instruction-instruction_handler
2875 db 'prefetcht2',3
2876 dw prefetch_instruction-instruction_handler
2877 db 'punpckhqdq',6Dh
2878 dw sse_pd_instruction-instruction_handler
2879 db 'punpcklqdq',6Ch
2880 dw sse_pd_instruction-instruction_handler
2881 db 'vcmptruepd',0Fh
2882 dw avx_cmp_pd_instruction-instruction_handler
2883 db 'vcmptrueps',0Fh
2884 dw avx_cmp_ps_instruction-instruction_handler
2885 db 'vcmptruesd',0Fh
2886 dw avx_cmp_sd_instruction-instruction_handler
2887 db 'vcmptruess',0Fh
2888 dw avx_cmp_ss_instruction-instruction_handler
2889 db 'vcvttpd2dq',0E6h
2890 dw avx_cvtpd2ps_instruction-instruction_handler
2891 db 'vcvttps2dq',5Bh
2892 dw avx_cvttps2dq_instruction-instruction_handler
2893 db 'vcvttsd2si',2Ch
2894 dw avx_cvtsd2si_instruction-instruction_handler
2895 db 'vcvttss2si',2Ch
2896 dw avx_cvtss2si_instruction-instruction_handler
2897 db 'vextractps',0
2898 dw avx_extractps_instruction-instruction_handler
2899 db 'vgatherdpd',92h
2900 dw gather_instruction_pd-instruction_handler
2901 db 'vgatherdps',92h
2902 dw gather_instruction_ps-instruction_handler
2903 db 'vgatherqpd',93h
2904 dw gather_instruction_pd-instruction_handler
2905 db 'vgatherqps',93h
2906 dw gather_instruction_ps-instruction_handler
2907 db 'vmaskmovpd',2Dh
2908 dw avx_maskmov_instruction-instruction_handler
2909 db 'vmaskmovps',2Ch
2910 dw avx_maskmov_instruction-instruction_handler
2911 db 'vpclmulqdq',-1
2912 dw avx_pclmulqdq_instruction-instruction_handler
2913 db 'vpcmpestri',61h
2914 dw avx_single_source_128bit_instruction_3a_imm8-instruction_handler
2915 db 'vpcmpestrm',60h
2916 dw avx_single_source_128bit_instruction_3a_imm8-instruction_handler
2917 db 'vpcmpistri',63h
2918 dw avx_single_source_128bit_instruction_3a_imm8-instruction_handler
2919 db 'vpcmpistrm',62h
2920 dw avx_single_source_128bit_instruction_3a_imm8-instruction_handler
2921 db 'vpcomnequb',5
2922 dw xop_pcom_ub_instruction-instruction_handler
2923 db 'vpcomnequd',5
2924 dw xop_pcom_ud_instruction-instruction_handler
2925 db 'vpcomnequq',5
2926 dw xop_pcom_uq_instruction-instruction_handler
2927 db 'vpcomnequw',5
2928 dw xop_pcom_uw_instruction-instruction_handler
2929 db 'vpcomtrueb',7
2930 dw xop_pcom_b_instruction-instruction_handler
2931 db 'vpcomtrued',7
2932 dw xop_pcom_d_instruction-instruction_handler
2933 db 'vpcomtrueq',7
2934 dw xop_pcom_q_instruction-instruction_handler
2935 db 'vpcomtruew',7
2936 dw xop_pcom_w_instruction-instruction_handler
2937 db 'vperm2f128',6
2938 dw avx_perm2f128_instruction-instruction_handler
2939 db 'vperm2i128',46h
2940 dw avx_perm2f128_instruction-instruction_handler
2941 db 'vpermil2pd',49h
2942 dw vpermil2_instruction-instruction_handler
2943 db 'vpermil2ps',48h
2944 dw vpermil2_instruction-instruction_handler
2945 db 'vpgatherdd',90h
2946 dw gather_instruction_ps-instruction_handler
2947 db 'vpgatherdq',90h
2948 dw gather_instruction_pd-instruction_handler
2949 db 'vpgatherqd',91h
2950 dw gather_instruction_ps-instruction_handler
2951 db 'vpgatherqq',91h
2952 dw gather_instruction_pd-instruction_handler
2953 db 'vpmacssdqh',8Fh
2954 dw xop_triple_source_128bit_instruction-instruction_handler
2955 db 'vpmacssdql',87h
2956 dw xop_triple_source_128bit_instruction-instruction_handler
2957 db 'vpmadcsswd',0A6h
2958 dw xop_triple_source_128bit_instruction-instruction_handler
2959 db 'vpmaddubsw',4
2960 dw avx_instruction_38-instruction_handler
2961 db 'vpmaskmovd',8Ch
2962 dw avx_maskmov_instruction-instruction_handler
2963 db 'vpmaskmovq',8Ch
2964 dw avx_maskmov_w1_instruction-instruction_handler
2965 db 'vpunpckhbw',68h
2966 dw avx_pd_instruction-instruction_handler
2967 db 'vpunpckhdq',6Ah
2968 dw avx_pd_instruction-instruction_handler
2969 db 'vpunpckhwd',69h
2970 dw avx_pd_instruction-instruction_handler
2971 db 'vpunpcklbw',60h
2972 dw avx_pd_instruction-instruction_handler
2973 db 'vpunpckldq',62h
2974 dw avx_pd_instruction-instruction_handler
2975 db 'vpunpcklwd',61h
2976 dw avx_pd_instruction-instruction_handler
2977 db 'vzeroupper',77h
2978 dw vzeroupper_instruction-instruction_handler
2979 db 'xsaveopt64',110b
2980 dw fxsave_instruction_64bit-instruction_handler
2981 instructions_11:
2982 db 'pclmulhqhdq',10001b
2983 dw pclmulqdq_instruction-instruction_handler
2984 db 'pclmullqhdq',10000b
2985 dw pclmulqdq_instruction-instruction_handler
2986 db 'prefetchnta',0
2987 dw prefetch_instruction-instruction_handler
2988 db 'vaesdeclast',0DFh
2989 dw avx_128bit_instruction_38-instruction_handler
2990 db 'vaesenclast',0DDh
2991 dw avx_128bit_instruction_38-instruction_handler
2992 db 'vcmpeq_ospd',10h
2993 dw avx_cmp_pd_instruction-instruction_handler
2994 db 'vcmpeq_osps',10h
2995 dw avx_cmp_ps_instruction-instruction_handler
2996 db 'vcmpeq_ossd',10h
2997 dw avx_cmp_sd_instruction-instruction_handler
2998 db 'vcmpeq_osss',10h
2999 dw avx_cmp_ss_instruction-instruction_handler
3000 db 'vcmpeq_uqpd',8
3001 dw avx_cmp_pd_instruction-instruction_handler
3002 db 'vcmpeq_uqps',8
3003 dw avx_cmp_ps_instruction-instruction_handler
3004 db 'vcmpeq_uqsd',8
3005 dw avx_cmp_sd_instruction-instruction_handler
3006 db 'vcmpeq_uqss',8
3007 dw avx_cmp_ss_instruction-instruction_handler
3008 db 'vcmpeq_uspd',18h
3009 dw avx_cmp_pd_instruction-instruction_handler
3010 db 'vcmpeq_usps',18h
3011 dw avx_cmp_ps_instruction-instruction_handler
3012 db 'vcmpeq_ussd',18h
3013 dw avx_cmp_sd_instruction-instruction_handler
3014 db 'vcmpeq_usss',18h
3015 dw avx_cmp_ss_instruction-instruction_handler
3016 db 'vcmpfalsepd',0Bh
3017 dw avx_cmp_pd_instruction-instruction_handler
3018 db 'vcmpfalseps',0Bh
3019 dw avx_cmp_ps_instruction-instruction_handler
3020 db 'vcmpfalsesd',0Bh
3021 dw avx_cmp_sd_instruction-instruction_handler
3022 db 'vcmpfalsess',0Bh
3023 dw avx_cmp_ss_instruction-instruction_handler
3024 db 'vcmpge_oqpd',1Dh
3025 dw avx_cmp_pd_instruction-instruction_handler
3026 db 'vcmpge_oqps',1Dh
3027 dw avx_cmp_ps_instruction-instruction_handler
3028 db 'vcmpge_oqsd',1Dh
3029 dw avx_cmp_sd_instruction-instruction_handler
3030 db 'vcmpge_oqss',1Dh
3031 dw avx_cmp_ss_instruction-instruction_handler
3032 db 'vcmpgt_oqpd',1Eh
3033 dw avx_cmp_pd_instruction-instruction_handler
3034 db 'vcmpgt_oqps',1Eh
3035 dw avx_cmp_ps_instruction-instruction_handler
3036 db 'vcmpgt_oqsd',1Eh
3037 dw avx_cmp_sd_instruction-instruction_handler
3038 db 'vcmpgt_oqss',1Eh
3039 dw avx_cmp_ss_instruction-instruction_handler
3040 db 'vcmple_oqpd',12h
3041 dw avx_cmp_pd_instruction-instruction_handler
3042 db 'vcmple_oqps',12h
3043 dw avx_cmp_ps_instruction-instruction_handler
3044 db 'vcmple_oqsd',12h
3045 dw avx_cmp_sd_instruction-instruction_handler
3046 db 'vcmple_oqss',12h
3047 dw avx_cmp_ss_instruction-instruction_handler
3048 db 'vcmplt_oqpd',11h
3049 dw avx_cmp_pd_instruction-instruction_handler
3050 db 'vcmplt_oqps',11h
3051 dw avx_cmp_ps_instruction-instruction_handler
3052 db 'vcmplt_oqsd',11h
3053 dw avx_cmp_sd_instruction-instruction_handler
3054 db 'vcmplt_oqss',11h
3055 dw avx_cmp_ss_instruction-instruction_handler
3056 db 'vcmpord_spd',17h
3057 dw avx_cmp_pd_instruction-instruction_handler
3058 db 'vcmpord_sps',17h
3059 dw avx_cmp_ps_instruction-instruction_handler
3060 db 'vcmpord_ssd',17h
3061 dw avx_cmp_sd_instruction-instruction_handler
3062 db 'vcmpord_sss',17h
3063 dw avx_cmp_ss_instruction-instruction_handler
3064 db 'vcmpunordpd',3
3065 dw avx_cmp_pd_instruction-instruction_handler
3066 db 'vcmpunordps',3
3067 dw avx_cmp_ps_instruction-instruction_handler
3068 db 'vcmpunordsd',3
3069 dw avx_cmp_sd_instruction-instruction_handler
3070 db 'vcmpunordss',3
3071 dw avx_cmp_ss_instruction-instruction_handler
3072 db 'vfmadd132pd',98h
3073 dw fma_instruction_pd-instruction_handler
3074 db 'vfmadd132ps',98h
3075 dw fma_instruction_ps-instruction_handler
3076 db 'vfmadd132sd',99h
3077 dw fma_instruction_sd-instruction_handler
3078 db 'vfmadd132ss',99h
3079 dw fma_instruction_ss-instruction_handler
3080 db 'vfmadd213pd',0A8h
3081 dw fma_instruction_pd-instruction_handler
3082 db 'vfmadd213ps',0A8h
3083 dw fma_instruction_ps-instruction_handler
3084 db 'vfmadd213sd',0A9h
3085 dw fma_instruction_sd-instruction_handler
3086 db 'vfmadd213ss',0A9h
3087 dw fma_instruction_ss-instruction_handler
3088 db 'vfmadd231pd',0B8h
3089 dw fma_instruction_pd-instruction_handler
3090 db 'vfmadd231ps',0B8h
3091 dw fma_instruction_ps-instruction_handler
3092 db 'vfmadd231sd',0B9h
3093 dw fma_instruction_sd-instruction_handler
3094 db 'vfmadd231ss',0B9h
3095 dw fma_instruction_ss-instruction_handler
3096 db 'vfmaddsubpd',5Dh
3097 dw fma4_instruction_p-instruction_handler
3098 db 'vfmaddsubps',5Ch
3099 dw fma4_instruction_p-instruction_handler
3100 db 'vfmsub132pd',9Ah
3101 dw fma_instruction_pd-instruction_handler
3102 db 'vfmsub132ps',9Ah
3103 dw fma_instruction_ps-instruction_handler
3104 db 'vfmsub132sd',9Bh
3105 dw fma_instruction_sd-instruction_handler
3106 db 'vfmsub132ss',9Bh
3107 dw fma_instruction_ss-instruction_handler
3108 db 'vfmsub213pd',0AAh
3109 dw fma_instruction_pd-instruction_handler
3110 db 'vfmsub213ps',0AAh
3111 dw fma_instruction_ps-instruction_handler
3112 db 'vfmsub213sd',0ABh
3113 dw fma_instruction_sd-instruction_handler
3114 db 'vfmsub213ss',0ABh
3115 dw fma_instruction_ss-instruction_handler
3116 db 'vfmsub231pd',0BAh
3117 dw fma_instruction_pd-instruction_handler
3118 db 'vfmsub231ps',0BAh
3119 dw fma_instruction_ps-instruction_handler
3120 db 'vfmsub231sd',0BBh
3121 dw fma_instruction_sd-instruction_handler
3122 db 'vfmsub231ss',0BBh
3123 dw fma_instruction_ss-instruction_handler
3124 db 'vfmsubaddpd',5Fh
3125 dw fma4_instruction_p-instruction_handler
3126 db 'vfmsubaddps',5Eh
3127 dw fma4_instruction_p-instruction_handler
3128 db 'vinsertf128',18h
3129 dw avx_insertf128_instruction-instruction_handler
3130 db 'vinserti128',38h
3131 dw avx_insertf128_instruction-instruction_handler
3132 db 'vmaskmovdqu',0
3133 dw avx_maskmovdqu_instruction-instruction_handler
3134 db 'vpcomfalseb',6
3135 dw xop_pcom_b_instruction-instruction_handler
3136 db 'vpcomfalsed',6
3137 dw xop_pcom_d_instruction-instruction_handler
3138 db 'vpcomfalseq',6
3139 dw xop_pcom_q_instruction-instruction_handler
3140 db 'vpcomfalsew',6
3141 dw xop_pcom_w_instruction-instruction_handler
3142 db 'vpcomtrueub',7
3143 dw xop_pcom_ub_instruction-instruction_handler
3144 db 'vpcomtrueud',7
3145 dw xop_pcom_ud_instruction-instruction_handler
3146 db 'vpcomtrueuq',7
3147 dw xop_pcom_uq_instruction-instruction_handler
3148 db 'vpcomtrueuw',7
3149 dw xop_pcom_uw_instruction-instruction_handler
3150 db 'vphminposuw',41h
3151 dw avx_single_source_instruction_38-instruction_handler
3152 db 'vpunpckhqdq',6Dh
3153 dw avx_pd_instruction-instruction_handler
3154 db 'vpunpcklqdq',6Ch
3155 dw avx_pd_instruction-instruction_handler
3156 instructions_12:
3157 db 'pclmulhqhqdq',10001b
3158 dw pclmulqdq_instruction-instruction_handler
3159 db 'pclmulhqlqdq',1
3160 dw pclmulqdq_instruction-instruction_handler
3161 db 'pclmullqhqdq',10000b
3162 dw pclmulqdq_instruction-instruction_handler
3163 db 'pclmullqlqdq',0
3164 dw pclmulqdq_instruction-instruction_handler
3165 db 'vbroadcastsd',19h
3166 dw avx_broadcastsd_instruction-instruction_handler
3167 db 'vbroadcastss',18h
3168 dw avx_broadcastss_instruction-instruction_handler
3169 db 'vcmpneq_oqpd',0Ch
3170 dw avx_cmp_pd_instruction-instruction_handler
3171 db 'vcmpneq_oqps',0Ch
3172 dw avx_cmp_ps_instruction-instruction_handler
3173 db 'vcmpneq_oqsd',0Ch
3174 dw avx_cmp_sd_instruction-instruction_handler
3175 db 'vcmpneq_oqss',0Ch
3176 dw avx_cmp_ss_instruction-instruction_handler
3177 db 'vcmpneq_ospd',1Ch
3178 dw avx_cmp_pd_instruction-instruction_handler
3179 db 'vcmpneq_osps',1Ch
3180 dw avx_cmp_ps_instruction-instruction_handler
3181 db 'vcmpneq_ossd',1Ch
3182 dw avx_cmp_sd_instruction-instruction_handler
3183 db 'vcmpneq_osss',1Ch
3184 dw avx_cmp_ss_instruction-instruction_handler
3185 db 'vcmpneq_uspd',14h
3186 dw avx_cmp_pd_instruction-instruction_handler
3187 db 'vcmpneq_usps',14h
3188 dw avx_cmp_ps_instruction-instruction_handler
3189 db 'vcmpneq_ussd',14h
3190 dw avx_cmp_sd_instruction-instruction_handler
3191 db 'vcmpneq_usss',14h
3192 dw avx_cmp_ss_instruction-instruction_handler
3193 db 'vcmpnge_uqpd',19h
3194 dw avx_cmp_pd_instruction-instruction_handler
3195 db 'vcmpnge_uqps',19h
3196 dw avx_cmp_ps_instruction-instruction_handler
3197 db 'vcmpnge_uqsd',19h
3198 dw avx_cmp_sd_instruction-instruction_handler
3199 db 'vcmpnge_uqss',19h
3200 dw avx_cmp_ss_instruction-instruction_handler
3201 db 'vcmpngt_uqpd',1Ah
3202 dw avx_cmp_pd_instruction-instruction_handler
3203 db 'vcmpngt_uqps',1Ah
3204 dw avx_cmp_ps_instruction-instruction_handler
3205 db 'vcmpngt_uqsd',1Ah
3206 dw avx_cmp_sd_instruction-instruction_handler
3207 db 'vcmpngt_uqss',1Ah
3208 dw avx_cmp_ss_instruction-instruction_handler
3209 db 'vcmpnle_uqpd',16h
3210 dw avx_cmp_pd_instruction-instruction_handler
3211 db 'vcmpnle_uqps',16h
3212 dw avx_cmp_ps_instruction-instruction_handler
3213 db 'vcmpnle_uqsd',16h
3214 dw avx_cmp_sd_instruction-instruction_handler
3215 db 'vcmpnle_uqss',16h
3216 dw avx_cmp_ss_instruction-instruction_handler
3217 db 'vcmpnlt_uqpd',15h
3218 dw avx_cmp_pd_instruction-instruction_handler
3219 db 'vcmpnlt_uqps',15h
3220 dw avx_cmp_ps_instruction-instruction_handler
3221 db 'vcmpnlt_uqsd',15h
3222 dw avx_cmp_sd_instruction-instruction_handler
3223 db 'vcmpnlt_uqss',15h
3224 dw avx_cmp_ss_instruction-instruction_handler
3225 db 'vextractf128',19h
3226 dw avx_extractf128_instruction-instruction_handler
3227 db 'vextracti128',39h
3228 dw avx_extractf128_instruction-instruction_handler
3229 db 'vfnmadd132pd',9Ch
3230 dw fma_instruction_pd-instruction_handler
3231 db 'vfnmadd132ps',9Ch
3232 dw fma_instruction_ps-instruction_handler
3233 db 'vfnmadd132sd',9Dh
3234 dw fma_instruction_sd-instruction_handler
3235 db 'vfnmadd132ss',9Dh
3236 dw fma_instruction_ss-instruction_handler
3237 db 'vfnmadd213pd',0ACh
3238 dw fma_instruction_pd-instruction_handler
3239 db 'vfnmadd213ps',0ACh
3240 dw fma_instruction_ps-instruction_handler
3241 db 'vfnmadd213sd',0ADh
3242 dw fma_instruction_sd-instruction_handler
3243 db 'vfnmadd213ss',0ADh
3244 dw fma_instruction_ss-instruction_handler
3245 db 'vfnmadd231pd',0BCh
3246 dw fma_instruction_pd-instruction_handler
3247 db 'vfnmadd231ps',0BCh
3248 dw fma_instruction_ps-instruction_handler
3249 db 'vfnmadd231sd',0BDh
3250 dw fma_instruction_sd-instruction_handler
3251 db 'vfnmadd231ss',0BDh
3252 dw fma_instruction_ss-instruction_handler
3253 db 'vfnmsub132pd',9Eh
3254 dw fma_instruction_pd-instruction_handler
3255 db 'vfnmsub132ps',9Eh
3256 dw fma_instruction_ps-instruction_handler
3257 db 'vfnmsub132sd',9Fh
3258 dw fma_instruction_sd-instruction_handler
3259 db 'vfnmsub132ss',9Fh
3260 dw fma_instruction_ss-instruction_handler
3261 db 'vfnmsub213pd',0AEh
3262 dw fma_instruction_pd-instruction_handler
3263 db 'vfnmsub213ps',0AEh
3264 dw fma_instruction_ps-instruction_handler
3265 db 'vfnmsub213sd',0AFh
3266 dw fma_instruction_sd-instruction_handler
3267 db 'vfnmsub213ss',0AFh
3268 dw fma_instruction_ss-instruction_handler
3269 db 'vfnmsub231pd',0BEh
3270 dw fma_instruction_pd-instruction_handler
3271 db 'vfnmsub231ps',0BEh
3272 dw fma_instruction_ps-instruction_handler
3273 db 'vfnmsub231sd',0BFh
3274 dw fma_instruction_sd-instruction_handler
3275 db 'vfnmsub231ss',0BFh
3276 dw fma_instruction_ss-instruction_handler
3277 db 'vpbroadcastb',78h
3278 dw avx_pbroadcastb_instruction-instruction_handler
3279 db 'vpbroadcastd',58h
3280 dw avx_pbroadcastd_instruction-instruction_handler
3281 db 'vpbroadcastq',59h
3282 dw avx_pbroadcastq_instruction-instruction_handler
3283 db 'vpbroadcastw',79h
3284 dw avx_pbroadcastw_instruction-instruction_handler
3285 db 'vpclmulhqhdq',10001b
3286 dw avx_pclmulqdq_instruction-instruction_handler
3287 db 'vpclmullqhdq',10000b
3288 dw avx_pclmulqdq_instruction-instruction_handler
3289 db 'vpcomfalseub',6
3290 dw xop_pcom_ub_instruction-instruction_handler
3291 db 'vpcomfalseud',6
3292 dw xop_pcom_ud_instruction-instruction_handler
3293 db 'vpcomfalseuq',6
3294 dw xop_pcom_uq_instruction-instruction_handler
3295 db 'vpcomfalseuw',6
3296 dw xop_pcom_uw_instruction-instruction_handler
3297 db 'vpermilmo2pd',10b
3298 dw vpermil_2pd_instruction-instruction_handler
3299 db 'vpermilmo2ps',10b
3300 dw vpermil_2ps_instruction-instruction_handler
3301 db 'vpermilmz2pd',11b
3302 dw vpermil_2pd_instruction-instruction_handler
3303 db 'vpermilmz2ps',11b
3304 dw vpermil_2ps_instruction-instruction_handler
3305 db 'vpermiltd2pd',0
3306 dw vpermil_2pd_instruction-instruction_handler
3307 db 'vpermiltd2ps',0
3308 dw vpermil_2ps_instruction-instruction_handler
3309 instructions_13:
3310 db 'vcmptrue_uspd',1Fh
3311 dw avx_cmp_pd_instruction-instruction_handler
3312 db 'vcmptrue_usps',1Fh
3313 dw avx_cmp_ps_instruction-instruction_handler
3314 db 'vcmptrue_ussd',1Fh
3315 dw avx_cmp_sd_instruction-instruction_handler
3316 db 'vcmptrue_usss',1Fh
3317 dw avx_cmp_ss_instruction-instruction_handler
3318 db 'vcmpunord_spd',13h
3319 dw avx_cmp_pd_instruction-instruction_handler
3320 db 'vcmpunord_sps',13h
3321 dw avx_cmp_ps_instruction-instruction_handler
3322 db 'vcmpunord_ssd',13h
3323 dw avx_cmp_sd_instruction-instruction_handler
3324 db 'vcmpunord_sss',13h
3325 dw avx_cmp_ss_instruction-instruction_handler
3326 db 'vpclmulhqlqdq',1
3327 dw avx_pclmulqdq_instruction-instruction_handler
3328 db 'vpclmullqlqdq',0
3329 dw avx_pclmulqdq_instruction-instruction_handler
3330 instructions_14:
3331 db 'vbroadcastf128',1Ah
3332 dw avx_broadcastf128_instruction-instruction_handler
3333 db 'vbroadcasti128',5Ah
3334 dw avx_broadcastf128_instruction-instruction_handler
3335 db 'vcmpfalse_ospd',1Bh
3336 dw avx_cmp_pd_instruction-instruction_handler
3337 db 'vcmpfalse_osps',1Bh
3338 dw avx_cmp_ps_instruction-instruction_handler
3339 db 'vcmpfalse_ossd',1Bh
3340 dw avx_cmp_sd_instruction-instruction_handler
3341 db 'vcmpfalse_osss',1Bh
3342 dw avx_cmp_ss_instruction-instruction_handler
3343 db 'vfmaddsub132pd',96h
3344 dw fma_instruction_pd-instruction_handler
3345 db 'vfmaddsub132ps',96h
3346 dw fma_instruction_ps-instruction_handler
3347 db 'vfmaddsub213pd',0A6h
3348 dw fma_instruction_pd-instruction_handler
3349 db 'vfmaddsub213ps',0A6h
3350 dw fma_instruction_ps-instruction_handler
3351 db 'vfmaddsub231pd',0B6h
3352 dw fma_instruction_pd-instruction_handler
3353 db 'vfmaddsub231ps',0B6h
3354 dw fma_instruction_ps-instruction_handler
3355 db 'vfmsubadd132pd',97h
3356 dw fma_instruction_pd-instruction_handler
3357 db 'vfmsubadd132ps',97h
3358 dw fma_instruction_ps-instruction_handler
3359 db 'vfmsubadd213pd',0A7h
3360 dw fma_instruction_pd-instruction_handler
3361 db 'vfmsubadd213ps',0A7h
3362 dw fma_instruction_ps-instruction_handler
3363 db 'vfmsubadd231pd',0B7h
3364 dw fma_instruction_pd-instruction_handler
3365 db 'vfmsubadd231ps',0B7h
3366 dw fma_instruction_ps-instruction_handler
3367 instructions_15:
3368 db 'aeskeygenassist',0DFh
3369 dw sse4_instruction_3a_imm8-instruction_handler
3370 instructions_16:
3371 db 'vaeskeygenassist',0DFh
3372 dw avx_single_source_128bit_instruction_3a_imm8-instruction_handler
3373 instructions_end:
3374
3375 data_directives:
3376 dw data_directives_2-data_directives,(data_directives_3-data_directives_2)/(2+3)
3377 dw data_directives_3-data_directives,(data_directives_4-data_directives_3)/(3+3)
3378 dw data_directives_4-data_directives,(data_directives_end-data_directives_4)/(4+3)
3379
3380 data_directives_2:
3381 db 'db',1
3382 dw data_bytes-instruction_handler
3383 db 'dd',4
3384 dw data_dwords-instruction_handler
3385 db 'df',6
3386 dw data_pwords-instruction_handler
3387 db 'dp',6
3388 dw data_pwords-instruction_handler
3389 db 'dq',8
3390 dw data_qwords-instruction_handler
3391 db 'dt',10
3392 dw data_twords-instruction_handler
3393 db 'du',2
3394 dw data_unicode-instruction_handler
3395 db 'dw',2
3396 dw data_words-instruction_handler
3397 db 'rb',1
3398 dw reserve_bytes-instruction_handler
3399 db 'rd',4
3400 dw reserve_dwords-instruction_handler
3401 db 'rf',6
3402 dw reserve_pwords-instruction_handler
3403 db 'rp',6
3404 dw reserve_pwords-instruction_handler
3405 db 'rq',8
3406 dw reserve_qwords-instruction_handler
3407 db 'rt',10
3408 dw reserve_twords-instruction_handler
3409 db 'rw',2
3410 dw reserve_words-instruction_handler
3411 data_directives_3:
3412 data_directives_4:
3413 db 'file',1
3414 dw data_file-instruction_handler
3415 data_directives_end:
0
1 ; flat assembler core variables
2 ; Copyright (c) 1999-2014, Tomasz Grysztar.
3 ; All rights reserved.
4
5 ; Variables which have to be set up by interface:
6
7 memory_start dd ?
8 memory_end dd ?
9
10 additional_memory dd ?
11 additional_memory_end dd ?
12
13 stack_limit dd ?
14
15 input_file dd ?
16 output_file dd ?
17 symbols_file dd ?
18
19 passes_limit dw ?
20
21 ; Internal core variables:
22
23 current_pass dw ?
24
25 include_paths dd ?
26 free_additional_memory dd ?
27 source_start dd ?
28 code_start dd ?
29 code_size dd ?
30 real_code_size dd ?
31 written_size dd ?
32 headers_size dd ?
33
34 current_line dd ?
35 macro_line dd ?
36 macro_block dd ?
37 macro_block_line dd ?
38 macro_block_line_number dd ?
39 macro_symbols dd ?
40 struc_name dd ?
41 struc_label dd ?
42 instant_macro_start dd ?
43 parameters_end dd ?
44 locals_counter rb 8
45 current_locals_prefix dd ?
46 anonymous_reverse dd ?
47 anonymous_forward dd ?
48 labels_list dd ?
49 label_hash dd ?
50 label_leaf dd ?
51 hash_tree dd ?
52 addressing_space dd ?
53 undefined_data_start dd ?
54 undefined_data_end dd ?
55 counter dd ?
56 counter_limit dd ?
57 error_info dd ?
58 error_line dd ?
59 error dd ?
60 tagged_blocks dd ?
61 structures_buffer dd ?
62 number_start dd ?
63 current_offset dd ?
64 value dq ?
65 fp_value rd 8
66 adjustment dq ?
67 symbol_identifier dd ?
68 address_symbol dd ?
69 address_high dd ?
70 format_flags dd ?
71 resolver_flags dd ?
72 symbols_stream dd ?
73 number_of_relocations dd ?
74 number_of_sections dd ?
75 stub_size dd ?
76 stub_file dd ?
77 current_section dd ?
78 machine dw ?
79 subsystem dw ?
80 subsystem_version dd ?
81 image_base dd ?
82 image_base_high dd ?
83 resource_data dd ?
84 resource_size dd ?
85 actual_fixups_size dd ?
86 reserved_fixups dd ?
87 reserved_fixups_size dd ?
88 last_fixup_base dd ?
89 last_fixup_header dd ?
90 parenthesis_stack dd ?
91 blocks_stack dd ?
92 parsed_lines dd ?
93 logical_value_parentheses dd ?
94 file_extension dd ?
95
96 operand_size db ?
97 size_override db ?
98 operand_prefix db ?
99 opcode_prefix db ?
100 rex_prefix db ?
101 vex_required db ?
102 vex_register db ?
103 immediate_size db ?
104
105 base_code db ?
106 extended_code db ?
107 supplemental_code db ?
108 postbyte_register db ?
109 segment_register db ?
110 xop_opcode_map db ?
111
112 mmx_size db ?
113 jump_type db ?
114 push_size db ?
115 value_size db ?
116 address_size db ?
117 label_size db ?
118 size_declared db ?
119
120 value_undefined db ?
121 value_constant db ?
122 value_type db ?
123 value_sign db ?
124 fp_sign db ?
125 fp_format db ?
126 address_sign db ?
127 compare_type db ?
128 logical_value_wrapping db ?
129 next_pass_needed db ?
130 output_format db ?
131 code_type db ?
132 adjustment_sign db ?
133
134 macro_status db ?
135 default_argument_value db ?
136 prefixed_instruction db ?
137 formatter_symbols_allowed db ?
138 free_address_range db ?
139
140
141 characters rb 100h
142 converted rb 100h
143 message rb 200h
0
1 ; flat assembler version 1.71
2 ; Copyright (c) 1999-2014, Tomasz Grysztar.
3 ; All rights reserved.
4 ;
5 ; This programs is free for commercial and non-commercial use as long as
6 ; the following conditions are adhered to.
7 ;
8 ; Redistribution and use in source and binary forms, with or without
9 ; modification, are permitted provided that the following conditions are
10 ; met:
11 ;
12 ; 1. Redistributions of source code must retain the above copyright notice,
13 ; this list of conditions and the following disclaimer.
14 ; 2. Redistributions in binary form must reproduce the above copyright
15 ; notice, this list of conditions and the following disclaimer in the
16 ; documentation and/or other materials provided with the distribution.
17 ;
18 ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 ; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 ; TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
21 ; PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
22 ; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 ; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 ; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 ; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 ; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 ; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 ;
30 ; The licence and distribution terms for any publically available
31 ; version or derivative of this code cannot be changed. i.e. this code
32 ; cannot simply be copied and put under another distribution licence
33 ; (including the GNU Public Licence).
34
35 VERSION_STRING equ "1.71.22"
36
37 VERSION_MAJOR = 1
38 VERSION_MINOR = 71
0
1 ; flat assembler core
2 ; Copyright (c) 1999-2014, Tomasz Grysztar.
3 ; All rights reserved.
4
5 simple_instruction_except64:
6 cmp [code_type],64
7 je illegal_instruction
8 simple_instruction:
9 stos byte [edi]
10 jmp instruction_assembled
11 simple_instruction_only64:
12 cmp [code_type],64
13 jne illegal_instruction
14 jmp simple_instruction
15 simple_instruction_16bit_except64:
16 cmp [code_type],64
17 je illegal_instruction
18 simple_instruction_16bit:
19 cmp [code_type],16
20 jne size_prefix
21 stos byte [edi]
22 jmp instruction_assembled
23 size_prefix:
24 mov ah,al
25 mov al,66h
26 stos word [edi]
27 jmp instruction_assembled
28 simple_instruction_32bit_except64:
29 cmp [code_type],64
30 je illegal_instruction
31 simple_instruction_32bit:
32 cmp [code_type],16
33 je size_prefix
34 stos byte [edi]
35 jmp instruction_assembled
36 iret_instruction:
37 cmp [code_type],64
38 jne simple_instruction
39 simple_instruction_64bit:
40 cmp [code_type],64
41 jne illegal_instruction
42 mov ah,al
43 mov al,48h
44 stos word [edi]
45 jmp instruction_assembled
46 simple_extended_instruction_64bit:
47 cmp [code_type],64
48 jne illegal_instruction
49 mov byte [edi],48h
50 inc edi
51 simple_extended_instruction:
52 mov ah,al
53 mov al,0Fh
54 stos word [edi]
55 jmp instruction_assembled
56 prefix_instruction:
57 stos byte [edi]
58 or [prefixed_instruction],-1
59 jmp continue_line
60 segment_prefix:
61 mov ah,al
62 shr ah,4
63 cmp ah,6
64 jne illegal_instruction
65 and al,1111b
66 mov [segment_register],al
67 call store_segment_prefix
68 or [prefixed_instruction],-1
69 jmp continue_line
70 int_instruction:
71 lods byte [esi]
72 call get_size_operator
73 cmp ah,1
74 ja invalid_operand_size
75 cmp al,'('
76 jne invalid_operand
77 call get_byte_value
78 test eax,eax
79 jns int_imm_ok
80 call recoverable_overflow
81 int_imm_ok:
82 mov ah,al
83 mov al,0CDh
84 stos word [edi]
85 jmp instruction_assembled
86 aa_instruction:
87 cmp [code_type],64
88 je illegal_instruction
89 push eax
90 mov bl,10
91 cmp byte [esi],'('
92 jne aa_store
93 inc esi
94 xor al,al
95 xchg al,[operand_size]
96 cmp al,1
97 ja invalid_operand_size
98 call get_byte_value
99 mov bl,al
100 aa_store:
101 cmp [operand_size],0
102 jne invalid_operand
103 pop eax
104 mov ah,bl
105 stos word [edi]
106 jmp instruction_assembled
107
108 basic_instruction:
109 mov [base_code],al
110 lods byte [esi]
111 call get_size_operator
112 cmp al,10h
113 je basic_reg
114 cmp al,'['
115 jne invalid_operand
116 basic_mem:
117 call get_address
118 push edx ebx ecx
119 lods byte [esi]
120 cmp al,','
121 jne invalid_operand
122 lods byte [esi]
123 call get_size_operator
124 cmp al,'('
125 je basic_mem_imm
126 cmp al,10h
127 jne invalid_operand
128 basic_mem_reg:
129 lods byte [esi]
130 call convert_register
131 mov [postbyte_register],al
132 pop ecx ebx edx
133 mov al,ah
134 cmp al,1
135 je instruction_ready
136 call operand_autodetect
137 inc [base_code]
138 instruction_ready:
139 call store_instruction
140 jmp instruction_assembled
141 basic_mem_imm:
142 mov al,[operand_size]
143 cmp al,1
144 jb basic_mem_imm_nosize
145 je basic_mem_imm_8bit
146 cmp al,2
147 je basic_mem_imm_16bit
148 cmp al,4
149 je basic_mem_imm_32bit
150 cmp al,8
151 jne invalid_operand_size
152 basic_mem_imm_64bit:
153 cmp [size_declared],0
154 jne long_immediate_not_encodable
155 call operand_64bit
156 call get_simm32
157 cmp [value_type],4
158 jae long_immediate_not_encodable
159 jmp basic_mem_imm_32bit_ok
160 basic_mem_imm_nosize:
161 call recoverable_unknown_size
162 basic_mem_imm_8bit:
163 call get_byte_value
164 mov byte [value],al
165 mov al,[base_code]
166 shr al,3
167 mov [postbyte_register],al
168 pop ecx ebx edx
169 mov [base_code],80h
170 call store_instruction_with_imm8
171 jmp instruction_assembled
172 basic_mem_imm_16bit:
173 call operand_16bit
174 call get_word_value
175 mov word [value],ax
176 mov al,[base_code]
177 shr al,3
178 mov [postbyte_register],al
179 pop ecx ebx edx
180 cmp [value_type],0
181 jne basic_mem_imm_16bit_store
182 cmp [size_declared],0
183 jne basic_mem_imm_16bit_store
184 cmp word [value],80h
185 jb basic_mem_simm_8bit
186 cmp word [value],-80h
187 jae basic_mem_simm_8bit
188 basic_mem_imm_16bit_store:
189 mov [base_code],81h
190 call store_instruction_with_imm16
191 jmp instruction_assembled
192 basic_mem_simm_8bit:
193 mov [base_code],83h
194 call store_instruction_with_imm8
195 jmp instruction_assembled
196 basic_mem_imm_32bit:
197 call operand_32bit
198 call get_dword_value
199 basic_mem_imm_32bit_ok:
200 mov dword [value],eax
201 mov al,[base_code]
202 shr al,3
203 mov [postbyte_register],al
204 pop ecx ebx edx
205 cmp [value_type],0
206 jne basic_mem_imm_32bit_store
207 cmp [size_declared],0
208 jne basic_mem_imm_32bit_store
209 cmp dword [value],80h
210 jb basic_mem_simm_8bit
211 cmp dword [value],-80h
212 jae basic_mem_simm_8bit
213 basic_mem_imm_32bit_store:
214 mov [base_code],81h
215 call store_instruction_with_imm32
216 jmp instruction_assembled
217 get_simm32:
218 call get_qword_value
219 mov ecx,edx
220 cdq
221 cmp ecx,edx
222 jne value_out_of_range
223 cmp [value_type],4
224 jne get_simm32_ok
225 mov [value_type],2
226 get_simm32_ok:
227 ret
228 basic_reg:
229 lods byte [esi]
230 call convert_register
231 mov [postbyte_register],al
232 lods byte [esi]
233 cmp al,','
234 jne invalid_operand
235 lods byte [esi]
236 call get_size_operator
237 cmp al,10h
238 je basic_reg_reg
239 cmp al,'('
240 je basic_reg_imm
241 cmp al,'['
242 jne invalid_operand
243 basic_reg_mem:
244 call get_address
245 mov al,[operand_size]
246 cmp al,1
247 je basic_reg_mem_8bit
248 call operand_autodetect
249 add [base_code],3
250 jmp instruction_ready
251 basic_reg_mem_8bit:
252 add [base_code],2
253 jmp instruction_ready
254 basic_reg_reg:
255 lods byte [esi]
256 call convert_register
257 mov bl,[postbyte_register]
258 mov [postbyte_register],al
259 mov al,ah
260 cmp al,1
261 je nomem_instruction_ready
262 call operand_autodetect
263 inc [base_code]
264 nomem_instruction_ready:
265 call store_nomem_instruction
266 jmp instruction_assembled
267 basic_reg_imm:
268 mov al,[operand_size]
269 cmp al,1
270 je basic_reg_imm_8bit
271 cmp al,2
272 je basic_reg_imm_16bit
273 cmp al,4
274 je basic_reg_imm_32bit
275 cmp al,8
276 jne invalid_operand_size
277 basic_reg_imm_64bit:
278 cmp [size_declared],0
279 jne long_immediate_not_encodable
280 call operand_64bit
281 call get_simm32
282 cmp [value_type],4
283 jae long_immediate_not_encodable
284 jmp basic_reg_imm_32bit_ok
285 basic_reg_imm_8bit:
286 call get_byte_value
287 mov dl,al
288 mov bl,[base_code]
289 shr bl,3
290 xchg bl,[postbyte_register]
291 or bl,bl
292 jz basic_al_imm
293 mov [base_code],80h
294 call store_nomem_instruction
295 mov al,dl
296 stos byte [edi]
297 jmp instruction_assembled
298 basic_al_imm:
299 mov al,[base_code]
300 add al,4
301 stos byte [edi]
302 mov al,dl
303 stos byte [edi]
304 jmp instruction_assembled
305 basic_reg_imm_16bit:
306 call operand_16bit
307 call get_word_value
308 mov dx,ax
309 mov bl,[base_code]
310 shr bl,3
311 xchg bl,[postbyte_register]
312 cmp [value_type],0
313 jne basic_reg_imm_16bit_store
314 cmp [size_declared],0
315 jne basic_reg_imm_16bit_store
316 cmp dx,80h
317 jb basic_reg_simm_8bit
318 cmp dx,-80h
319 jae basic_reg_simm_8bit
320 basic_reg_imm_16bit_store:
321 or bl,bl
322 jz basic_ax_imm
323 mov [base_code],81h
324 call store_nomem_instruction
325 basic_store_imm_16bit:
326 mov ax,dx
327 call mark_relocation
328 stos word [edi]
329 jmp instruction_assembled
330 basic_reg_simm_8bit:
331 mov [base_code],83h
332 call store_nomem_instruction
333 mov al,dl
334 stos byte [edi]
335 jmp instruction_assembled
336 basic_ax_imm:
337 add [base_code],5
338 call store_instruction_code
339 jmp basic_store_imm_16bit
340 basic_reg_imm_32bit:
341 call operand_32bit
342 call get_dword_value
343 basic_reg_imm_32bit_ok:
344 mov edx,eax
345 mov bl,[base_code]
346 shr bl,3
347 xchg bl,[postbyte_register]
348 cmp [value_type],0
349 jne basic_reg_imm_32bit_store
350 cmp [size_declared],0
351 jne basic_reg_imm_32bit_store
352 cmp edx,80h
353 jb basic_reg_simm_8bit
354 cmp edx,-80h
355 jae basic_reg_simm_8bit
356 basic_reg_imm_32bit_store:
357 or bl,bl
358 jz basic_eax_imm
359 mov [base_code],81h
360 call store_nomem_instruction
361 basic_store_imm_32bit:
362 mov eax,edx
363 call mark_relocation
364 stos dword [edi]
365 jmp instruction_assembled
366 basic_eax_imm:
367 add [base_code],5
368 call store_instruction_code
369 jmp basic_store_imm_32bit
370 recoverable_unknown_size:
371 cmp [error_line],0
372 jne ignore_unknown_size
373 push [current_line]
374 pop [error_line]
375 mov [error],operand_size_not_specified
376 ignore_unknown_size:
377 ret
378 single_operand_instruction:
379 mov [base_code],0F6h
380 mov [postbyte_register],al
381 lods byte [esi]
382 call get_size_operator
383 cmp al,10h
384 je single_reg
385 cmp al,'['
386 jne invalid_operand
387 single_mem:
388 call get_address
389 mov al,[operand_size]
390 cmp al,1
391 je single_mem_8bit
392 jb single_mem_nosize
393 call operand_autodetect
394 inc [base_code]
395 jmp instruction_ready
396 single_mem_nosize:
397 call recoverable_unknown_size
398 single_mem_8bit:
399 jmp instruction_ready
400 single_reg:
401 lods byte [esi]
402 call convert_register
403 mov bl,al
404 mov al,ah
405 cmp al,1
406 je single_reg_8bit
407 call operand_autodetect
408 inc [base_code]
409 single_reg_8bit:
410 jmp nomem_instruction_ready
411 mov_instruction:
412 mov [base_code],88h
413 lods byte [esi]
414 call get_size_operator
415 cmp al,10h
416 je mov_reg
417 cmp al,'['
418 jne invalid_operand
419 mov_mem:
420 call get_address
421 push edx ebx ecx
422 lods byte [esi]
423 cmp al,','
424 jne invalid_operand
425 lods byte [esi]
426 call get_size_operator
427 cmp al,'('
428 je mov_mem_imm
429 cmp al,10h
430 jne invalid_operand
431 mov_mem_reg:
432 lods byte [esi]
433 cmp al,60h
434 jb mov_mem_general_reg
435 cmp al,70h
436 jb mov_mem_sreg
437 mov_mem_general_reg:
438 call convert_register
439 mov [postbyte_register],al
440 pop ecx ebx edx
441 cmp ah,1
442 je mov_mem_reg_8bit
443 mov al,ah
444 call operand_autodetect
445 mov al,[postbyte_register]
446 or al,bl
447 or al,bh
448 jz mov_mem_ax
449 inc [base_code]
450 jmp instruction_ready
451 mov_mem_reg_8bit:
452 or al,bl
453 or al,bh
454 jnz instruction_ready
455 mov_mem_al:
456 test ch,22h
457 jnz mov_mem_address16_al
458 test ch,44h
459 jnz mov_mem_address32_al
460 test ch,88h
461 jnz mov_mem_address64_al
462 or ch,ch
463 jnz invalid_address_size
464 cmp [code_type],64
465 je mov_mem_address64_al
466 cmp [code_type],32
467 je mov_mem_address32_al
468 cmp edx,10000h
469 jb mov_mem_address16_al
470 mov_mem_address32_al:
471 call store_segment_prefix_if_necessary
472 call address_32bit_prefix
473 mov [base_code],0A2h
474 store_mov_address32:
475 call store_instruction_code
476 call store_address_32bit_value
477 jmp instruction_assembled
478 mov_mem_address16_al:
479 call store_segment_prefix_if_necessary
480 call address_16bit_prefix
481 mov [base_code],0A2h
482 store_mov_address16:
483 cmp [code_type],64
484 je invalid_address
485 call store_instruction_code
486 mov eax,edx
487 stos word [edi]
488 cmp edx,10000h
489 jge value_out_of_range
490 jmp instruction_assembled
491 mov_mem_address64_al:
492 call store_segment_prefix_if_necessary
493 mov [base_code],0A2h
494 store_mov_address64:
495 call store_instruction_code
496 call store_address_64bit_value
497 jmp instruction_assembled
498 mov_mem_ax:
499 test ch,22h
500 jnz mov_mem_address16_ax
501 test ch,44h
502 jnz mov_mem_address32_ax
503 test ch,88h
504 jnz mov_mem_address64_ax
505 or ch,ch
506 jnz invalid_address_size
507 cmp [code_type],64
508 je mov_mem_address64_ax
509 cmp [code_type],32
510 je mov_mem_address32_ax
511 cmp edx,10000h
512 jb mov_mem_address16_ax
513 mov_mem_address32_ax:
514 call store_segment_prefix_if_necessary
515 call address_32bit_prefix
516 mov [base_code],0A3h
517 jmp store_mov_address32
518 mov_mem_address16_ax:
519 call store_segment_prefix_if_necessary
520 call address_16bit_prefix
521 mov [base_code],0A3h
522 jmp store_mov_address16
523 mov_mem_address64_ax:
524 call store_segment_prefix_if_necessary
525 mov [base_code],0A3h
526 jmp store_mov_address64
527 mov_mem_sreg:
528 sub al,61h
529 mov [postbyte_register],al
530 pop ecx ebx edx
531 mov ah,[operand_size]
532 or ah,ah
533 jz mov_mem_sreg_store
534 cmp ah,2
535 jne invalid_operand_size
536 mov_mem_sreg_store:
537 mov [base_code],8Ch
538 jmp instruction_ready
539 mov_mem_imm:
540 mov al,[operand_size]
541 cmp al,1
542 jb mov_mem_imm_nosize
543 je mov_mem_imm_8bit
544 cmp al,2
545 je mov_mem_imm_16bit
546 cmp al,4
547 je mov_mem_imm_32bit
548 cmp al,8
549 jne invalid_operand_size
550 mov_mem_imm_64bit:
551 cmp [size_declared],0
552 jne long_immediate_not_encodable
553 call operand_64bit
554 call get_simm32
555 cmp [value_type],4
556 jae long_immediate_not_encodable
557 jmp mov_mem_imm_32bit_store
558 mov_mem_imm_8bit:
559 call get_byte_value
560 mov byte [value],al
561 mov [postbyte_register],0
562 mov [base_code],0C6h
563 pop ecx ebx edx
564 call store_instruction_with_imm8
565 jmp instruction_assembled
566 mov_mem_imm_16bit:
567 call operand_16bit
568 call get_word_value
569 mov word [value],ax
570 mov [postbyte_register],0
571 mov [base_code],0C7h
572 pop ecx ebx edx
573 call store_instruction_with_imm16
574 jmp instruction_assembled
575 mov_mem_imm_nosize:
576 call recoverable_unknown_size
577 mov_mem_imm_32bit:
578 call operand_32bit
579 call get_dword_value
580 mov_mem_imm_32bit_store:
581 mov dword [value],eax
582 mov [postbyte_register],0
583 mov [base_code],0C7h
584 pop ecx ebx edx
585 call store_instruction_with_imm32
586 jmp instruction_assembled
587 mov_reg:
588 lods byte [esi]
589 mov ah,al
590 sub ah,10h
591 and ah,al
592 test ah,0F0h
593 jnz mov_sreg
594 call convert_register
595 mov [postbyte_register],al
596 lods byte [esi]
597 cmp al,','
598 jne invalid_operand
599 lods byte [esi]
600 call get_size_operator
601 cmp al,'['
602 je mov_reg_mem
603 cmp al,'('
604 je mov_reg_imm
605 cmp al,10h
606 jne invalid_operand
607 mov_reg_reg:
608 lods byte [esi]
609 mov ah,al
610 sub ah,10h
611 and ah,al
612 test ah,0F0h
613 jnz mov_reg_sreg
614 call convert_register
615 mov bl,[postbyte_register]
616 mov [postbyte_register],al
617 mov al,ah
618 cmp al,1
619 je mov_reg_reg_8bit
620 call operand_autodetect
621 inc [base_code]
622 mov_reg_reg_8bit:
623 jmp nomem_instruction_ready
624 mov_reg_sreg:
625 mov bl,[postbyte_register]
626 mov ah,al
627 and al,1111b
628 mov [postbyte_register],al
629 shr ah,4
630 cmp ah,5
631 je mov_reg_creg
632 cmp ah,7
633 je mov_reg_dreg
634 ja mov_reg_treg
635 dec [postbyte_register]
636 cmp [operand_size],8
637 je mov_reg_sreg64
638 cmp [operand_size],4
639 je mov_reg_sreg32
640 cmp [operand_size],2
641 jne invalid_operand_size
642 call operand_16bit
643 jmp mov_reg_sreg_store
644 mov_reg_sreg64:
645 call operand_64bit
646 jmp mov_reg_sreg_store
647 mov_reg_sreg32:
648 call operand_32bit
649 mov_reg_sreg_store:
650 mov [base_code],8Ch
651 jmp nomem_instruction_ready
652 mov_reg_treg:
653 cmp ah,9
654 jne invalid_operand
655 mov [extended_code],24h
656 jmp mov_reg_xrx
657 mov_reg_dreg:
658 mov [extended_code],21h
659 jmp mov_reg_xrx
660 mov_reg_creg:
661 mov [extended_code],20h
662 mov_reg_xrx:
663 mov [base_code],0Fh
664 cmp [code_type],64
665 je mov_reg_xrx_64bit
666 cmp [operand_size],4
667 jne invalid_operand_size
668 cmp [postbyte_register],8
669 jne mov_reg_xrx_store
670 cmp [extended_code],20h
671 jne mov_reg_xrx_store
672 mov al,0F0h
673 stos byte [edi]
674 mov [postbyte_register],0
675 mov_reg_xrx_store:
676 jmp nomem_instruction_ready
677 mov_reg_xrx_64bit:
678 cmp [operand_size],8
679 jne invalid_operand_size
680 jmp nomem_instruction_ready
681 mov_reg_mem:
682 call get_address
683 mov al,[operand_size]
684 cmp al,1
685 je mov_reg_mem_8bit
686 call operand_autodetect
687 mov al,[postbyte_register]
688 or al,bl
689 or al,bh
690 jz mov_ax_mem
691 add [base_code],3
692 jmp instruction_ready
693 mov_reg_mem_8bit:
694 mov al,[postbyte_register]
695 or al,bl
696 or al,bh
697 jz mov_al_mem
698 add [base_code],2
699 jmp instruction_ready
700 mov_al_mem:
701 test ch,22h
702 jnz mov_al_mem_address16
703 test ch,44h
704 jnz mov_al_mem_address32
705 test ch,88h
706 jnz mov_al_mem_address64
707 or ch,ch
708 jnz invalid_address_size
709 cmp [code_type],64
710 je mov_al_mem_address64
711 cmp [code_type],32
712 je mov_al_mem_address32
713 cmp edx,10000h
714 jb mov_al_mem_address16
715 mov_al_mem_address32:
716 call store_segment_prefix_if_necessary
717 call address_32bit_prefix
718 mov [base_code],0A0h
719 jmp store_mov_address32
720 mov_al_mem_address16:
721 call store_segment_prefix_if_necessary
722 call address_16bit_prefix
723 mov [base_code],0A0h
724 jmp store_mov_address16
725 mov_al_mem_address64:
726 call store_segment_prefix_if_necessary
727 mov [base_code],0A0h
728 jmp store_mov_address64
729 mov_ax_mem:
730 test ch,22h
731 jnz mov_ax_mem_address16
732 test ch,44h
733 jnz mov_ax_mem_address32
734 test ch,88h
735 jnz mov_ax_mem_address64
736 or ch,ch
737 jnz invalid_address_size
738 cmp [code_type],64
739 je mov_ax_mem_address64
740 cmp [code_type],32
741 je mov_ax_mem_address32
742 cmp edx,10000h
743 jb mov_ax_mem_address16
744 mov_ax_mem_address32:
745 call store_segment_prefix_if_necessary
746 call address_32bit_prefix
747 mov [base_code],0A1h
748 jmp store_mov_address32
749 mov_ax_mem_address16:
750 call store_segment_prefix_if_necessary
751 call address_16bit_prefix
752 mov [base_code],0A1h
753 jmp store_mov_address16
754 mov_ax_mem_address64:
755 call store_segment_prefix_if_necessary
756 mov [base_code],0A1h
757 jmp store_mov_address64
758 mov_reg_imm:
759 mov al,[operand_size]
760 cmp al,1
761 je mov_reg_imm_8bit
762 cmp al,2
763 je mov_reg_imm_16bit
764 cmp al,4
765 je mov_reg_imm_32bit
766 cmp al,8
767 jne invalid_operand_size
768 mov_reg_imm_64bit:
769 call operand_64bit
770 call get_qword_value
771 mov ecx,edx
772 cmp [size_declared],0
773 jne mov_reg_imm_64bit_store
774 cmp [value_type],4
775 jae mov_reg_imm_64bit_store
776 cdq
777 cmp ecx,edx
778 je mov_reg_64bit_imm_32bit
779 mov_reg_imm_64bit_store:
780 push eax ecx
781 mov al,0B8h
782 call store_mov_reg_imm_code
783 pop edx eax
784 call mark_relocation
785 stos dword [edi]
786 mov eax,edx
787 stos dword [edi]
788 jmp instruction_assembled
789 mov_reg_imm_8bit:
790 call get_byte_value
791 mov dl,al
792 mov al,0B0h
793 call store_mov_reg_imm_code
794 mov al,dl
795 stos byte [edi]
796 jmp instruction_assembled
797 mov_reg_imm_16bit:
798 call get_word_value
799 mov dx,ax
800 call operand_16bit
801 mov al,0B8h
802 call store_mov_reg_imm_code
803 mov ax,dx
804 call mark_relocation
805 stos word [edi]
806 jmp instruction_assembled
807 mov_reg_imm_32bit:
808 call operand_32bit
809 call get_dword_value
810 mov edx,eax
811 mov al,0B8h
812 call store_mov_reg_imm_code
813 mov_store_imm_32bit:
814 mov eax,edx
815 call mark_relocation
816 stos dword [edi]
817 jmp instruction_assembled
818 store_mov_reg_imm_code:
819 mov ah,[postbyte_register]
820 test ah,1000b
821 jz mov_reg_imm_prefix_ok
822 or [rex_prefix],41h
823 mov_reg_imm_prefix_ok:
824 and ah,111b
825 add al,ah
826 mov [base_code],al
827 call store_instruction_code
828 ret
829 mov_reg_64bit_imm_32bit:
830 mov edx,eax
831 mov bl,[postbyte_register]
832 mov [postbyte_register],0
833 mov [base_code],0C7h
834 call store_nomem_instruction
835 jmp mov_store_imm_32bit
836 mov_sreg:
837 mov ah,al
838 and al,1111b
839 mov [postbyte_register],al
840 shr ah,4
841 cmp ah,5
842 je mov_creg
843 cmp ah,7
844 je mov_dreg
845 ja mov_treg
846 cmp al,2
847 je illegal_instruction
848 dec [postbyte_register]
849 lods byte [esi]
850 cmp al,','
851 jne invalid_operand
852 lods byte [esi]
853 call get_size_operator
854 cmp al,'['
855 je mov_sreg_mem
856 cmp al,10h
857 jne invalid_operand
858 mov_sreg_reg:
859 lods byte [esi]
860 call convert_register
861 or ah,ah
862 jz mov_sreg_reg_size_ok
863 cmp ah,2
864 jne invalid_operand_size
865 mov bl,al
866 mov_sreg_reg_size_ok:
867 mov [base_code],8Eh
868 jmp nomem_instruction_ready
869 mov_sreg_mem:
870 call get_address
871 mov al,[operand_size]
872 or al,al
873 jz mov_sreg_mem_size_ok
874 cmp al,2
875 jne invalid_operand_size
876 mov_sreg_mem_size_ok:
877 mov [base_code],8Eh
878 jmp instruction_ready
879 mov_treg:
880 cmp ah,9
881 jne invalid_operand
882 mov [extended_code],26h
883 jmp mov_xrx
884 mov_dreg:
885 mov [extended_code],23h
886 jmp mov_xrx
887 mov_creg:
888 mov [extended_code],22h
889 mov_xrx:
890 mov [base_code],0Fh
891 lods byte [esi]
892 cmp al,','
893 jne invalid_operand
894 lods byte [esi]
895 cmp al,10h
896 jne invalid_operand
897 lods byte [esi]
898 call convert_register
899 mov bl,al
900 cmp [code_type],64
901 je mov_xrx_64bit
902 cmp ah,4
903 jne invalid_operand_size
904 cmp [postbyte_register],8
905 jne mov_xrx_store
906 cmp [extended_code],22h
907 jne mov_xrx_store
908 mov al,0F0h
909 stos byte [edi]
910 mov [postbyte_register],0
911 mov_xrx_store:
912 jmp nomem_instruction_ready
913 mov_xrx_64bit:
914 cmp ah,8
915 je mov_xrx_store
916 jmp invalid_operand_size
917 test_instruction:
918 mov [base_code],84h
919 lods byte [esi]
920 call get_size_operator
921 cmp al,10h
922 je test_reg
923 cmp al,'['
924 jne invalid_operand
925 test_mem:
926 call get_address
927 push edx ebx ecx
928 lods byte [esi]
929 cmp al,','
930 jne invalid_operand
931 lods byte [esi]
932 call get_size_operator
933 cmp al,'('
934 je test_mem_imm
935 cmp al,10h
936 jne invalid_operand
937 test_mem_reg:
938 lods byte [esi]
939 call convert_register
940 mov [postbyte_register],al
941 pop ecx ebx edx
942 mov al,ah
943 cmp al,1
944 je test_mem_reg_8bit
945 call operand_autodetect
946 inc [base_code]
947 test_mem_reg_8bit:
948 jmp instruction_ready
949 test_mem_imm:
950 mov al,[operand_size]
951 cmp al,1
952 jb test_mem_imm_nosize
953 je test_mem_imm_8bit
954 cmp al,2
955 je test_mem_imm_16bit
956 cmp al,4
957 je test_mem_imm_32bit
958 cmp al,8
959 jne invalid_operand_size
960 test_mem_imm_64bit:
961 cmp [size_declared],0
962 jne long_immediate_not_encodable
963 call operand_64bit
964 call get_simm32
965 cmp [value_type],4
966 jae long_immediate_not_encodable
967 jmp test_mem_imm_32bit_store
968 test_mem_imm_8bit:
969 call get_byte_value
970 mov byte [value],al
971 mov [postbyte_register],0
972 mov [base_code],0F6h
973 pop ecx ebx edx
974 call store_instruction_with_imm8
975 jmp instruction_assembled
976 test_mem_imm_16bit:
977 call operand_16bit
978 call get_word_value
979 mov word [value],ax
980 mov [postbyte_register],0
981 mov [base_code],0F7h
982 pop ecx ebx edx
983 call store_instruction_with_imm16
984 jmp instruction_assembled
985 test_mem_imm_nosize:
986 call recoverable_unknown_size
987 test_mem_imm_32bit:
988 call operand_32bit
989 call get_dword_value
990 test_mem_imm_32bit_store:
991 mov dword [value],eax
992 mov [postbyte_register],0
993 mov [base_code],0F7h
994 pop ecx ebx edx
995 call store_instruction_with_imm32
996 jmp instruction_assembled
997 test_reg:
998 lods byte [esi]
999 call convert_register
1000 mov [postbyte_register],al
1001 lods byte [esi]
1002 cmp al,','
1003 jne invalid_operand
1004 lods byte [esi]
1005 call get_size_operator
1006 cmp al,'['
1007 je test_reg_mem
1008 cmp al,'('
1009 je test_reg_imm
1010 cmp al,10h
1011 jne invalid_operand
1012 test_reg_reg:
1013 lods byte [esi]
1014 call convert_register
1015 mov bl,[postbyte_register]
1016 mov [postbyte_register],al
1017 mov al,ah
1018 cmp al,1
1019 je test_reg_reg_8bit
1020 call operand_autodetect
1021 inc [base_code]
1022 test_reg_reg_8bit:
1023 jmp nomem_instruction_ready
1024 test_reg_imm:
1025 mov al,[operand_size]
1026 cmp al,1
1027 je test_reg_imm_8bit
1028 cmp al,2
1029 je test_reg_imm_16bit
1030 cmp al,4
1031 je test_reg_imm_32bit
1032 cmp al,8
1033 jne invalid_operand_size
1034 test_reg_imm_64bit:
1035 cmp [size_declared],0
1036 jne long_immediate_not_encodable
1037 call operand_64bit
1038 call get_simm32
1039 cmp [value_type],4
1040 jae long_immediate_not_encodable
1041 jmp test_reg_imm_32bit_store
1042 test_reg_imm_8bit:
1043 call get_byte_value
1044 mov dl,al
1045 mov bl,[postbyte_register]
1046 mov [postbyte_register],0
1047 mov [base_code],0F6h
1048 or bl,bl
1049 jz test_al_imm
1050 call store_nomem_instruction
1051 mov al,dl
1052 stos byte [edi]
1053 jmp instruction_assembled
1054 test_al_imm:
1055 mov [base_code],0A8h
1056 call store_instruction_code
1057 mov al,dl
1058 stos byte [edi]
1059 jmp instruction_assembled
1060 test_reg_imm_16bit:
1061 call operand_16bit
1062 call get_word_value
1063 mov dx,ax
1064 mov bl,[postbyte_register]
1065 mov [postbyte_register],0
1066 mov [base_code],0F7h
1067 or bl,bl
1068 jz test_ax_imm
1069 call store_nomem_instruction
1070 mov ax,dx
1071 call mark_relocation
1072 stos word [edi]
1073 jmp instruction_assembled
1074 test_ax_imm:
1075 mov [base_code],0A9h
1076 call store_instruction_code
1077 mov ax,dx
1078 stos word [edi]
1079 jmp instruction_assembled
1080 test_reg_imm_32bit:
1081 call operand_32bit
1082 call get_dword_value
1083 test_reg_imm_32bit_store:
1084 mov edx,eax
1085 mov bl,[postbyte_register]
1086 mov [postbyte_register],0
1087 mov [base_code],0F7h
1088 or bl,bl
1089 jz test_eax_imm
1090 call store_nomem_instruction
1091 mov eax,edx
1092 call mark_relocation
1093 stos dword [edi]
1094 jmp instruction_assembled
1095 test_eax_imm:
1096 mov [base_code],0A9h
1097 call store_instruction_code
1098 mov eax,edx
1099 stos dword [edi]
1100 jmp instruction_assembled
1101 test_reg_mem:
1102 call get_address
1103 mov al,[operand_size]
1104 cmp al,1
1105 je test_reg_mem_8bit
1106 call operand_autodetect
1107 inc [base_code]
1108 test_reg_mem_8bit:
1109 jmp instruction_ready
1110 xchg_instruction:
1111 mov [base_code],86h
1112 lods byte [esi]
1113 call get_size_operator
1114 cmp al,10h
1115 je xchg_reg
1116 cmp al,'['
1117 jne invalid_operand
1118 xchg_mem:
1119 call get_address
1120 push edx ebx ecx
1121 lods byte [esi]
1122 cmp al,','
1123 jne invalid_operand
1124 lods byte [esi]
1125 call get_size_operator
1126 cmp al,10h
1127 je test_mem_reg
1128 jmp invalid_operand
1129 xchg_reg:
1130 lods byte [esi]
1131 call convert_register
1132 mov [postbyte_register],al
1133 lods byte [esi]
1134 cmp al,','
1135 jne invalid_operand
1136 lods byte [esi]
1137 call get_size_operator
1138 cmp al,'['
1139 je test_reg_mem
1140 cmp al,10h
1141 jne invalid_operand
1142 xchg_reg_reg:
1143 lods byte [esi]
1144 call convert_register
1145 mov bl,al
1146 mov al,ah
1147 cmp al,1
1148 je xchg_reg_reg_8bit
1149 call operand_autodetect
1150 cmp [postbyte_register],0
1151 je xchg_ax_reg
1152 or bl,bl
1153 jnz xchg_reg_reg_store
1154 mov bl,[postbyte_register]
1155 xchg_ax_reg:
1156 cmp [code_type],64
1157 jne xchg_ax_reg_ok
1158 cmp ah,4
1159 jne xchg_ax_reg_ok
1160 or bl,bl
1161 jz xchg_reg_reg_store
1162 xchg_ax_reg_ok:
1163 test bl,1000b
1164 jz xchg_ax_reg_store
1165 or [rex_prefix],41h
1166 and bl,111b
1167 xchg_ax_reg_store:
1168 add bl,90h
1169 mov [base_code],bl
1170 call store_instruction_code
1171 jmp instruction_assembled
1172 xchg_reg_reg_store:
1173 inc [base_code]
1174 xchg_reg_reg_8bit:
1175 jmp nomem_instruction_ready
1176 push_instruction:
1177 mov [push_size],al
1178 push_next:
1179 lods byte [esi]
1180 call get_size_operator
1181 cmp al,10h
1182 je push_reg
1183 cmp al,'('
1184 je push_imm
1185 cmp al,'['
1186 jne invalid_operand
1187 push_mem:
1188 call get_address
1189 mov al,[operand_size]
1190 mov ah,[push_size]
1191 cmp al,2
1192 je push_mem_16bit
1193 cmp al,4
1194 je push_mem_32bit
1195 cmp al,8
1196 je push_mem_64bit
1197 or al,al
1198 jnz invalid_operand_size
1199 cmp ah,2
1200 je push_mem_16bit
1201 cmp ah,4
1202 je push_mem_32bit
1203 cmp ah,8
1204 je push_mem_64bit
1205 call recoverable_unknown_size
1206 jmp push_mem_store
1207 push_mem_16bit:
1208 test ah,not 2
1209 jnz invalid_operand_size
1210 call operand_16bit
1211 jmp push_mem_store
1212 push_mem_32bit:
1213 test ah,not 4
1214 jnz invalid_operand_size
1215 cmp [code_type],64
1216 je illegal_instruction
1217 call operand_32bit
1218 jmp push_mem_store
1219 push_mem_64bit:
1220 test ah,not 8
1221 jnz invalid_operand_size
1222 cmp [code_type],64
1223 jne illegal_instruction
1224 push_mem_store:
1225 mov [base_code],0FFh
1226 mov [postbyte_register],110b
1227 call store_instruction
1228 jmp push_done
1229 push_reg:
1230 lods byte [esi]
1231 mov ah,al
1232 sub ah,10h
1233 and ah,al
1234 test ah,0F0h
1235 jnz push_sreg
1236 call convert_register
1237 test al,1000b
1238 jz push_reg_ok
1239 or [rex_prefix],41h
1240 and al,111b
1241 push_reg_ok:
1242 add al,50h
1243 mov [base_code],al
1244 mov al,ah
1245 mov ah,[push_size]
1246 cmp al,2
1247 je push_reg_16bit
1248 cmp al,4
1249 je push_reg_32bit
1250 cmp al,8
1251 jne invalid_operand_size
1252 push_reg_64bit:
1253 test ah,not 8
1254 jnz invalid_operand_size
1255 cmp [code_type],64
1256 jne illegal_instruction
1257 jmp push_reg_store
1258 push_reg_32bit:
1259 test ah,not 4
1260 jnz invalid_operand_size
1261 cmp [code_type],64
1262 je illegal_instruction
1263 call operand_32bit
1264 jmp push_reg_store
1265 push_reg_16bit:
1266 test ah,not 2
1267 jnz invalid_operand_size
1268 call operand_16bit
1269 push_reg_store:
1270 call store_instruction_code
1271 jmp push_done
1272 push_sreg:
1273 mov bl,al
1274 mov dl,[operand_size]
1275 mov dh,[push_size]
1276 cmp dl,2
1277 je push_sreg16
1278 cmp dl,4
1279 je push_sreg32
1280 cmp dl,8
1281 je push_sreg64
1282 or dl,dl
1283 jnz invalid_operand_size
1284 cmp dh,2
1285 je push_sreg16
1286 cmp dh,4
1287 je push_sreg32
1288 cmp dh,8
1289 je push_sreg64
1290 jmp push_sreg_store
1291 push_sreg16:
1292 test dh,not 2
1293 jnz invalid_operand_size
1294 call operand_16bit
1295 jmp push_sreg_store
1296 push_sreg32:
1297 test dh,not 4
1298 jnz invalid_operand_size
1299 cmp [code_type],64
1300 je illegal_instruction
1301 call operand_32bit
1302 jmp push_sreg_store
1303 push_sreg64:
1304 test dh,not 8
1305 jnz invalid_operand_size
1306 cmp [code_type],64
1307 jne illegal_instruction
1308 push_sreg_store:
1309 mov al,bl
1310 cmp al,70h
1311 jae invalid_operand
1312 sub al,61h
1313 jc invalid_operand
1314 cmp al,4
1315 jae push_sreg_386
1316 shl al,3
1317 add al,6
1318 mov [base_code],al
1319 cmp [code_type],64
1320 je illegal_instruction
1321 jmp push_reg_store
1322 push_sreg_386:
1323 sub al,4
1324 shl al,3
1325 add al,0A0h
1326 mov [extended_code],al
1327 mov [base_code],0Fh
1328 jmp push_reg_store
1329 push_imm:
1330 mov al,[operand_size]
1331 mov ah,[push_size]
1332 or al,al
1333 je push_imm_size_ok
1334 or ah,ah
1335 je push_imm_size_ok
1336 cmp al,ah
1337 jne invalid_operand_size
1338 push_imm_size_ok:
1339 cmp al,2
1340 je push_imm_16bit
1341 cmp al,4
1342 je push_imm_32bit
1343 cmp al,8
1344 je push_imm_64bit
1345 cmp ah,2
1346 je push_imm_optimized_16bit
1347 cmp ah,4
1348 je push_imm_optimized_32bit
1349 cmp ah,8
1350 je push_imm_optimized_64bit
1351 or al,al
1352 jnz invalid_operand_size
1353 cmp [code_type],16
1354 je push_imm_optimized_16bit
1355 cmp [code_type],32
1356 je push_imm_optimized_32bit
1357 push_imm_optimized_64bit:
1358 cmp [code_type],64
1359 jne illegal_instruction
1360 call get_simm32
1361 mov edx,eax
1362 cmp [value_type],0
1363 jne push_imm_32bit_store
1364 cmp eax,-80h
1365 jl push_imm_32bit_store
1366 cmp eax,80h
1367 jge push_imm_32bit_store
1368 jmp push_imm_8bit
1369 push_imm_optimized_32bit:
1370 cmp [code_type],64
1371 je illegal_instruction
1372 call get_dword_value
1373 mov edx,eax
1374 call operand_32bit
1375 cmp [value_type],0
1376 jne push_imm_32bit_store
1377 cmp eax,-80h
1378 jl push_imm_32bit_store
1379 cmp eax,80h
1380 jge push_imm_32bit_store
1381 jmp push_imm_8bit
1382 push_imm_optimized_16bit:
1383 call get_word_value
1384 mov dx,ax
1385 call operand_16bit
1386 cmp [value_type],0
1387 jne push_imm_16bit_store
1388 cmp ax,-80h
1389 jl push_imm_16bit_store
1390 cmp ax,80h
1391 jge push_imm_16bit_store
1392 push_imm_8bit:
1393 mov ah,al
1394 mov [base_code],6Ah
1395 call store_instruction_code
1396 mov al,ah
1397 stos byte [edi]
1398 jmp push_done
1399 push_imm_16bit:
1400 call get_word_value
1401 mov dx,ax
1402 call operand_16bit
1403 push_imm_16bit_store:
1404 mov [base_code],68h
1405 call store_instruction_code
1406 mov ax,dx
1407 call mark_relocation
1408 stos word [edi]
1409 jmp push_done
1410 push_imm_64bit:
1411 cmp [code_type],64
1412 jne illegal_instruction
1413 call get_simm32
1414 mov edx,eax
1415 jmp push_imm_32bit_store
1416 push_imm_32bit:
1417 cmp [code_type],64
1418 je illegal_instruction
1419 call get_dword_value
1420 mov edx,eax
1421 call operand_32bit
1422 push_imm_32bit_store:
1423 mov [base_code],68h
1424 call store_instruction_code
1425 mov eax,edx
1426 call mark_relocation
1427 stos dword [edi]
1428 push_done:
1429 lods byte [esi]
1430 dec esi
1431 cmp al,0Fh
1432 je instruction_assembled
1433 or al,al
1434 jz instruction_assembled
1435 mov [operand_size],0
1436 mov [size_override],0
1437 mov [operand_prefix],0
1438 mov [rex_prefix],0
1439 jmp push_next
1440 pop_instruction:
1441 mov [push_size],al
1442 pop_next:
1443 lods byte [esi]
1444 call get_size_operator
1445 cmp al,10h
1446 je pop_reg
1447 cmp al,'['
1448 jne invalid_operand
1449 pop_mem:
1450 call get_address
1451 mov al,[operand_size]
1452 mov ah,[push_size]
1453 cmp al,2
1454 je pop_mem_16bit
1455 cmp al,4
1456 je pop_mem_32bit
1457 cmp al,8
1458 je pop_mem_64bit
1459 or al,al
1460 jnz invalid_operand_size
1461 cmp ah,2
1462 je pop_mem_16bit
1463 cmp ah,4
1464 je pop_mem_32bit
1465 cmp ah,8
1466 je pop_mem_64bit
1467 call recoverable_unknown_size
1468 jmp pop_mem_store
1469 pop_mem_16bit:
1470 test ah,not 2
1471 jnz invalid_operand_size
1472 call operand_16bit
1473 jmp pop_mem_store
1474 pop_mem_32bit:
1475 test ah,not 4
1476 jnz invalid_operand_size
1477 cmp [code_type],64
1478 je illegal_instruction
1479 call operand_32bit
1480 jmp pop_mem_store
1481 pop_mem_64bit:
1482 test ah,not 8
1483 jnz invalid_operand_size
1484 cmp [code_type],64
1485 jne illegal_instruction
1486 pop_mem_store:
1487 mov [base_code],08Fh
1488 mov [postbyte_register],0
1489 call store_instruction
1490 jmp pop_done
1491 pop_reg:
1492 lods byte [esi]
1493 mov ah,al
1494 sub ah,10h
1495 and ah,al
1496 test ah,0F0h
1497 jnz pop_sreg
1498 call convert_register
1499 test al,1000b
1500 jz pop_reg_ok
1501 or [rex_prefix],41h
1502 and al,111b
1503 pop_reg_ok:
1504 add al,58h
1505 mov [base_code],al
1506 mov al,ah
1507 mov ah,[push_size]
1508 cmp al,2
1509 je pop_reg_16bit
1510 cmp al,4
1511 je pop_reg_32bit
1512 cmp al,8
1513 je pop_reg_64bit
1514 jmp invalid_operand_size
1515 pop_reg_64bit:
1516 test ah,not 8
1517 jnz invalid_operand_size
1518 cmp [code_type],64
1519 jne illegal_instruction
1520 jmp pop_reg_store
1521 pop_reg_32bit:
1522 test ah,not 4
1523 jnz invalid_operand_size
1524 cmp [code_type],64
1525 je illegal_instruction
1526 call operand_32bit
1527 jmp pop_reg_store
1528 pop_reg_16bit:
1529 test ah,not 2
1530 jnz invalid_operand_size
1531 call operand_16bit
1532 pop_reg_store:
1533 call store_instruction_code
1534 pop_done:
1535 lods byte [esi]
1536 dec esi
1537 cmp al,0Fh
1538 je instruction_assembled
1539 or al,al
1540 jz instruction_assembled
1541 mov [operand_size],0
1542 mov [size_override],0
1543 mov [operand_prefix],0
1544 mov [rex_prefix],0
1545 jmp pop_next
1546 pop_sreg:
1547 mov dl,[operand_size]
1548 mov dh,[push_size]
1549 cmp al,62h
1550 je pop_cs
1551 mov bl,al
1552 cmp dl,2
1553 je pop_sreg16
1554 cmp dl,4
1555 je pop_sreg32
1556 cmp dl,8
1557 je pop_sreg64
1558 or dl,dl
1559 jnz invalid_operand_size
1560 cmp dh,2
1561 je pop_sreg16
1562 cmp dh,4
1563 je pop_sreg32
1564 cmp dh,8
1565 je pop_sreg64
1566 jmp pop_sreg_store
1567 pop_sreg16:
1568 test dh,not 2
1569 jnz invalid_operand_size
1570 call operand_16bit
1571 jmp pop_sreg_store
1572 pop_sreg32:
1573 test dh,not 4
1574 jnz invalid_operand_size
1575 cmp [code_type],64
1576 je illegal_instruction
1577 call operand_32bit
1578 jmp pop_sreg_store
1579 pop_sreg64:
1580 test dh,not 8
1581 jnz invalid_operand_size
1582 cmp [code_type],64
1583 jne illegal_instruction
1584 pop_sreg_store:
1585 mov al,bl
1586 cmp al,70h
1587 jae invalid_operand
1588 sub al,61h
1589 jc invalid_operand
1590 cmp al,4
1591 jae pop_sreg_386
1592 shl al,3
1593 add al,7
1594 mov [base_code],al
1595 cmp [code_type],64
1596 je illegal_instruction
1597 jmp pop_reg_store
1598 pop_cs:
1599 cmp [code_type],16
1600 jne illegal_instruction
1601 cmp dl,2
1602 je pop_cs_store
1603 or dl,dl
1604 jnz invalid_operand_size
1605 cmp dh,2
1606 je pop_cs_store
1607 or dh,dh
1608 jnz illegal_instruction
1609 pop_cs_store:
1610 test dh,not 2
1611 jnz invalid_operand_size
1612 mov al,0Fh
1613 stos byte [edi]
1614 jmp pop_done
1615 pop_sreg_386:
1616 sub al,4
1617 shl al,3
1618 add al,0A1h
1619 mov [extended_code],al
1620 mov [base_code],0Fh
1621 jmp pop_reg_store
1622 inc_instruction:
1623 mov [base_code],al
1624 lods byte [esi]
1625 call get_size_operator
1626 cmp al,10h
1627 je inc_reg
1628 cmp al,'['
1629 je inc_mem
1630 jne invalid_operand
1631 inc_mem:
1632 call get_address
1633 mov al,[operand_size]
1634 cmp al,1
1635 je inc_mem_8bit
1636 jb inc_mem_nosize
1637 call operand_autodetect
1638 mov al,0FFh
1639 xchg al,[base_code]
1640 mov [postbyte_register],al
1641 jmp instruction_ready
1642 inc_mem_nosize:
1643 call recoverable_unknown_size
1644 inc_mem_8bit:
1645 mov al,0FEh
1646 xchg al,[base_code]
1647 mov [postbyte_register],al
1648 jmp instruction_ready
1649 inc_reg:
1650 lods byte [esi]
1651 call convert_register
1652 mov bl,al
1653 mov al,0FEh
1654 xchg al,[base_code]
1655 mov [postbyte_register],al
1656 mov al,ah
1657 cmp al,1
1658 je inc_reg_8bit
1659 call operand_autodetect
1660 cmp [code_type],64
1661 je inc_reg_long_form
1662 mov al,[postbyte_register]
1663 shl al,3
1664 add al,bl
1665 add al,40h
1666 mov [base_code],al
1667 call store_instruction_code
1668 jmp instruction_assembled
1669 inc_reg_long_form:
1670 inc [base_code]
1671 inc_reg_8bit:
1672 jmp nomem_instruction_ready
1673 set_instruction:
1674 mov [base_code],0Fh
1675 mov [extended_code],al
1676 lods byte [esi]
1677 call get_size_operator
1678 cmp al,10h
1679 je set_reg
1680 cmp al,'['
1681 jne invalid_operand
1682 set_mem:
1683 call get_address
1684 cmp [operand_size],1
1685 ja invalid_operand_size
1686 mov [postbyte_register],0
1687 jmp instruction_ready
1688 set_reg:
1689 lods byte [esi]
1690 call convert_register
1691 cmp ah,1
1692 jne invalid_operand_size
1693 mov bl,al
1694 mov [postbyte_register],0
1695 jmp nomem_instruction_ready
1696 arpl_instruction:
1697 cmp [code_type],64
1698 je illegal_instruction
1699 mov [base_code],63h
1700 lods byte [esi]
1701 call get_size_operator
1702 cmp al,10h
1703 je arpl_reg
1704 cmp al,'['
1705 jne invalid_operand
1706 call get_address
1707 lods byte [esi]
1708 cmp al,','
1709 jne invalid_operand
1710 lods byte [esi]
1711 cmp al,10h
1712 jne invalid_operand
1713 lods byte [esi]
1714 call convert_register
1715 mov [postbyte_register],al
1716 cmp ah,2
1717 jne invalid_operand_size
1718 jmp instruction_ready
1719 arpl_reg:
1720 lods byte [esi]
1721 call convert_register
1722 cmp ah,2
1723 jne invalid_operand_size
1724 mov bl,al
1725 lods byte [esi]
1726 cmp al,','
1727 jne invalid_operand
1728 lods byte [esi]
1729 cmp al,10h
1730 jne invalid_operand
1731 lods byte [esi]
1732 call convert_register
1733 mov [postbyte_register],al
1734 jmp nomem_instruction_ready
1735 bound_instruction:
1736 cmp [code_type],64
1737 je illegal_instruction
1738 lods byte [esi]
1739 call get_size_operator
1740 cmp al,10h
1741 jne invalid_operand
1742 lods byte [esi]
1743 call convert_register
1744 mov [postbyte_register],al
1745 lods byte [esi]
1746 cmp al,','
1747 jne invalid_operand
1748 lods byte [esi]
1749 call get_size_operator
1750 cmp al,'['
1751 jne invalid_operand
1752 call get_address
1753 mov al,[operand_size]
1754 cmp al,2
1755 je bound_store
1756 cmp al,4
1757 jne invalid_operand_size
1758 bound_store:
1759 call operand_autodetect
1760 mov [base_code],62h
1761 jmp instruction_ready
1762 enter_instruction:
1763 lods byte [esi]
1764 call get_size_operator
1765 cmp ah,2
1766 je enter_imm16_size_ok
1767 or ah,ah
1768 jnz invalid_operand_size
1769 enter_imm16_size_ok:
1770 cmp al,'('
1771 jne invalid_operand
1772 call get_word_value
1773 cmp [next_pass_needed],0
1774 jne enter_imm16_ok
1775 cmp [value_type],0
1776 jne invalid_use_of_symbol
1777 test eax,eax
1778 js value_out_of_range
1779 enter_imm16_ok:
1780 push eax
1781 mov [operand_size],0
1782 lods byte [esi]
1783 cmp al,','
1784 jne invalid_operand
1785 lods byte [esi]
1786 call get_size_operator
1787 cmp ah,1
1788 je enter_imm8_size_ok
1789 or ah,ah
1790 jnz invalid_operand_size
1791 enter_imm8_size_ok:
1792 cmp al,'('
1793 jne invalid_operand
1794 call get_byte_value
1795 cmp [next_pass_needed],0
1796 jne enter_imm8_ok
1797 test eax,eax
1798 js value_out_of_range
1799 enter_imm8_ok:
1800 mov dl,al
1801 pop ebx
1802 mov al,0C8h
1803 stos byte [edi]
1804 mov ax,bx
1805 stos word [edi]
1806 mov al,dl
1807 stos byte [edi]
1808 jmp instruction_assembled
1809 ret_instruction_only64:
1810 cmp [code_type],64
1811 jne illegal_instruction
1812 jmp ret_instruction
1813 ret_instruction_32bit_except64:
1814 cmp [code_type],64
1815 je illegal_instruction
1816 ret_instruction_32bit:
1817 call operand_32bit
1818 jmp ret_instruction
1819 ret_instruction_16bit:
1820 call operand_16bit
1821 jmp ret_instruction
1822 retf_instruction:
1823 cmp [code_type],64
1824 jne ret_instruction
1825 ret_instruction_64bit:
1826 call operand_64bit
1827 ret_instruction:
1828 mov [base_code],al
1829 lods byte [esi]
1830 dec esi
1831 or al,al
1832 jz simple_ret
1833 cmp al,0Fh
1834 je simple_ret
1835 lods byte [esi]
1836 call get_size_operator
1837 or ah,ah
1838 jz ret_imm
1839 cmp ah,2
1840 je ret_imm
1841 jmp invalid_operand_size
1842 ret_imm:
1843 cmp al,'('
1844 jne invalid_operand
1845 call get_word_value
1846 cmp [next_pass_needed],0
1847 jne ret_imm_ok
1848 cmp [value_type],0
1849 jne invalid_use_of_symbol
1850 test eax,eax
1851 js value_out_of_range
1852 ret_imm_ok:
1853 cmp [size_declared],0
1854 jne ret_imm_store
1855 or ax,ax
1856 jz simple_ret
1857 ret_imm_store:
1858 mov dx,ax
1859 call store_instruction_code
1860 mov ax,dx
1861 stos word [edi]
1862 jmp instruction_assembled
1863 simple_ret:
1864 inc [base_code]
1865 call store_instruction_code
1866 jmp instruction_assembled
1867 lea_instruction:
1868 mov [base_code],8Dh
1869 lods byte [esi]
1870 call get_size_operator
1871 cmp al,10h
1872 jne invalid_operand
1873 lods byte [esi]
1874 call convert_register
1875 mov [postbyte_register],al
1876 lods byte [esi]
1877 cmp al,','
1878 jne invalid_operand
1879 xor al,al
1880 xchg al,[operand_size]
1881 push eax
1882 lods byte [esi]
1883 call get_size_operator
1884 cmp al,'['
1885 jne invalid_operand
1886 mov [size_override],-1
1887 call get_address
1888 pop eax
1889 mov [operand_size],al
1890 call operand_autodetect
1891 jmp instruction_ready
1892 ls_instruction:
1893 or al,al
1894 jz les_instruction
1895 cmp al,3
1896 jz lds_instruction
1897 add al,0B0h
1898 mov [extended_code],al
1899 mov [base_code],0Fh
1900 jmp ls_code_ok
1901 les_instruction:
1902 mov [base_code],0C4h
1903 jmp ls_short_code
1904 lds_instruction:
1905 mov [base_code],0C5h
1906 ls_short_code:
1907 cmp [code_type],64
1908 je illegal_instruction
1909 ls_code_ok:
1910 lods byte [esi]
1911 call get_size_operator
1912 cmp al,10h
1913 jne invalid_operand
1914 lods byte [esi]
1915 call convert_register
1916 mov [postbyte_register],al
1917 lods byte [esi]
1918 cmp al,','
1919 jne invalid_operand
1920 add [operand_size],2
1921 lods byte [esi]
1922 call get_size_operator
1923 cmp al,'['
1924 jne invalid_operand
1925 call get_address
1926 mov al,[operand_size]
1927 cmp al,4
1928 je ls_16bit
1929 cmp al,6
1930 je ls_32bit
1931 cmp al,10
1932 je ls_64bit
1933 jmp invalid_operand_size
1934 ls_16bit:
1935 call operand_16bit
1936 jmp instruction_ready
1937 ls_32bit:
1938 call operand_32bit
1939 jmp instruction_ready
1940 ls_64bit:
1941 call operand_64bit
1942 jmp instruction_ready
1943 sh_instruction:
1944 mov [postbyte_register],al
1945 lods byte [esi]
1946 call get_size_operator
1947 cmp al,10h
1948 je sh_reg
1949 cmp al,'['
1950 jne invalid_operand
1951 sh_mem:
1952 call get_address
1953 push edx ebx ecx
1954 mov al,[operand_size]
1955 push eax
1956 mov [operand_size],0
1957 lods byte [esi]
1958 cmp al,','
1959 jne invalid_operand
1960 lods byte [esi]
1961 call get_size_operator
1962 cmp al,'('
1963 je sh_mem_imm
1964 cmp al,10h
1965 jne invalid_operand
1966 sh_mem_reg:
1967 lods byte [esi]
1968 cmp al,11h
1969 jne invalid_operand
1970 pop eax ecx ebx edx
1971 cmp al,1
1972 je sh_mem_cl_8bit
1973 jb sh_mem_cl_nosize
1974 call operand_autodetect
1975 mov [base_code],0D3h
1976 jmp instruction_ready
1977 sh_mem_cl_nosize:
1978 call recoverable_unknown_size
1979 sh_mem_cl_8bit:
1980 mov [base_code],0D2h
1981 jmp instruction_ready
1982 sh_mem_imm:
1983 mov al,[operand_size]
1984 or al,al
1985 jz sh_mem_imm_size_ok
1986 cmp al,1
1987 jne invalid_operand_size
1988 sh_mem_imm_size_ok:
1989 call get_byte_value
1990 mov byte [value],al
1991 pop eax ecx ebx edx
1992 cmp al,1
1993 je sh_mem_imm_8bit
1994 jb sh_mem_imm_nosize
1995 call operand_autodetect
1996 cmp byte [value],1
1997 je sh_mem_1
1998 mov [base_code],0C1h
1999 call store_instruction_with_imm8
2000 jmp instruction_assembled
2001 sh_mem_1:
2002 mov [base_code],0D1h
2003 jmp instruction_ready
2004 sh_mem_imm_nosize:
2005 call recoverable_unknown_size
2006 sh_mem_imm_8bit:
2007 cmp byte [value],1
2008 je sh_mem_1_8bit
2009 mov [base_code],0C0h
2010 call store_instruction_with_imm8
2011 jmp instruction_assembled
2012 sh_mem_1_8bit:
2013 mov [base_code],0D0h
2014 jmp instruction_ready
2015 sh_reg:
2016 lods byte [esi]
2017 call convert_register
2018 mov bx,ax
2019 mov [operand_size],0
2020 lods byte [esi]
2021 cmp al,','
2022 jne invalid_operand
2023 lods byte [esi]
2024 call get_size_operator
2025 cmp al,'('
2026 je sh_reg_imm
2027 cmp al,10h
2028 jne invalid_operand
2029 sh_reg_reg:
2030 lods byte [esi]
2031 cmp al,11h
2032 jne invalid_operand
2033 mov al,bh
2034 cmp al,1
2035 je sh_reg_cl_8bit
2036 call operand_autodetect
2037 mov [base_code],0D3h
2038 jmp nomem_instruction_ready
2039 sh_reg_cl_8bit:
2040 mov [base_code],0D2h
2041 jmp nomem_instruction_ready
2042 sh_reg_imm:
2043 mov al,[operand_size]
2044 or al,al
2045 jz sh_reg_imm_size_ok
2046 cmp al,1
2047 jne invalid_operand_size
2048 sh_reg_imm_size_ok:
2049 push ebx
2050 call get_byte_value
2051 mov dl,al
2052 pop ebx
2053 mov al,bh
2054 cmp al,1
2055 je sh_reg_imm_8bit
2056 call operand_autodetect
2057 cmp dl,1
2058 je sh_reg_1
2059 mov [base_code],0C1h
2060 call store_nomem_instruction
2061 mov al,dl
2062 stos byte [edi]
2063 jmp instruction_assembled
2064 sh_reg_1:
2065 mov [base_code],0D1h
2066 jmp nomem_instruction_ready
2067 sh_reg_imm_8bit:
2068 cmp dl,1
2069 je sh_reg_1_8bit
2070 mov [base_code],0C0h
2071 call store_nomem_instruction
2072 mov al,dl
2073 stos byte [edi]
2074 jmp instruction_assembled
2075 sh_reg_1_8bit:
2076 mov [base_code],0D0h
2077 jmp nomem_instruction_ready
2078 shd_instruction:
2079 mov [base_code],0Fh
2080 mov [extended_code],al
2081 lods byte [esi]
2082 call get_size_operator
2083 cmp al,10h
2084 je shd_reg
2085 cmp al,'['
2086 jne invalid_operand
2087 shd_mem:
2088 call get_address
2089 push edx ebx ecx
2090 lods byte [esi]
2091 cmp al,','
2092 jne invalid_operand
2093 lods byte [esi]
2094 call get_size_operator
2095 cmp al,10h
2096 jne invalid_operand
2097 lods byte [esi]
2098 call convert_register
2099 mov [postbyte_register],al
2100 lods byte [esi]
2101 cmp al,','
2102 jne invalid_operand
2103 mov al,ah
2104 mov [operand_size],0
2105 push eax
2106 lods byte [esi]
2107 call get_size_operator
2108 cmp al,'('
2109 je shd_mem_reg_imm
2110 cmp al,10h
2111 jne invalid_operand
2112 lods byte [esi]
2113 cmp al,11h
2114 jne invalid_operand
2115 pop eax ecx ebx edx
2116 call operand_autodetect
2117 inc [extended_code]
2118 jmp instruction_ready
2119 shd_mem_reg_imm:
2120 mov al,[operand_size]
2121 or al,al
2122 jz shd_mem_reg_imm_size_ok
2123 cmp al,1
2124 jne invalid_operand_size
2125 shd_mem_reg_imm_size_ok:
2126 call get_byte_value
2127 mov byte [value],al
2128 pop eax ecx ebx edx
2129 call operand_autodetect
2130 call store_instruction_with_imm8
2131 jmp instruction_assembled
2132 shd_reg:
2133 lods byte [esi]
2134 call convert_register
2135 mov [postbyte_register],al
2136 lods byte [esi]
2137 cmp al,','
2138 jne invalid_operand
2139 lods byte [esi]
2140 call get_size_operator
2141 cmp al,10h
2142 jne invalid_operand
2143 lods byte [esi]
2144 call convert_register
2145 mov bl,[postbyte_register]
2146 mov [postbyte_register],al
2147 mov al,ah
2148 push eax ebx
2149 lods byte [esi]
2150 cmp al,','
2151 jne invalid_operand
2152 mov [operand_size],0
2153 lods byte [esi]
2154 call get_size_operator
2155 cmp al,'('
2156 je shd_reg_reg_imm
2157 cmp al,10h
2158 jne invalid_operand
2159 lods byte [esi]
2160 cmp al,11h
2161 jne invalid_operand
2162 pop ebx eax
2163 call operand_autodetect
2164 inc [extended_code]
2165 jmp nomem_instruction_ready
2166 shd_reg_reg_imm:
2167 mov al,[operand_size]
2168 or al,al
2169 jz shd_reg_reg_imm_size_ok
2170 cmp al,1
2171 jne invalid_operand_size
2172 shd_reg_reg_imm_size_ok:
2173 call get_byte_value
2174 mov dl,al
2175 pop ebx eax
2176 call operand_autodetect
2177 call store_nomem_instruction
2178 mov al,dl
2179 stos byte [edi]
2180 jmp instruction_assembled
2181 movx_instruction:
2182 mov [base_code],0Fh
2183 mov [extended_code],al
2184 lods byte [esi]
2185 call get_size_operator
2186 cmp al,10h
2187 jne invalid_operand
2188 lods byte [esi]
2189 call convert_register
2190 mov [postbyte_register],al
2191 mov al,ah
2192 push eax
2193 lods byte [esi]
2194 cmp al,','
2195 jne invalid_operand
2196 mov [operand_size],0
2197 lods byte [esi]
2198 call get_size_operator
2199 cmp al,10h
2200 je movx_reg
2201 cmp al,'['
2202 jne invalid_operand
2203 call get_address
2204 pop eax
2205 mov ah,[operand_size]
2206 or ah,ah
2207 jz movx_unknown_size
2208 cmp ah,al
2209 jae invalid_operand_size
2210 cmp ah,1
2211 je movx_mem_store
2212 cmp ah,2
2213 jne invalid_operand_size
2214 inc [extended_code]
2215 movx_mem_store:
2216 call operand_autodetect
2217 jmp instruction_ready
2218 movx_unknown_size:
2219 call recoverable_unknown_size
2220 jmp movx_mem_store
2221 movx_reg:
2222 lods byte [esi]
2223 call convert_register
2224 pop ebx
2225 xchg bl,al
2226 cmp ah,al
2227 jae invalid_operand_size
2228 cmp ah,1
2229 je movx_reg_8bit
2230 cmp ah,2
2231 je movx_reg_16bit
2232 jmp invalid_operand_size
2233 movx_reg_8bit:
2234 call operand_autodetect
2235 jmp nomem_instruction_ready
2236 movx_reg_16bit:
2237 call operand_autodetect
2238 inc [extended_code]
2239 jmp nomem_instruction_ready
2240 movsxd_instruction:
2241 mov [base_code],al
2242 lods byte [esi]
2243 call get_size_operator
2244 cmp al,10h
2245 jne invalid_operand
2246 lods byte [esi]
2247 call convert_register
2248 mov [postbyte_register],al
2249 cmp ah,8
2250 jne invalid_operand_size
2251 lods byte [esi]
2252 cmp al,','
2253 jne invalid_operand
2254 mov [operand_size],0
2255 lods byte [esi]
2256 call get_size_operator
2257 cmp al,10h
2258 je movsxd_reg
2259 cmp al,'['
2260 jne invalid_operand
2261 call get_address
2262 cmp [operand_size],4
2263 je movsxd_mem_store
2264 cmp [operand_size],0
2265 jne invalid_operand_size
2266 movsxd_mem_store:
2267 call operand_64bit
2268 jmp instruction_ready
2269 movsxd_reg:
2270 lods byte [esi]
2271 call convert_register
2272 cmp ah,4
2273 jne invalid_operand_size
2274 mov bl,al
2275 call operand_64bit
2276 jmp nomem_instruction_ready
2277 bt_instruction:
2278 mov [postbyte_register],al
2279 shl al,3
2280 add al,83h
2281 mov [extended_code],al
2282 mov [base_code],0Fh
2283 lods byte [esi]
2284 call get_size_operator
2285 cmp al,10h
2286 je bt_reg
2287 cmp al,'['
2288 jne invalid_operand
2289 call get_address
2290 push eax ebx ecx
2291 lods byte [esi]
2292 cmp al,','
2293 jne invalid_operand
2294 cmp byte [esi],'('
2295 je bt_mem_imm
2296 cmp byte [esi],11h
2297 jne bt_mem_reg
2298 cmp byte [esi+2],'('
2299 je bt_mem_imm
2300 bt_mem_reg:
2301 lods byte [esi]
2302 call get_size_operator
2303 cmp al,10h
2304 jne invalid_operand
2305 lods byte [esi]
2306 call convert_register
2307 mov [postbyte_register],al
2308 pop ecx ebx edx
2309 mov al,ah
2310 call operand_autodetect
2311 jmp instruction_ready
2312 bt_mem_imm:
2313 xor al,al
2314 xchg al,[operand_size]
2315 push eax
2316 lods byte [esi]
2317 call get_size_operator
2318 cmp al,'('
2319 jne invalid_operand
2320 mov al,[operand_size]
2321 or al,al
2322 jz bt_mem_imm_size_ok
2323 cmp al,1
2324 jne invalid_operand_size
2325 bt_mem_imm_size_ok:
2326 call get_byte_value
2327 mov byte [value],al
2328 pop eax
2329 or al,al
2330 jz bt_mem_imm_nosize
2331 call operand_autodetect
2332 bt_mem_imm_store:
2333 pop ecx ebx edx
2334 mov [extended_code],0BAh
2335 call store_instruction_with_imm8
2336 jmp instruction_assembled
2337 bt_mem_imm_nosize:
2338 call recoverable_unknown_size
2339 jmp bt_mem_imm_store
2340 bt_reg:
2341 lods byte [esi]
2342 call convert_register
2343 mov bl,al
2344 lods byte [esi]
2345 cmp al,','
2346 jne invalid_operand
2347 cmp byte [esi],'('
2348 je bt_reg_imm
2349 cmp byte [esi],11h
2350 jne bt_reg_reg
2351 cmp byte [esi+2],'('
2352 je bt_reg_imm
2353 bt_reg_reg:
2354 lods byte [esi]
2355 call get_size_operator
2356 cmp al,10h
2357 jne invalid_operand
2358 lods byte [esi]
2359 call convert_register
2360 mov [postbyte_register],al
2361 mov al,ah
2362 call operand_autodetect
2363 jmp nomem_instruction_ready
2364 bt_reg_imm:
2365 xor al,al
2366 xchg al,[operand_size]
2367 push eax ebx
2368 lods byte [esi]
2369 call get_size_operator
2370 cmp al,'('
2371 jne invalid_operand
2372 mov al,[operand_size]
2373 or al,al
2374 jz bt_reg_imm_size_ok
2375 cmp al,1
2376 jne invalid_operand_size
2377 bt_reg_imm_size_ok:
2378 call get_byte_value
2379 mov byte [value],al
2380 pop ebx eax
2381 call operand_autodetect
2382 bt_reg_imm_store:
2383 mov [extended_code],0BAh
2384 call store_nomem_instruction
2385 mov al,byte [value]
2386 stos byte [edi]
2387 jmp instruction_assembled
2388 bs_instruction:
2389 mov [extended_code],al
2390 mov [base_code],0Fh
2391 call get_reg_mem
2392 jc bs_reg_reg
2393 mov al,[operand_size]
2394 call operand_autodetect
2395 jmp instruction_ready
2396 bs_reg_reg:
2397 mov al,ah
2398 call operand_autodetect
2399 jmp nomem_instruction_ready
2400 get_reg_mem:
2401 lods byte [esi]
2402 call get_size_operator
2403 cmp al,10h
2404 jne invalid_operand
2405 lods byte [esi]
2406 call convert_register
2407 mov [postbyte_register],al
2408 lods byte [esi]
2409 cmp al,','
2410 jne invalid_operand
2411 lods byte [esi]
2412 call get_size_operator
2413 cmp al,10h
2414 je get_reg_reg
2415 cmp al,'['
2416 jne invalid_argument
2417 call get_address
2418 clc
2419 ret
2420 get_reg_reg:
2421 lods byte [esi]
2422 call convert_register
2423 mov bl,al
2424 stc
2425 ret
2426
2427 imul_instruction:
2428 mov [base_code],0F6h
2429 mov [postbyte_register],5
2430 lods byte [esi]
2431 call get_size_operator
2432 cmp al,10h
2433 je imul_reg
2434 cmp al,'['
2435 jne invalid_operand
2436 imul_mem:
2437 call get_address
2438 mov al,[operand_size]
2439 cmp al,1
2440 je imul_mem_8bit
2441 jb imul_mem_nosize
2442 call operand_autodetect
2443 inc [base_code]
2444 jmp instruction_ready
2445 imul_mem_nosize:
2446 call recoverable_unknown_size
2447 imul_mem_8bit:
2448 jmp instruction_ready
2449 imul_reg:
2450 lods byte [esi]
2451 call convert_register
2452 cmp byte [esi],','
2453 je imul_reg_
2454 mov bl,al
2455 mov al,ah
2456 cmp al,1
2457 je imul_reg_8bit
2458 call operand_autodetect
2459 inc [base_code]
2460 imul_reg_8bit:
2461 jmp nomem_instruction_ready
2462 imul_reg_:
2463 mov [postbyte_register],al
2464 inc esi
2465 cmp byte [esi],'('
2466 je imul_reg_imm
2467 cmp byte [esi],11h
2468 jne imul_reg_noimm
2469 cmp byte [esi+2],'('
2470 je imul_reg_imm
2471 imul_reg_noimm:
2472 lods byte [esi]
2473 call get_size_operator
2474 cmp al,10h
2475 je imul_reg_reg
2476 cmp al,'['
2477 jne invalid_operand
2478 imul_reg_mem:
2479 call get_address
2480 push edx ebx ecx
2481 cmp byte [esi],','
2482 je imul_reg_mem_imm
2483 mov al,[operand_size]
2484 call operand_autodetect
2485 pop ecx ebx edx
2486 mov [base_code],0Fh
2487 mov [extended_code],0AFh
2488 jmp instruction_ready
2489 imul_reg_mem_imm:
2490 inc esi
2491 lods byte [esi]
2492 call get_size_operator
2493 cmp al,'('
2494 jne invalid_operand
2495 mov al,[operand_size]
2496 cmp al,2
2497 je imul_reg_mem_imm_16bit
2498 cmp al,4
2499 je imul_reg_mem_imm_32bit
2500 cmp al,8
2501 jne invalid_operand_size
2502 imul_reg_mem_imm_64bit:
2503 cmp [size_declared],0
2504 jne long_immediate_not_encodable
2505 call operand_64bit
2506 call get_simm32
2507 cmp [value_type],4
2508 jae long_immediate_not_encodable
2509 jmp imul_reg_mem_imm_32bit_ok
2510 imul_reg_mem_imm_16bit:
2511 call operand_16bit
2512 call get_word_value
2513 mov word [value],ax
2514 cmp [value_type],0
2515 jne imul_reg_mem_imm_16bit_store
2516 cmp [size_declared],0
2517 jne imul_reg_mem_imm_16bit_store
2518 cmp ax,-80h
2519 jl imul_reg_mem_imm_16bit_store
2520 cmp ax,80h
2521 jl imul_reg_mem_imm_8bit_store
2522 imul_reg_mem_imm_16bit_store:
2523 pop ecx ebx edx
2524 mov [base_code],69h
2525 call store_instruction_with_imm16
2526 jmp instruction_assembled
2527 imul_reg_mem_imm_32bit:
2528 call operand_32bit
2529 call get_dword_value
2530 imul_reg_mem_imm_32bit_ok:
2531 mov dword [value],eax
2532 cmp [value_type],0
2533 jne imul_reg_mem_imm_32bit_store
2534 cmp [size_declared],0
2535 jne imul_reg_mem_imm_32bit_store
2536 cmp eax,-80h
2537 jl imul_reg_mem_imm_32bit_store
2538 cmp eax,80h
2539 jl imul_reg_mem_imm_8bit_store
2540 imul_reg_mem_imm_32bit_store:
2541 pop ecx ebx edx
2542 mov [base_code],69h
2543 call store_instruction_with_imm32
2544 jmp instruction_assembled
2545 imul_reg_mem_imm_8bit_store:
2546 pop ecx ebx edx
2547 mov [base_code],6Bh
2548 call store_instruction_with_imm8
2549 jmp instruction_assembled
2550 imul_reg_imm:
2551 mov bl,[postbyte_register]
2552 dec esi
2553 jmp imul_reg_reg_imm
2554 imul_reg_reg:
2555 lods byte [esi]
2556 call convert_register
2557 mov bl,al
2558 cmp byte [esi],','
2559 je imul_reg_reg_imm
2560 mov al,ah
2561 call operand_autodetect
2562 mov [base_code],0Fh
2563 mov [extended_code],0AFh
2564 jmp nomem_instruction_ready
2565 imul_reg_reg_imm:
2566 inc esi
2567 lods byte [esi]
2568 call get_size_operator
2569 cmp al,'('
2570 jne invalid_operand
2571 mov al,[operand_size]
2572 cmp al,2
2573 je imul_reg_reg_imm_16bit
2574 cmp al,4
2575 je imul_reg_reg_imm_32bit
2576 cmp al,8
2577 jne invalid_operand_size
2578 imul_reg_reg_imm_64bit:
2579 cmp [size_declared],0
2580 jne long_immediate_not_encodable
2581 call operand_64bit
2582 push ebx
2583 call get_simm32
2584 cmp [value_type],4
2585 jae long_immediate_not_encodable
2586 jmp imul_reg_reg_imm_32bit_ok
2587 imul_reg_reg_imm_16bit:
2588 call operand_16bit
2589 push ebx
2590 call get_word_value
2591 pop ebx
2592 mov dx,ax
2593 cmp [value_type],0
2594 jne imul_reg_reg_imm_16bit_store
2595 cmp [size_declared],0
2596 jne imul_reg_reg_imm_16bit_store
2597 cmp ax,-80h
2598 jl imul_reg_reg_imm_16bit_store
2599 cmp ax,80h
2600 jl imul_reg_reg_imm_8bit_store
2601 imul_reg_reg_imm_16bit_store:
2602 mov [base_code],69h
2603 call store_nomem_instruction
2604 mov ax,dx
2605 call mark_relocation
2606 stos word [edi]
2607 jmp instruction_assembled
2608 imul_reg_reg_imm_32bit:
2609 call operand_32bit
2610 push ebx
2611 call get_dword_value
2612 imul_reg_reg_imm_32bit_ok:
2613 pop ebx
2614 mov edx,eax
2615 cmp [value_type],0
2616 jne imul_reg_reg_imm_32bit_store
2617 cmp [size_declared],0
2618 jne imul_reg_reg_imm_32bit_store
2619 cmp eax,-80h
2620 jl imul_reg_reg_imm_32bit_store
2621 cmp eax,80h
2622 jl imul_reg_reg_imm_8bit_store
2623 imul_reg_reg_imm_32bit_store:
2624 mov [base_code],69h
2625 call store_nomem_instruction
2626 mov eax,edx
2627 call mark_relocation
2628 stos dword [edi]
2629 jmp instruction_assembled
2630 imul_reg_reg_imm_8bit_store:
2631 mov [base_code],6Bh
2632 call store_nomem_instruction
2633 mov al,dl
2634 stos byte [edi]
2635 jmp instruction_assembled
2636 in_instruction:
2637 lods byte [esi]
2638 call get_size_operator
2639 cmp al,10h
2640 jne invalid_operand
2641 lods byte [esi]
2642 call convert_register
2643 or al,al
2644 jnz invalid_operand
2645 lods byte [esi]
2646 cmp al,','
2647 jne invalid_operand
2648 mov al,ah
2649 push eax
2650 mov [operand_size],0
2651 lods byte [esi]
2652 call get_size_operator
2653 cmp al,'('
2654 je in_imm
2655 cmp al,10h
2656 je in_reg
2657 jmp invalid_operand
2658 in_reg:
2659 lods byte [esi]
2660 cmp al,22h
2661 jne invalid_operand
2662 pop eax
2663 cmp al,1
2664 je in_al_dx
2665 cmp al,2
2666 je in_ax_dx
2667 cmp al,4
2668 jne invalid_operand_size
2669 in_ax_dx:
2670 call operand_autodetect
2671 mov [base_code],0EDh
2672 call store_instruction_code
2673 jmp instruction_assembled
2674 in_al_dx:
2675 mov al,0ECh
2676 stos byte [edi]
2677 jmp instruction_assembled
2678 in_imm:
2679 mov al,[operand_size]
2680 or al,al
2681 jz in_imm_size_ok
2682 cmp al,1
2683 jne invalid_operand_size
2684 in_imm_size_ok:
2685 call get_byte_value
2686 mov dl,al
2687 pop eax
2688 cmp al,1
2689 je in_al_imm
2690 cmp al,2
2691 je in_ax_imm
2692 cmp al,4
2693 jne invalid_operand_size
2694 in_ax_imm:
2695 call operand_autodetect
2696 mov [base_code],0E5h
2697 call store_instruction_code
2698 mov al,dl
2699 stos byte [edi]
2700 jmp instruction_assembled
2701 in_al_imm:
2702 mov al,0E4h
2703 stos byte [edi]
2704 mov al,dl
2705 stos byte [edi]
2706 jmp instruction_assembled
2707 out_instruction:
2708 lods byte [esi]
2709 call get_size_operator
2710 cmp al,'('
2711 je out_imm
2712 cmp al,10h
2713 jne invalid_operand
2714 lods byte [esi]
2715 cmp al,22h
2716 jne invalid_operand
2717 lods byte [esi]
2718 cmp al,','
2719 jne invalid_operand
2720 mov [operand_size],0
2721 lods byte [esi]
2722 call get_size_operator
2723 cmp al,10h
2724 jne invalid_operand
2725 lods byte [esi]
2726 call convert_register
2727 or al,al
2728 jnz invalid_operand
2729 mov al,ah
2730 cmp al,1
2731 je out_dx_al
2732 cmp al,2
2733 je out_dx_ax
2734 cmp al,4
2735 jne invalid_operand_size
2736 out_dx_ax:
2737 call operand_autodetect
2738 mov [base_code],0EFh
2739 call store_instruction_code
2740 jmp instruction_assembled
2741 out_dx_al:
2742 mov al,0EEh
2743 stos byte [edi]
2744 jmp instruction_assembled
2745 out_imm:
2746 mov al,[operand_size]
2747 or al,al
2748 jz out_imm_size_ok
2749 cmp al,1
2750 jne invalid_operand_size
2751 out_imm_size_ok:
2752 call get_byte_value
2753 mov dl,al
2754 lods byte [esi]
2755 cmp al,','
2756 jne invalid_operand
2757 mov [operand_size],0
2758 lods byte [esi]
2759 call get_size_operator
2760 cmp al,10h
2761 jne invalid_operand
2762 lods byte [esi]
2763 call convert_register
2764 or al,al
2765 jnz invalid_operand
2766 mov al,ah
2767 cmp al,1
2768 je out_imm_al
2769 cmp al,2
2770 je out_imm_ax
2771 cmp al,4
2772 jne invalid_operand_size
2773 out_imm_ax:
2774 call operand_autodetect
2775 mov [base_code],0E7h
2776 call store_instruction_code
2777 mov al,dl
2778 stos byte [edi]
2779 jmp instruction_assembled
2780 out_imm_al:
2781 mov al,0E6h
2782 stos byte [edi]
2783 mov al,dl
2784 stos byte [edi]
2785 jmp instruction_assembled
2786
2787 call_instruction:
2788 mov [postbyte_register],10b
2789 mov [base_code],0E8h
2790 mov [extended_code],9Ah
2791 jmp process_jmp
2792 jmp_instruction:
2793 mov [postbyte_register],100b
2794 mov [base_code],0E9h
2795 mov [extended_code],0EAh
2796 process_jmp:
2797 lods byte [esi]
2798 call get_jump_operator
2799 call get_size_operator
2800 cmp al,'('
2801 je jmp_imm
2802 mov [base_code],0FFh
2803 cmp al,10h
2804 je jmp_reg
2805 cmp al,'['
2806 jne invalid_operand
2807 jmp_mem:
2808 cmp [jump_type],1
2809 je illegal_instruction
2810 call get_address
2811 mov edx,eax
2812 mov al,[operand_size]
2813 or al,al
2814 jz jmp_mem_size_not_specified
2815 cmp al,2
2816 je jmp_mem_16bit
2817 cmp al,4
2818 je jmp_mem_32bit
2819 cmp al,6
2820 je jmp_mem_48bit
2821 cmp al,8
2822 je jmp_mem_64bit
2823 cmp al,10
2824 je jmp_mem_80bit
2825 jmp invalid_operand_size
2826 jmp_mem_size_not_specified:
2827 cmp [jump_type],3
2828 je jmp_mem_far
2829 cmp [jump_type],2
2830 je jmp_mem_near
2831 call recoverable_unknown_size
2832 jmp_mem_near:
2833 cmp [code_type],16
2834 je jmp_mem_16bit
2835 cmp [code_type],32
2836 je jmp_mem_near_32bit
2837 jmp_mem_64bit:
2838 cmp [jump_type],3
2839 je invalid_operand_size
2840 cmp [code_type],64
2841 jne illegal_instruction
2842 jmp instruction_ready
2843 jmp_mem_far:
2844 cmp [code_type],16
2845 je jmp_mem_far_32bit
2846 jmp_mem_48bit:
2847 call operand_32bit
2848 jmp_mem_far_store:
2849 cmp [jump_type],2
2850 je invalid_operand_size
2851 inc [postbyte_register]
2852 jmp instruction_ready
2853 jmp_mem_80bit:
2854 call operand_64bit
2855 jmp jmp_mem_far_store
2856 jmp_mem_far_32bit:
2857 call operand_16bit
2858 jmp jmp_mem_far_store
2859 jmp_mem_32bit:
2860 cmp [jump_type],3
2861 je jmp_mem_far_32bit
2862 cmp [jump_type],2
2863 je jmp_mem_near_32bit
2864 cmp [code_type],16
2865 je jmp_mem_far_32bit
2866 jmp_mem_near_32bit:
2867 cmp [code_type],64
2868 je illegal_instruction
2869 call operand_32bit
2870 jmp instruction_ready
2871 jmp_mem_16bit:
2872 cmp [jump_type],3
2873 je invalid_operand_size
2874 call operand_16bit
2875 jmp instruction_ready
2876 jmp_reg:
2877 test [jump_type],1
2878 jnz invalid_operand
2879 lods byte [esi]
2880 call convert_register
2881 mov bl,al
2882 mov al,ah
2883 cmp al,2
2884 je jmp_reg_16bit
2885 cmp al,4
2886 je jmp_reg_32bit
2887 cmp al,8
2888 jne invalid_operand_size
2889 jmp_reg_64bit:
2890 cmp [code_type],64
2891 jne illegal_instruction
2892 jmp nomem_instruction_ready
2893 jmp_reg_32bit:
2894 cmp [code_type],64
2895 je illegal_instruction
2896 call operand_32bit
2897 jmp nomem_instruction_ready
2898 jmp_reg_16bit:
2899 call operand_16bit
2900 jmp nomem_instruction_ready
2901 jmp_imm:
2902 cmp byte [esi],'.'
2903 je invalid_value
2904 mov ebx,esi
2905 dec esi
2906 call skip_symbol
2907 xchg esi,ebx
2908 cmp byte [ebx],':'
2909 je jmp_far
2910 cmp [jump_type],3
2911 je invalid_operand
2912 jmp_near:
2913 mov al,[operand_size]
2914 cmp al,2
2915 je jmp_imm_16bit
2916 cmp al,4
2917 je jmp_imm_32bit
2918 cmp al,8
2919 je jmp_imm_64bit
2920 or al,al
2921 jnz invalid_operand_size
2922 cmp [code_type],16
2923 je jmp_imm_16bit
2924 cmp [code_type],64
2925 je jmp_imm_64bit
2926 jmp_imm_32bit:
2927 cmp [code_type],64
2928 je invalid_operand_size
2929 call get_address_dword_value
2930 cmp [code_type],16
2931 jne jmp_imm_32bit_prefix_ok
2932 mov byte [edi],66h
2933 inc edi
2934 jmp_imm_32bit_prefix_ok:
2935 call calculate_jump_offset
2936 cdq
2937 call check_for_short_jump
2938 jc jmp_short
2939 jmp_imm_32bit_store:
2940 mov edx,eax
2941 sub edx,3
2942 jno jmp_imm_32bit_ok
2943 cmp [code_type],64
2944 je jump_out_of_range
2945 jmp_imm_32bit_ok:
2946 mov al,[base_code]
2947 stos byte [edi]
2948 mov eax,edx
2949 call mark_relocation
2950 stos dword [edi]
2951 jmp instruction_assembled
2952 jmp_imm_64bit:
2953 cmp [code_type],64
2954 jne invalid_operand_size
2955 call get_address_qword_value
2956 call calculate_jump_offset
2957 mov ecx,edx
2958 cdq
2959 cmp edx,ecx
2960 jne jump_out_of_range
2961 call check_for_short_jump
2962 jnc jmp_imm_32bit_store
2963 jmp_short:
2964 mov ah,al
2965 mov al,0EBh
2966 stos word [edi]
2967 jmp instruction_assembled
2968 jmp_imm_16bit:
2969 call get_address_word_value
2970 cmp [code_type],16
2971 je jmp_imm_16bit_prefix_ok
2972 mov byte [edi],66h
2973 inc edi
2974 jmp_imm_16bit_prefix_ok:
2975 call calculate_jump_offset
2976 cwde
2977 cdq
2978 call check_for_short_jump
2979 jc jmp_short
2980 cmp [value_type],0
2981 jne invalid_use_of_symbol
2982 mov edx,eax
2983 dec edx
2984 mov al,[base_code]
2985 stos byte [edi]
2986 mov eax,edx
2987 stos word [edi]
2988 jmp instruction_assembled
2989 calculate_jump_offset:
2990 add edi,2
2991 mov ebp,[addressing_space]
2992 call calculate_relative_offset
2993 sub edi,2
2994 ret
2995 check_for_short_jump:
2996 cmp [jump_type],1
2997 je forced_short
2998 ja no_short_jump
2999 cmp [base_code],0E8h
3000 je no_short_jump
3001 cmp [value_type],0
3002 jne no_short_jump
3003 cmp eax,80h
3004 jb short_jump
3005 cmp eax,-80h
3006 jae short_jump
3007 no_short_jump:
3008 clc
3009 ret
3010 forced_short:
3011 cmp [base_code],0E8h
3012 je illegal_instruction
3013 cmp [next_pass_needed],0
3014 jne jmp_short_value_type_ok
3015 cmp [value_type],0
3016 jne invalid_use_of_symbol
3017 jmp_short_value_type_ok:
3018 cmp eax,-80h
3019 jae short_jump
3020 cmp eax,80h
3021 jae jump_out_of_range
3022 short_jump:
3023 stc
3024 ret
3025 jump_out_of_range:
3026 cmp [error_line],0
3027 jne instruction_assembled
3028 mov eax,[current_line]
3029 mov [error_line],eax
3030 mov [error],relative_jump_out_of_range
3031 jmp instruction_assembled
3032 jmp_far:
3033 cmp [jump_type],2
3034 je invalid_operand
3035 cmp [code_type],64
3036 je illegal_instruction
3037 mov al,[extended_code]
3038 mov [base_code],al
3039 call get_word_value
3040 push eax
3041 inc esi
3042 lods byte [esi]
3043 cmp al,'('
3044 jne invalid_operand
3045 mov al,[value_type]
3046 push eax [symbol_identifier]
3047 cmp byte [esi],'.'
3048 je invalid_value
3049 mov al,[operand_size]
3050 cmp al,4
3051 je jmp_far_16bit
3052 cmp al,6
3053 je jmp_far_32bit
3054 or al,al
3055 jnz invalid_operand_size
3056 cmp [code_type],16
3057 jne jmp_far_32bit
3058 jmp_far_16bit:
3059 call get_word_value
3060 mov ebx,eax
3061 call operand_16bit
3062 call store_instruction_code
3063 mov ax,bx
3064 call mark_relocation
3065 stos word [edi]
3066 jmp_far_segment:
3067 pop [symbol_identifier] eax
3068 mov [value_type],al
3069 pop eax
3070 call mark_relocation
3071 stos word [edi]
3072 jmp instruction_assembled
3073 jmp_far_32bit:
3074 call get_dword_value
3075 mov ebx,eax
3076 call operand_32bit
3077 call store_instruction_code
3078 mov eax,ebx
3079 call mark_relocation
3080 stos dword [edi]
3081 jmp jmp_far_segment
3082 conditional_jump:
3083 mov [base_code],al
3084 lods byte [esi]
3085 call get_jump_operator
3086 cmp [jump_type],3
3087 je invalid_operand
3088 call get_size_operator
3089 cmp al,'('
3090 jne invalid_operand
3091 cmp byte [esi],'.'
3092 je invalid_value
3093 mov al,[operand_size]
3094 cmp al,2
3095 je conditional_jump_16bit
3096 cmp al,4
3097 je conditional_jump_32bit
3098 cmp al,8
3099 je conditional_jump_64bit
3100 or al,al
3101 jnz invalid_operand_size
3102 cmp [code_type],16
3103 je conditional_jump_16bit
3104 cmp [code_type],64
3105 je conditional_jump_64bit
3106 conditional_jump_32bit:
3107 cmp [code_type],64
3108 je invalid_operand_size
3109 call get_address_dword_value
3110 cmp [code_type],16
3111 jne conditional_jump_32bit_prefix_ok
3112 mov byte [edi],66h
3113 inc edi
3114 conditional_jump_32bit_prefix_ok:
3115 call calculate_jump_offset
3116 cdq
3117 call check_for_short_jump
3118 jc conditional_jump_short
3119 conditional_jump_32bit_store:
3120 mov edx,eax
3121 sub edx,4
3122 jno conditional_jump_32bit_range_ok
3123 cmp [code_type],64
3124 je jump_out_of_range
3125 conditional_jump_32bit_range_ok:
3126 mov ah,[base_code]
3127 add ah,10h
3128 mov al,0Fh
3129 stos word [edi]
3130 mov eax,edx
3131 call mark_relocation
3132 stos dword [edi]
3133 jmp instruction_assembled
3134 conditional_jump_64bit:
3135 cmp [code_type],64
3136 jne invalid_operand_size
3137 call get_address_qword_value
3138 call calculate_jump_offset
3139 mov ecx,edx
3140 cdq
3141 cmp edx,ecx
3142 jne jump_out_of_range
3143 call check_for_short_jump
3144 jnc conditional_jump_32bit_store
3145 conditional_jump_short:
3146 mov ah,al
3147 mov al,[base_code]
3148 stos word [edi]
3149 jmp instruction_assembled
3150 conditional_jump_16bit:
3151 call get_address_word_value
3152 cmp [code_type],16
3153 je conditional_jump_16bit_prefix_ok
3154 mov byte [edi],66h
3155 inc edi
3156 conditional_jump_16bit_prefix_ok:
3157 call calculate_jump_offset
3158 cwde
3159 cdq
3160 call check_for_short_jump
3161 jc conditional_jump_short
3162 cmp [value_type],0
3163 jne invalid_use_of_symbol
3164 mov edx,eax
3165 sub dx,2
3166 mov ah,[base_code]
3167 add ah,10h
3168 mov al,0Fh
3169 stos word [edi]
3170 mov eax,edx
3171 stos word [edi]
3172 jmp instruction_assembled
3173 loop_instruction_16bit:
3174 cmp [code_type],64
3175 je illegal_instruction
3176 cmp [code_type],16
3177 je loop_instruction
3178 mov [operand_prefix],67h
3179 jmp loop_instruction
3180 loop_instruction_32bit:
3181 cmp [code_type],32
3182 je loop_instruction
3183 mov [operand_prefix],67h
3184 jmp loop_instruction
3185 loop_instruction_64bit:
3186 cmp [code_type],64
3187 jne illegal_instruction
3188 loop_instruction:
3189 mov [base_code],al
3190 lods byte [esi]
3191 call get_jump_operator
3192 cmp [jump_type],1
3193 ja invalid_operand
3194 call get_size_operator
3195 cmp al,'('
3196 jne invalid_operand
3197 cmp byte [esi],'.'
3198 je invalid_value
3199 mov al,[operand_size]
3200 cmp al,2
3201 je loop_jump_16bit
3202 cmp al,4
3203 je loop_jump_32bit
3204 cmp al,8
3205 je loop_jump_64bit
3206 or al,al
3207 jnz invalid_operand_size
3208 cmp [code_type],16
3209 je loop_jump_16bit
3210 cmp [code_type],64
3211 je loop_jump_64bit
3212 loop_jump_32bit:
3213 cmp [code_type],64
3214 je invalid_operand_size
3215 call get_address_dword_value
3216 cmp [code_type],16
3217 jne loop_jump_32bit_prefix_ok
3218 mov byte [edi],66h
3219 inc edi
3220 loop_jump_32bit_prefix_ok:
3221 call loop_counter_size
3222 call calculate_jump_offset
3223 cdq
3224 make_loop_jump:
3225 call check_for_short_jump
3226 jc conditional_jump_short
3227 scas word [edi]
3228 jmp jump_out_of_range
3229 loop_counter_size:
3230 cmp [operand_prefix],0
3231 je loop_counter_size_ok
3232 push eax
3233 mov al,[operand_prefix]
3234 stos byte [edi]
3235 pop eax
3236 loop_counter_size_ok:
3237 ret
3238 loop_jump_64bit:
3239 cmp [code_type],64
3240 jne invalid_operand_size
3241 call get_address_qword_value
3242 call loop_counter_size
3243 call calculate_jump_offset
3244 mov ecx,edx
3245 cdq
3246 cmp edx,ecx
3247 jne jump_out_of_range
3248 jmp make_loop_jump
3249 loop_jump_16bit:
3250 call get_address_word_value
3251 cmp [code_type],16
3252 je loop_jump_16bit_prefix_ok
3253 mov byte [edi],66h
3254 inc edi
3255 loop_jump_16bit_prefix_ok:
3256 call loop_counter_size
3257 call calculate_jump_offset
3258 cwde
3259 cdq
3260 jmp make_loop_jump
3261
3262 movs_instruction:
3263 lods byte [esi]
3264 call get_size_operator
3265 cmp al,'['
3266 jne invalid_operand
3267 call get_address
3268 or eax,eax
3269 jnz invalid_address
3270 or bl,ch
3271 jnz invalid_address
3272 cmp [segment_register],1
3273 ja invalid_address
3274 push ebx
3275 lods byte [esi]
3276 cmp al,','
3277 jne invalid_operand
3278 lods byte [esi]
3279 call get_size_operator
3280 cmp al,'['
3281 jne invalid_operand
3282 call get_address
3283 pop edx
3284 or eax,eax
3285 jnz invalid_address
3286 or bl,ch
3287 jnz invalid_address
3288 mov al,dh
3289 mov ah,bh
3290 shr al,4
3291 shr ah,4
3292 cmp al,ah
3293 jne address_sizes_do_not_agree
3294 and bh,111b
3295 and dh,111b
3296 cmp bh,6
3297 jne invalid_address
3298 cmp dh,7
3299 jne invalid_address
3300 cmp al,2
3301 je movs_address_16bit
3302 cmp al,4
3303 je movs_address_32bit
3304 cmp [code_type],64
3305 jne invalid_address_size
3306 jmp movs_store
3307 movs_address_32bit:
3308 call address_32bit_prefix
3309 jmp movs_store
3310 movs_address_16bit:
3311 cmp [code_type],64
3312 je invalid_address_size
3313 call address_16bit_prefix
3314 movs_store:
3315 xor ebx,ebx
3316 call store_segment_prefix_if_necessary
3317 mov al,0A4h
3318 movs_check_size:
3319 mov bl,[operand_size]
3320 cmp bl,1
3321 je simple_instruction
3322 inc al
3323 cmp bl,2
3324 je simple_instruction_16bit
3325 cmp bl,4
3326 je simple_instruction_32bit
3327 cmp bl,8
3328 je simple_instruction_64bit
3329 or bl,bl
3330 jnz invalid_operand_size
3331 call recoverable_unknown_size
3332 jmp simple_instruction
3333 lods_instruction:
3334 lods byte [esi]
3335 call get_size_operator
3336 cmp al,'['
3337 jne invalid_operand
3338 call get_address
3339 or eax,eax
3340 jnz invalid_address
3341 or bl,ch
3342 jnz invalid_address
3343 cmp bh,26h
3344 je lods_address_16bit
3345 cmp bh,46h
3346 je lods_address_32bit
3347 cmp bh,86h
3348 jne invalid_address
3349 cmp [code_type],64
3350 jne invalid_address_size
3351 jmp lods_store
3352 lods_address_32bit:
3353 call address_32bit_prefix
3354 jmp lods_store
3355 lods_address_16bit:
3356 cmp [code_type],64
3357 je invalid_address_size
3358 call address_16bit_prefix
3359 lods_store:
3360 xor ebx,ebx
3361 call store_segment_prefix_if_necessary
3362 mov al,0ACh
3363 jmp movs_check_size
3364 stos_instruction:
3365 mov [base_code],al
3366 lods byte [esi]
3367 call get_size_operator
3368 cmp al,'['
3369 jne invalid_operand
3370 call get_address
3371 or eax,eax
3372 jnz invalid_address
3373 or bl,ch
3374 jnz invalid_address
3375 cmp bh,27h
3376 je stos_address_16bit
3377 cmp bh,47h
3378 je stos_address_32bit
3379 cmp bh,87h
3380 jne invalid_address
3381 cmp [code_type],64
3382 jne invalid_address_size
3383 jmp stos_store
3384 stos_address_32bit:
3385 call address_32bit_prefix
3386 jmp stos_store
3387 stos_address_16bit:
3388 cmp [code_type],64
3389 je invalid_address_size
3390 call address_16bit_prefix
3391 stos_store:
3392 cmp [segment_register],1
3393 ja invalid_address
3394 mov al,[base_code]
3395 jmp movs_check_size
3396 cmps_instruction:
3397 lods byte [esi]
3398 call get_size_operator
3399 cmp al,'['
3400 jne invalid_operand
3401 call get_address
3402 or eax,eax
3403 jnz invalid_address
3404 or bl,ch
3405 jnz invalid_address
3406 mov al,[segment_register]
3407 push eax ebx
3408 lods byte [esi]
3409 cmp al,','
3410 jne invalid_operand
3411 lods byte [esi]
3412 call get_size_operator
3413 cmp al,'['
3414 jne invalid_operand
3415 call get_address
3416 or eax,eax
3417 jnz invalid_address
3418 or bl,ch
3419 jnz invalid_address
3420 pop edx eax
3421 cmp [segment_register],1
3422 ja invalid_address
3423 mov [segment_register],al
3424 mov al,dh
3425 mov ah,bh
3426 shr al,4
3427 shr ah,4
3428 cmp al,ah
3429 jne address_sizes_do_not_agree
3430 and bh,111b
3431 and dh,111b
3432 cmp bh,7
3433 jne invalid_address
3434 cmp dh,6
3435 jne invalid_address
3436 cmp al,2
3437 je cmps_address_16bit
3438 cmp al,4
3439 je cmps_address_32bit
3440 cmp [code_type],64
3441 jne invalid_address_size
3442 jmp cmps_store
3443 cmps_address_32bit:
3444 call address_32bit_prefix
3445 jmp cmps_store
3446 cmps_address_16bit:
3447 cmp [code_type],64
3448 je invalid_address_size
3449 call address_16bit_prefix
3450 cmps_store:
3451 xor ebx,ebx
3452 call store_segment_prefix_if_necessary
3453 mov al,0A6h
3454 jmp movs_check_size
3455 ins_instruction:
3456 lods byte [esi]
3457 call get_size_operator
3458 cmp al,'['
3459 jne invalid_operand
3460 call get_address
3461 or eax,eax
3462 jnz invalid_address
3463 or bl,ch
3464 jnz invalid_address
3465 cmp bh,27h
3466 je ins_address_16bit
3467 cmp bh,47h
3468 je ins_address_32bit
3469 cmp bh,87h
3470 jne invalid_address
3471 cmp [code_type],64
3472 jne invalid_address_size
3473 jmp ins_store
3474 ins_address_32bit:
3475 call address_32bit_prefix
3476 jmp ins_store
3477 ins_address_16bit:
3478 cmp [code_type],64
3479 je invalid_address_size
3480 call address_16bit_prefix
3481 ins_store:
3482 cmp [segment_register],1
3483 ja invalid_address
3484 lods byte [esi]
3485 cmp al,','
3486 jne invalid_operand
3487 lods byte [esi]
3488 cmp al,10h
3489 jne invalid_operand
3490 lods byte [esi]
3491 cmp al,22h
3492 jne invalid_operand
3493 mov al,6Ch
3494 ins_check_size:
3495 cmp [operand_size],8
3496 jne movs_check_size
3497 jmp invalid_operand_size
3498 outs_instruction:
3499 lods byte [esi]
3500 cmp al,10h
3501 jne invalid_operand
3502 lods byte [esi]
3503 cmp al,22h
3504 jne invalid_operand
3505 lods byte [esi]
3506 cmp al,','
3507 jne invalid_operand
3508 lods byte [esi]
3509 call get_size_operator
3510 cmp al,'['
3511 jne invalid_operand
3512 call get_address
3513 or eax,eax
3514 jnz invalid_address
3515 or bl,ch
3516 jnz invalid_address
3517 cmp bh,26h
3518 je outs_address_16bit
3519 cmp bh,46h
3520 je outs_address_32bit
3521 cmp bh,86h
3522 jne invalid_address
3523 cmp [code_type],64
3524 jne invalid_address_size
3525 jmp outs_store
3526 outs_address_32bit:
3527 call address_32bit_prefix
3528 jmp outs_store
3529 outs_address_16bit:
3530 cmp [code_type],64
3531 je invalid_address_size
3532 call address_16bit_prefix
3533 outs_store:
3534 xor ebx,ebx
3535 call store_segment_prefix_if_necessary
3536 mov al,6Eh
3537 jmp ins_check_size
3538 xlat_instruction:
3539 lods byte [esi]
3540 call get_size_operator
3541 cmp al,'['
3542 jne invalid_operand
3543 call get_address
3544 or eax,eax
3545 jnz invalid_address
3546 or bl,ch
3547 jnz invalid_address
3548 cmp bh,23h
3549 je xlat_address_16bit
3550 cmp bh,43h
3551 je xlat_address_32bit
3552 cmp bh,83h
3553 jne invalid_address
3554 cmp [code_type],64
3555 jne invalid_address_size
3556 jmp xlat_store
3557 xlat_address_32bit:
3558 call address_32bit_prefix
3559 jmp xlat_store
3560 xlat_address_16bit:
3561 cmp [code_type],64
3562 je invalid_address_size
3563 call address_16bit_prefix
3564 xlat_store:
3565 call store_segment_prefix_if_necessary
3566 mov al,0D7h
3567 cmp [operand_size],1
3568 jbe simple_instruction
3569 jmp invalid_operand_size
3570
3571 pm_word_instruction:
3572 mov ah,al
3573 shr ah,4
3574 and al,111b
3575 mov [base_code],0Fh
3576 mov [extended_code],ah
3577 mov [postbyte_register],al
3578 lods byte [esi]
3579 call get_size_operator
3580 cmp al,10h
3581 je pm_reg
3582 pm_mem:
3583 cmp al,'['
3584 jne invalid_operand
3585 call get_address
3586 mov al,[operand_size]
3587 cmp al,2
3588 je pm_mem_store
3589 or al,al
3590 jnz invalid_operand_size
3591 pm_mem_store:
3592 jmp instruction_ready
3593 pm_reg:
3594 lods byte [esi]
3595 call convert_register
3596 mov bl,al
3597 cmp ah,2
3598 jne invalid_operand_size
3599 jmp nomem_instruction_ready
3600 pm_store_word_instruction:
3601 mov ah,al
3602 shr ah,4
3603 and al,111b
3604 mov [base_code],0Fh
3605 mov [extended_code],ah
3606 mov [postbyte_register],al
3607 lods byte [esi]
3608 call get_size_operator
3609 cmp al,10h
3610 jne pm_mem
3611 lods byte [esi]
3612 call convert_register
3613 mov bl,al
3614 mov al,ah
3615 call operand_autodetect
3616 jmp nomem_instruction_ready
3617 lgdt_instruction:
3618 mov [base_code],0Fh
3619 mov [extended_code],1
3620 mov [postbyte_register],al
3621 lods byte [esi]
3622 call get_size_operator
3623 cmp al,'['
3624 jne invalid_operand
3625 call get_address
3626 mov al,[operand_size]
3627 cmp al,6
3628 je lgdt_mem_48bit
3629 cmp al,10
3630 je lgdt_mem_80bit
3631 or al,al
3632 jnz invalid_operand_size
3633 jmp lgdt_mem_store
3634 lgdt_mem_80bit:
3635 cmp [code_type],64
3636 jne illegal_instruction
3637 jmp lgdt_mem_store
3638 lgdt_mem_48bit:
3639 cmp [code_type],64
3640 je illegal_instruction
3641 cmp [postbyte_register],2
3642 jb lgdt_mem_store
3643 call operand_32bit
3644 lgdt_mem_store:
3645 jmp instruction_ready
3646 lar_instruction:
3647 mov [extended_code],al
3648 mov [base_code],0Fh
3649 lods byte [esi]
3650 call get_size_operator
3651 cmp al,10h
3652 jne invalid_operand
3653 lods byte [esi]
3654 call convert_register
3655 mov [postbyte_register],al
3656 lods byte [esi]
3657 cmp al,','
3658 jne invalid_operand
3659 xor al,al
3660 xchg al,[operand_size]
3661 call operand_autodetect
3662 lods byte [esi]
3663 call get_size_operator
3664 cmp al,10h
3665 je lar_reg_reg
3666 cmp al,'['
3667 jne invalid_operand
3668 call get_address
3669 mov al,[operand_size]
3670 or al,al
3671 jz lar_reg_mem
3672 cmp al,2
3673 jne invalid_operand_size
3674 lar_reg_mem:
3675 jmp instruction_ready
3676 lar_reg_reg:
3677 lods byte [esi]
3678 call convert_register
3679 cmp ah,2
3680 jne invalid_operand_size
3681 mov bl,al
3682 jmp nomem_instruction_ready
3683 invlpg_instruction:
3684 mov [base_code],0Fh
3685 mov [extended_code],1
3686 mov [postbyte_register],7
3687 lods byte [esi]
3688 call get_size_operator
3689 cmp al,'['
3690 jne invalid_operand
3691 call get_address
3692 jmp instruction_ready
3693 swapgs_instruction:
3694 cmp [code_type],64
3695 jne illegal_instruction
3696 rdtscp_instruction:
3697 mov [base_code],0Fh
3698 mov [extended_code],1
3699 mov [postbyte_register],7
3700 mov bl,al
3701 jmp nomem_instruction_ready
3702
3703 basic_486_instruction:
3704 mov [base_code],0Fh
3705 mov [extended_code],al
3706 lods byte [esi]
3707 call get_size_operator
3708 cmp al,10h
3709 je basic_486_reg
3710 cmp al,'['
3711 jne invalid_operand
3712 call get_address
3713 push edx ebx ecx
3714 lods byte [esi]
3715 cmp al,','
3716 jne invalid_operand
3717 lods byte [esi]
3718 call get_size_operator
3719 cmp al,10h
3720 jne invalid_operand
3721 lods byte [esi]
3722 call convert_register
3723 mov [postbyte_register],al
3724 pop ecx ebx edx
3725 mov al,ah
3726 cmp al,1
3727 je basic_486_mem_reg_8bit
3728 call operand_autodetect
3729 inc [extended_code]
3730 basic_486_mem_reg_8bit:
3731 jmp instruction_ready
3732 basic_486_reg:
3733 lods byte [esi]
3734 call convert_register
3735 mov [postbyte_register],al
3736 lods byte [esi]
3737 cmp al,','
3738 jne invalid_operand
3739 lods byte [esi]
3740 call get_size_operator
3741 cmp al,10h
3742 jne invalid_operand
3743 lods byte [esi]
3744 call convert_register
3745 mov bl,[postbyte_register]
3746 mov [postbyte_register],al
3747 mov al,ah
3748 cmp al,1
3749 je basic_486_reg_reg_8bit
3750 call operand_autodetect
3751 inc [extended_code]
3752 basic_486_reg_reg_8bit:
3753 jmp nomem_instruction_ready
3754 bswap_instruction:
3755 lods byte [esi]
3756 call get_size_operator
3757 cmp al,10h
3758 jne invalid_operand
3759 lods byte [esi]
3760 call convert_register
3761 test al,1000b
3762 jz bswap_reg_code_ok
3763 or [rex_prefix],41h
3764 and al,111b
3765 bswap_reg_code_ok:
3766 add al,0C8h
3767 mov [extended_code],al
3768 mov [base_code],0Fh
3769 cmp ah,8
3770 je bswap_reg64
3771 cmp ah,4
3772 jne invalid_operand_size
3773 call operand_32bit
3774 call store_instruction_code
3775 jmp instruction_assembled
3776 bswap_reg64:
3777 call operand_64bit
3778 call store_instruction_code
3779 jmp instruction_assembled
3780 cmpxchgx_instruction:
3781 mov [base_code],0Fh
3782 mov [extended_code],0C7h
3783 mov [postbyte_register],al
3784 lods byte [esi]
3785 call get_size_operator
3786 cmp al,'['
3787 jne invalid_operand
3788 call get_address
3789 mov ah,1
3790 xchg [postbyte_register],ah
3791 mov al,[operand_size]
3792 or al,al
3793 jz cmpxchgx_size_ok
3794 cmp al,ah
3795 jne invalid_operand_size
3796 cmpxchgx_size_ok:
3797 cmp ah,16
3798 jne cmpxchgx_store
3799 call operand_64bit
3800 cmpxchgx_store:
3801 jmp instruction_ready
3802 nop_instruction:
3803 mov ah,[esi]
3804 cmp ah,10h
3805 je extended_nop
3806 cmp ah,11h
3807 je extended_nop
3808 cmp ah,'['
3809 je extended_nop
3810 stos byte [edi]
3811 jmp instruction_assembled
3812 extended_nop:
3813 mov [base_code],0Fh
3814 mov [extended_code],1Fh
3815 mov [postbyte_register],0
3816 lods byte [esi]
3817 call get_size_operator
3818 cmp al,10h
3819 je extended_nop_reg
3820 cmp al,'['
3821 jne invalid_operand
3822 call get_address
3823 mov al,[operand_size]
3824 or al,al
3825 jz extended_nop_store
3826 call operand_autodetect
3827 extended_nop_store:
3828 jmp instruction_ready
3829 extended_nop_reg:
3830 lods byte [esi]
3831 call convert_register
3832 mov bl,al
3833 mov al,ah
3834 call operand_autodetect
3835 jmp nomem_instruction_ready
3836
3837 basic_fpu_instruction:
3838 mov [postbyte_register],al
3839 mov [base_code],0D8h
3840 lods byte [esi]
3841 call get_size_operator
3842 cmp al,10h
3843 je basic_fpu_streg
3844 cmp al,'['
3845 je basic_fpu_mem
3846 dec esi
3847 mov ah,[postbyte_register]
3848 cmp ah,2
3849 jb invalid_operand
3850 cmp ah,3
3851 ja invalid_operand
3852 mov bl,1
3853 jmp nomem_instruction_ready
3854 basic_fpu_mem:
3855 call get_address
3856 mov al,[operand_size]
3857 cmp al,4
3858 je basic_fpu_mem_32bit
3859 cmp al,8
3860 je basic_fpu_mem_64bit
3861 or al,al
3862 jnz invalid_operand_size
3863 call recoverable_unknown_size
3864 basic_fpu_mem_32bit:
3865 jmp instruction_ready
3866 basic_fpu_mem_64bit:
3867 mov [base_code],0DCh
3868 jmp instruction_ready
3869 basic_fpu_streg:
3870 lods byte [esi]
3871 call convert_fpu_register
3872 mov bl,al
3873 mov ah,[postbyte_register]
3874 cmp ah,2
3875 je basic_fpu_single_streg
3876 cmp ah,3
3877 je basic_fpu_single_streg
3878 or al,al
3879 jz basic_fpu_st0
3880 test ah,110b
3881 jz basic_fpu_streg_st0
3882 xor [postbyte_register],1
3883 basic_fpu_streg_st0:
3884 lods byte [esi]
3885 cmp al,','
3886 jne invalid_operand
3887 lods byte [esi]
3888 call get_size_operator
3889 cmp al,10h
3890 jne invalid_operand
3891 lods byte [esi]
3892 call convert_fpu_register
3893 or al,al
3894 jnz invalid_operand
3895 mov [base_code],0DCh
3896 jmp nomem_instruction_ready
3897 basic_fpu_st0:
3898 lods byte [esi]
3899 cmp al,','
3900 jne invalid_operand
3901 lods byte [esi]
3902 call get_size_operator
3903 cmp al,10h
3904 jne invalid_operand
3905 lods byte [esi]
3906 call convert_fpu_register
3907 mov bl,al
3908 basic_fpu_single_streg:
3909 mov [base_code],0D8h
3910 jmp nomem_instruction_ready
3911 simple_fpu_instruction:
3912 mov ah,al
3913 or ah,11000000b
3914 mov al,0D9h
3915 stos word [edi]
3916 jmp instruction_assembled
3917 fi_instruction:
3918 mov [postbyte_register],al
3919 lods byte [esi]
3920 call get_size_operator
3921 cmp al,'['
3922 jne invalid_operand
3923 call get_address
3924 mov al,[operand_size]
3925 cmp al,2
3926 je fi_mem_16bit
3927 cmp al,4
3928 je fi_mem_32bit
3929 or al,al
3930 jnz invalid_operand_size
3931 call recoverable_unknown_size
3932 fi_mem_32bit:
3933 mov [base_code],0DAh
3934 jmp instruction_ready
3935 fi_mem_16bit:
3936 mov [base_code],0DEh
3937 jmp instruction_ready
3938 fld_instruction:
3939 mov [postbyte_register],al
3940 lods byte [esi]
3941 call get_size_operator
3942 cmp al,10h
3943 je fld_streg
3944 cmp al,'['
3945 jne invalid_operand
3946 call get_address
3947 mov al,[operand_size]
3948 cmp al,4
3949 je fld_mem_32bit
3950 cmp al,8
3951 je fld_mem_64bit
3952 cmp al,10
3953 je fld_mem_80bit
3954 or al,al
3955 jnz invalid_operand_size
3956 call recoverable_unknown_size
3957 fld_mem_32bit:
3958 mov [base_code],0D9h
3959 jmp instruction_ready
3960 fld_mem_64bit:
3961 mov [base_code],0DDh
3962 jmp instruction_ready
3963 fld_mem_80bit:
3964 mov al,[postbyte_register]
3965 cmp al,0
3966 je fld_mem_80bit_store
3967 dec [postbyte_register]
3968 cmp al,3
3969 je fld_mem_80bit_store
3970 jmp invalid_operand_size
3971 fld_mem_80bit_store:
3972 add [postbyte_register],5
3973 mov [base_code],0DBh
3974 jmp instruction_ready
3975 fld_streg:
3976 lods byte [esi]
3977 call convert_fpu_register
3978 mov bl,al
3979 cmp [postbyte_register],2
3980 jae fst_streg
3981 mov [base_code],0D9h
3982 jmp nomem_instruction_ready
3983 fst_streg:
3984 mov [base_code],0DDh
3985 jmp nomem_instruction_ready
3986 fild_instruction:
3987 mov [postbyte_register],al
3988 lods byte [esi]
3989 call get_size_operator
3990 cmp al,'['
3991 jne invalid_operand
3992 call get_address
3993 mov al,[operand_size]
3994 cmp al,2
3995 je fild_mem_16bit
3996 cmp al,4
3997 je fild_mem_32bit
3998 cmp al,8
3999 je fild_mem_64bit
4000 or al,al
4001 jnz invalid_operand_size
4002 call recoverable_unknown_size
4003 fild_mem_32bit:
4004 mov [base_code],0DBh
4005 jmp instruction_ready
4006 fild_mem_16bit:
4007 mov [base_code],0DFh
4008 jmp instruction_ready
4009 fild_mem_64bit:
4010 mov al,[postbyte_register]
4011 cmp al,1
4012 je fisttp_64bit_store
4013 jb fild_mem_64bit_store
4014 dec [postbyte_register]
4015 cmp al,3
4016 je fild_mem_64bit_store
4017 jmp invalid_operand_size
4018 fild_mem_64bit_store:
4019 add [postbyte_register],5
4020 mov [base_code],0DFh
4021 jmp instruction_ready
4022 fisttp_64bit_store:
4023 mov [base_code],0DDh
4024 jmp instruction_ready
4025 fbld_instruction:
4026 mov [postbyte_register],al
4027 lods byte [esi]
4028 call get_size_operator
4029 cmp al,'['
4030 jne invalid_operand
4031 call get_address
4032 mov al,[operand_size]
4033 or al,al
4034 jz fbld_mem_80bit
4035 cmp al,10
4036 je fbld_mem_80bit
4037 jmp invalid_operand_size
4038 fbld_mem_80bit:
4039 mov [base_code],0DFh
4040 jmp instruction_ready
4041 faddp_instruction:
4042 mov [postbyte_register],al
4043 mov [base_code],0DEh
4044 mov edx,esi
4045 lods byte [esi]
4046 call get_size_operator
4047 cmp al,10h
4048 je faddp_streg
4049 mov esi,edx
4050 mov bl,1
4051 jmp nomem_instruction_ready
4052 faddp_streg:
4053 lods byte [esi]
4054 call convert_fpu_register
4055 mov bl,al
4056 lods byte [esi]
4057 cmp al,','
4058 jne invalid_operand
4059 lods byte [esi]
4060 call get_size_operator
4061 cmp al,10h
4062 jne invalid_operand
4063 lods byte [esi]
4064 call convert_fpu_register
4065 or al,al
4066 jnz invalid_operand
4067 jmp nomem_instruction_ready
4068 fcompp_instruction:
4069 mov ax,0D9DEh
4070 stos word [edi]
4071 jmp instruction_assembled
4072 fucompp_instruction:
4073 mov ax,0E9DAh
4074 stos word [edi]
4075 jmp instruction_assembled
4076 fxch_instruction:
4077 mov dx,01D9h
4078 jmp fpu_single_operand
4079 ffreep_instruction:
4080 mov dx,00DFh
4081 jmp fpu_single_operand
4082 ffree_instruction:
4083 mov dl,0DDh
4084 mov dh,al
4085 fpu_single_operand:
4086 mov ebx,esi
4087 lods byte [esi]
4088 call get_size_operator
4089 cmp al,10h
4090 je fpu_streg
4091 or dh,dh
4092 jz invalid_operand
4093 mov esi,ebx
4094 shl dh,3
4095 or dh,11000001b
4096 mov ax,dx
4097 stos word [edi]
4098 jmp instruction_assembled
4099 fpu_streg:
4100 lods byte [esi]
4101 call convert_fpu_register
4102 shl dh,3
4103 or dh,al
4104 or dh,11000000b
4105 mov ax,dx
4106 stos word [edi]
4107 jmp instruction_assembled
4108
4109 fstenv_instruction:
4110 mov byte [edi],9Bh
4111 inc edi
4112 fldenv_instruction:
4113 mov [base_code],0D9h
4114 jmp fpu_mem
4115 fstenv_instruction_16bit:
4116 mov byte [edi],9Bh
4117 inc edi
4118 fldenv_instruction_16bit:
4119 call operand_16bit
4120 jmp fldenv_instruction
4121 fstenv_instruction_32bit:
4122 mov byte [edi],9Bh
4123 inc edi
4124 fldenv_instruction_32bit:
4125 call operand_32bit
4126 jmp fldenv_instruction
4127 fsave_instruction_32bit:
4128 mov byte [edi],9Bh
4129 inc edi
4130 fnsave_instruction_32bit:
4131 call operand_32bit
4132 jmp fnsave_instruction
4133 fsave_instruction_16bit:
4134 mov byte [edi],9Bh
4135 inc edi
4136 fnsave_instruction_16bit:
4137 call operand_16bit
4138 jmp fnsave_instruction
4139 fsave_instruction:
4140 mov byte [edi],9Bh
4141 inc edi
4142 fnsave_instruction:
4143 mov [base_code],0DDh
4144 fpu_mem:
4145 mov [postbyte_register],al
4146 lods byte [esi]
4147 call get_size_operator
4148 cmp al,'['
4149 jne invalid_operand
4150 call get_address
4151 cmp [operand_size],0
4152 jne invalid_operand_size
4153 jmp instruction_ready
4154 fstcw_instruction:
4155 mov byte [edi],9Bh
4156 inc edi
4157 fldcw_instruction:
4158 mov [postbyte_register],al
4159 mov [base_code],0D9h
4160 lods byte [esi]
4161 call get_size_operator
4162 cmp al,'['
4163 jne invalid_operand
4164 call get_address
4165 mov al,[operand_size]
4166 or al,al
4167 jz fldcw_mem_16bit
4168 cmp al,2
4169 je fldcw_mem_16bit
4170 jmp invalid_operand_size
4171 fldcw_mem_16bit:
4172 jmp instruction_ready
4173 fstsw_instruction:
4174 mov al,9Bh
4175 stos byte [edi]
4176 fnstsw_instruction:
4177 mov [base_code],0DDh
4178 mov [postbyte_register],7
4179 lods byte [esi]
4180 call get_size_operator
4181 cmp al,10h
4182 je fstsw_reg
4183 cmp al,'['
4184 jne invalid_operand
4185 call get_address
4186 mov al,[operand_size]
4187 or al,al
4188 jz fstsw_mem_16bit
4189 cmp al,2
4190 je fstsw_mem_16bit
4191 jmp invalid_operand_size
4192 fstsw_mem_16bit:
4193 jmp instruction_ready
4194 fstsw_reg:
4195 lods byte [esi]
4196 call convert_register
4197 cmp ax,0200h
4198 jne invalid_operand
4199 mov ax,0E0DFh
4200 stos word [edi]
4201 jmp instruction_assembled
4202 finit_instruction:
4203 mov byte [edi],9Bh
4204 inc edi
4205 fninit_instruction:
4206 mov ah,al
4207 mov al,0DBh
4208 stos word [edi]
4209 jmp instruction_assembled
4210 fcmov_instruction:
4211 mov dh,0DAh
4212 jmp fcomi_streg
4213 fcomi_instruction:
4214 mov dh,0DBh
4215 jmp fcomi_streg
4216 fcomip_instruction:
4217 mov dh,0DFh
4218 fcomi_streg:
4219 mov dl,al
4220 lods byte [esi]
4221 call get_size_operator
4222 cmp al,10h
4223 jne invalid_operand
4224 lods byte [esi]
4225 call convert_fpu_register
4226 mov ah,al
4227 cmp byte [esi],','
4228 je fcomi_st0_streg
4229 add ah,dl
4230 mov al,dh
4231 stos word [edi]
4232 jmp instruction_assembled
4233 fcomi_st0_streg:
4234 or ah,ah
4235 jnz invalid_operand
4236 inc esi
4237 lods byte [esi]
4238 call get_size_operator
4239 cmp al,10h
4240 jne invalid_operand
4241 lods byte [esi]
4242 call convert_fpu_register
4243 mov ah,al
4244 add ah,dl
4245 mov al,dh
4246 stos word [edi]
4247 jmp instruction_assembled
4248
4249 basic_mmx_instruction:
4250 mov [base_code],0Fh
4251 mov [extended_code],al
4252 mmx_instruction:
4253 lods byte [esi]
4254 call get_size_operator
4255 cmp al,10h
4256 jne invalid_operand
4257 lods byte [esi]
4258 call convert_mmx_register
4259 call make_mmx_prefix
4260 mov [postbyte_register],al
4261 lods byte [esi]
4262 cmp al,','
4263 jne invalid_operand
4264 lods byte [esi]
4265 call get_size_operator
4266 cmp al,10h
4267 je mmx_mmreg_mmreg
4268 cmp al,'['
4269 jne invalid_operand
4270 mmx_mmreg_mem:
4271 call get_address
4272 jmp instruction_ready
4273 mmx_mmreg_mmreg:
4274 lods byte [esi]
4275 call convert_mmx_register
4276 mov bl,al
4277 jmp nomem_instruction_ready
4278 mmx_bit_shift_instruction:
4279 mov [base_code],0Fh
4280 mov [extended_code],al
4281 lods byte [esi]
4282 call get_size_operator
4283 cmp al,10h
4284 jne invalid_operand
4285 lods byte [esi]
4286 call convert_mmx_register
4287 call make_mmx_prefix
4288 mov [postbyte_register],al
4289 lods byte [esi]
4290 cmp al,','
4291 jne invalid_operand
4292 mov [operand_size],0
4293 lods byte [esi]
4294 call get_size_operator
4295 cmp al,10h
4296 je mmx_mmreg_mmreg
4297 cmp al,'('
4298 je mmx_ps_mmreg_imm8
4299 cmp al,'['
4300 je mmx_mmreg_mem
4301 jmp invalid_operand
4302 mmx_ps_mmreg_imm8:
4303 call get_byte_value
4304 mov byte [value],al
4305 test [operand_size],not 1
4306 jnz invalid_value
4307 mov bl,[extended_code]
4308 mov al,bl
4309 shr bl,4
4310 and al,1111b
4311 add al,70h
4312 mov [extended_code],al
4313 sub bl,0Ch
4314 shl bl,1
4315 xchg bl,[postbyte_register]
4316 call store_nomem_instruction
4317 mov al,byte [value]
4318 stos byte [edi]
4319 jmp instruction_assembled
4320 pmovmskb_instruction:
4321 mov [base_code],0Fh
4322 mov [extended_code],al
4323 lods byte [esi]
4324 call get_size_operator
4325 cmp al,10h
4326 jne invalid_operand
4327 lods byte [esi]
4328 call convert_register
4329 cmp ah,4
4330 je pmovmskb_reg_size_ok
4331 cmp [code_type],64
4332 jne invalid_operand_size
4333 cmp ah,8
4334 jnz invalid_operand_size
4335 pmovmskb_reg_size_ok:
4336 mov [postbyte_register],al
4337 mov [operand_size],0
4338 lods byte [esi]
4339 cmp al,','
4340 jne invalid_operand
4341 lods byte [esi]
4342 call get_size_operator
4343 cmp al,10h
4344 jne invalid_operand
4345 lods byte [esi]
4346 call convert_mmx_register
4347 mov bl,al
4348 call make_mmx_prefix
4349 cmp [extended_code],0C5h
4350 je mmx_nomem_imm8
4351 jmp nomem_instruction_ready
4352 mmx_imm8:
4353 push ebx ecx edx
4354 xor cl,cl
4355 xchg cl,[operand_size]
4356 lods byte [esi]
4357 cmp al,','
4358 jne invalid_operand
4359 lods byte [esi]
4360 call get_size_operator
4361 test ah,not 1
4362 jnz invalid_operand_size
4363 mov [operand_size],cl
4364 cmp al,'('
4365 jne invalid_operand
4366 call get_byte_value
4367 mov byte [value],al
4368 pop edx ecx ebx
4369 call store_instruction_with_imm8
4370 jmp instruction_assembled
4371 mmx_nomem_imm8:
4372 call store_nomem_instruction
4373 call append_imm8
4374 jmp instruction_assembled
4375 append_imm8:
4376 mov [operand_size],0
4377 lods byte [esi]
4378 cmp al,','
4379 jne invalid_operand
4380 lods byte [esi]
4381 call get_size_operator
4382 test ah,not 1
4383 jnz invalid_operand_size
4384 cmp al,'('
4385 jne invalid_operand
4386 call get_byte_value
4387 stosb
4388 ret
4389 pinsrw_instruction:
4390 mov [extended_code],al
4391 mov [base_code],0Fh
4392 lods byte [esi]
4393 call get_size_operator
4394 cmp al,10h
4395 jne invalid_operand
4396 lods byte [esi]
4397 call convert_mmx_register
4398 call make_mmx_prefix
4399 mov [postbyte_register],al
4400 mov [operand_size],0
4401 lods byte [esi]
4402 cmp al,','
4403 jne invalid_operand
4404 lods byte [esi]
4405 call get_size_operator
4406 cmp al,10h
4407 je pinsrw_mmreg_reg
4408 cmp al,'['
4409 jne invalid_operand
4410 call get_address
4411 cmp [operand_size],0
4412 je mmx_imm8
4413 cmp [operand_size],2
4414 jne invalid_operand_size
4415 jmp mmx_imm8
4416 pinsrw_mmreg_reg:
4417 lods byte [esi]
4418 call convert_register
4419 cmp ah,4
4420 jne invalid_operand_size
4421 mov bl,al
4422 jmp mmx_nomem_imm8
4423 pshufw_instruction:
4424 mov [mmx_size],8
4425 mov [opcode_prefix],al
4426 jmp pshuf_instruction
4427 pshufd_instruction:
4428 mov [mmx_size],16
4429 mov [opcode_prefix],al
4430 pshuf_instruction:
4431 mov [base_code],0Fh
4432 mov [extended_code],70h
4433 lods byte [esi]
4434 call get_size_operator
4435 cmp al,10h
4436 jne invalid_operand
4437 lods byte [esi]
4438 call convert_mmx_register
4439 cmp ah,[mmx_size]
4440 jne invalid_operand_size
4441 mov [postbyte_register],al
4442 lods byte [esi]
4443 cmp al,','
4444 jne invalid_operand
4445 lods byte [esi]
4446 call get_size_operator
4447 cmp al,10h
4448 je pshuf_mmreg_mmreg
4449 cmp al,'['
4450 jne invalid_operand
4451 call get_address
4452 jmp mmx_imm8
4453 pshuf_mmreg_mmreg:
4454 lods byte [esi]
4455 call convert_mmx_register
4456 mov bl,al
4457 jmp mmx_nomem_imm8
4458 movd_instruction:
4459 mov [base_code],0Fh
4460 mov [extended_code],7Eh
4461 lods byte [esi]
4462 call get_size_operator
4463 cmp al,10h
4464 je movd_reg
4465 cmp al,'['
4466 jne invalid_operand
4467 call get_address
4468 test [operand_size],not 4
4469 jnz invalid_operand_size
4470 mov [operand_size],0
4471 lods byte [esi]
4472 cmp al,','
4473 jne invalid_operand
4474 lods byte [esi]
4475 call get_size_operator
4476 cmp al,10h
4477 jne invalid_operand
4478 lods byte [esi]
4479 call convert_mmx_register
4480 call make_mmx_prefix
4481 mov [postbyte_register],al
4482 jmp instruction_ready
4483 movd_reg:
4484 lods byte [esi]
4485 cmp al,0B0h
4486 jae movd_mmreg
4487 call convert_register
4488 cmp ah,4
4489 jne invalid_operand_size
4490 mov [operand_size],0
4491 mov bl,al
4492 lods byte [esi]
4493 cmp al,','
4494 jne invalid_operand
4495 lods byte [esi]
4496 call get_size_operator
4497 cmp al,10h
4498 jne invalid_operand
4499 lods byte [esi]
4500 call convert_mmx_register
4501 mov [postbyte_register],al
4502 call make_mmx_prefix
4503 jmp nomem_instruction_ready
4504 movd_mmreg:
4505 mov [extended_code],6Eh
4506 call convert_mmx_register
4507 call make_mmx_prefix
4508 mov [postbyte_register],al
4509 mov [operand_size],0
4510 lods byte [esi]
4511 cmp al,','
4512 jne invalid_operand
4513 lods byte [esi]
4514 call get_size_operator
4515 cmp al,10h
4516 je movd_mmreg_reg
4517 cmp al,'['
4518 jne invalid_operand
4519 call get_address
4520 test [operand_size],not 4
4521 jnz invalid_operand_size
4522 jmp instruction_ready
4523 movd_mmreg_reg:
4524 lods byte [esi]
4525 call convert_register
4526 cmp ah,4
4527 jne invalid_operand_size
4528 mov bl,al
4529 jmp nomem_instruction_ready
4530 make_mmx_prefix:
4531 cmp [vex_required],0
4532 jne mmx_prefix_for_vex
4533 cmp [operand_size],16
4534 jne no_mmx_prefix
4535 mov [operand_prefix],66h
4536 no_mmx_prefix:
4537 ret
4538 mmx_prefix_for_vex:
4539 cmp [operand_size],16
4540 jne invalid_operand
4541 mov [opcode_prefix],66h
4542 ret
4543 movq_instruction:
4544 mov [base_code],0Fh
4545 lods byte [esi]
4546 call get_size_operator
4547 cmp al,10h
4548 je movq_reg
4549 cmp al,'['
4550 jne invalid_operand
4551 call get_address
4552 test [operand_size],not 8
4553 jnz invalid_operand_size
4554 mov [operand_size],0
4555 lods byte [esi]
4556 cmp al,','
4557 jne invalid_operand
4558 lods byte [esi]
4559 cmp al,10h
4560 jne invalid_operand
4561 lods byte [esi]
4562 call convert_mmx_register
4563 mov [postbyte_register],al
4564 cmp ah,16
4565 je movq_mem_xmmreg
4566 mov [extended_code],7Fh
4567 jmp instruction_ready
4568 movq_mem_xmmreg:
4569 mov [extended_code],0D6h
4570 mov [opcode_prefix],66h
4571 jmp instruction_ready
4572 movq_reg:
4573 lods byte [esi]
4574 cmp al,0B0h
4575 jae movq_mmreg
4576 call convert_register
4577 cmp ah,8
4578 jne invalid_operand_size
4579 mov bl,al
4580 lods byte [esi]
4581 cmp al,','
4582 jne invalid_operand
4583 lods byte [esi]
4584 call get_size_operator
4585 cmp al,10h
4586 jne invalid_operand
4587 mov [operand_size],0
4588 lods byte [esi]
4589 call convert_mmx_register
4590 mov [postbyte_register],al
4591 call make_mmx_prefix
4592 mov [extended_code],7Eh
4593 call operand_64bit
4594 jmp nomem_instruction_ready
4595 movq_mmreg:
4596 call convert_mmx_register
4597 mov [postbyte_register],al
4598 mov [extended_code],6Fh
4599 mov [mmx_size],ah
4600 cmp ah,16
4601 jne movq_mmreg_
4602 mov [extended_code],7Eh
4603 mov [opcode_prefix],0F3h
4604 movq_mmreg_:
4605 lods byte [esi]
4606 cmp al,','
4607 jne invalid_operand
4608 mov [operand_size],0
4609 lods byte [esi]
4610 call get_size_operator
4611 cmp al,10h
4612 je movq_mmreg_reg
4613 call get_address
4614 test [operand_size],not 8
4615 jnz invalid_operand_size
4616 jmp instruction_ready
4617 movq_mmreg_reg:
4618 lods byte [esi]
4619 cmp al,0B0h
4620 jae movq_mmreg_mmreg
4621 mov [operand_size],0
4622 call convert_register
4623 cmp ah,8
4624 jne invalid_operand_size
4625 mov [extended_code],6Eh
4626 mov [opcode_prefix],0
4627 mov bl,al
4628 cmp [mmx_size],16
4629 jne movq_mmreg_reg_store
4630 mov [opcode_prefix],66h
4631 movq_mmreg_reg_store:
4632 call operand_64bit
4633 jmp nomem_instruction_ready
4634 movq_mmreg_mmreg:
4635 call convert_mmx_register
4636 cmp ah,[mmx_size]
4637 jne invalid_operand_size
4638 mov bl,al
4639 jmp nomem_instruction_ready
4640 movdq_instruction:
4641 mov [opcode_prefix],al
4642 mov [base_code],0Fh
4643 mov [extended_code],6Fh
4644 lods byte [esi]
4645 call get_size_operator
4646 cmp al,10h
4647 je movdq_mmreg
4648 cmp al,'['
4649 jne invalid_operand
4650 call get_address
4651 lods byte [esi]
4652 cmp al,','
4653 jne invalid_operand
4654 lods byte [esi]
4655 call get_size_operator
4656 cmp al,10h
4657 jne invalid_operand
4658 lods byte [esi]
4659 call convert_xmm_register
4660 mov [postbyte_register],al
4661 mov [extended_code],7Fh
4662 jmp instruction_ready
4663 movdq_mmreg:
4664 lods byte [esi]
4665 call convert_xmm_register
4666 mov [postbyte_register],al
4667 lods byte [esi]
4668 cmp al,','
4669 jne invalid_operand
4670 lods byte [esi]
4671 call get_size_operator
4672 cmp al,10h
4673 je movdq_mmreg_mmreg
4674 cmp al,'['
4675 jne invalid_operand
4676 call get_address
4677 jmp instruction_ready
4678 movdq_mmreg_mmreg:
4679 lods byte [esi]
4680 call convert_xmm_register
4681 mov bl,al
4682 jmp nomem_instruction_ready
4683 lddqu_instruction:
4684 lods byte [esi]
4685 call get_size_operator
4686 cmp al,10h
4687 jne invalid_operand
4688 lods byte [esi]
4689 call convert_xmm_register
4690 push eax
4691 lods byte [esi]
4692 cmp al,','
4693 jne invalid_operand
4694 lods byte [esi]
4695 call get_size_operator
4696 cmp al,'['
4697 jne invalid_operand
4698 call get_address
4699 pop eax
4700 mov [postbyte_register],al
4701 mov [opcode_prefix],0F2h
4702 mov [base_code],0Fh
4703 mov [extended_code],0F0h
4704 jmp instruction_ready
4705
4706 movdq2q_instruction:
4707 mov [opcode_prefix],0F2h
4708 mov [mmx_size],8
4709 jmp movq2dq_
4710 movq2dq_instruction:
4711 mov [opcode_prefix],0F3h
4712 mov [mmx_size],16
4713 movq2dq_:
4714 lods byte [esi]
4715 call get_size_operator
4716 cmp al,10h
4717 jne invalid_operand
4718 lods byte [esi]
4719 call convert_mmx_register
4720 cmp ah,[mmx_size]
4721 jne invalid_operand_size
4722 mov [postbyte_register],al
4723 mov [operand_size],0
4724 lods byte [esi]
4725 cmp al,','
4726 jne invalid_operand
4727 lods byte [esi]
4728 call get_size_operator
4729 cmp al,10h
4730 jne invalid_operand
4731 lods byte [esi]
4732 call convert_mmx_register
4733 xor [mmx_size],8+16
4734 cmp ah,[mmx_size]
4735 jne invalid_operand_size
4736 mov bl,al
4737 mov [base_code],0Fh
4738 mov [extended_code],0D6h
4739 jmp nomem_instruction_ready
4740
4741 sse_ps_instruction_imm8:
4742 mov [immediate_size],1
4743 sse_ps_instruction:
4744 mov [mmx_size],16
4745 jmp sse_instruction
4746 sse_pd_instruction_imm8:
4747 mov [immediate_size],1
4748 sse_pd_instruction:
4749 mov [mmx_size],16
4750 mov [opcode_prefix],66h
4751 jmp sse_instruction
4752 sse_ss_instruction:
4753 mov [mmx_size],4
4754 mov [opcode_prefix],0F3h
4755 jmp sse_instruction
4756 sse_sd_instruction:
4757 mov [mmx_size],8
4758 mov [opcode_prefix],0F2h
4759 jmp sse_instruction
4760 cmp_pd_instruction:
4761 mov [opcode_prefix],66h
4762 cmp_ps_instruction:
4763 mov [mmx_size],16
4764 mov byte [value],al
4765 mov al,0C2h
4766 jmp sse_instruction
4767 cmp_ss_instruction:
4768 mov [mmx_size],4
4769 mov [opcode_prefix],0F3h
4770 jmp cmp_sx_instruction
4771 cmpsd_instruction:
4772 mov al,0A7h
4773 mov ah,[esi]
4774 or ah,ah
4775 jz simple_instruction_32bit
4776 cmp ah,0Fh
4777 je simple_instruction_32bit
4778 mov al,-1
4779 cmp_sd_instruction:
4780 mov [mmx_size],8
4781 mov [opcode_prefix],0F2h
4782 cmp_sx_instruction:
4783 mov byte [value],al
4784 mov al,0C2h
4785 jmp sse_instruction
4786 comiss_instruction:
4787 mov [mmx_size],4
4788 jmp sse_instruction
4789 comisd_instruction:
4790 mov [mmx_size],8
4791 mov [opcode_prefix],66h
4792 jmp sse_instruction
4793 cvtdq2pd_instruction:
4794 mov [opcode_prefix],0F3h
4795 cvtps2pd_instruction:
4796 mov [mmx_size],8
4797 jmp sse_instruction
4798 cvtpd2dq_instruction:
4799 mov [mmx_size],16
4800 mov [opcode_prefix],0F2h
4801 jmp sse_instruction
4802 movshdup_instruction:
4803 mov [mmx_size],16
4804 mov [opcode_prefix],0F3h
4805 sse_instruction:
4806 mov [base_code],0Fh
4807 mov [extended_code],al
4808 lods byte [esi]
4809 call get_size_operator
4810 cmp al,10h
4811 jne invalid_operand
4812 sse_xmmreg:
4813 lods byte [esi]
4814 call convert_xmm_register
4815 sse_reg:
4816 mov [postbyte_register],al
4817 mov [operand_size],0
4818 lods byte [esi]
4819 cmp al,','
4820 jne invalid_operand
4821 lods byte [esi]
4822 call get_size_operator
4823 cmp al,10h
4824 je sse_xmmreg_xmmreg
4825 sse_reg_mem:
4826 cmp al,'['
4827 jne invalid_operand
4828 call get_address
4829 cmp [operand_size],0
4830 je sse_mem_size_ok
4831 mov al,[mmx_size]
4832 cmp [operand_size],al
4833 jne invalid_operand_size
4834 sse_mem_size_ok:
4835 mov al,[extended_code]
4836 mov ah,[supplemental_code]
4837 cmp al,0C2h
4838 je sse_cmp_mem_ok
4839 cmp ax,443Ah
4840 je sse_cmp_mem_ok
4841 cmp [immediate_size],1
4842 je mmx_imm8
4843 cmp [immediate_size],-1
4844 jne sse_ok
4845 call take_additional_xmm0
4846 mov [immediate_size],0
4847 sse_ok:
4848 jmp instruction_ready
4849 sse_cmp_mem_ok:
4850 cmp byte [value],-1
4851 je mmx_imm8
4852 call store_instruction_with_imm8
4853 jmp instruction_assembled
4854 sse_xmmreg_xmmreg:
4855 cmp [operand_prefix],66h
4856 jne sse_xmmreg_xmmreg_ok
4857 cmp [extended_code],12h
4858 je invalid_operand
4859 cmp [extended_code],16h
4860 je invalid_operand
4861 sse_xmmreg_xmmreg_ok:
4862 lods byte [esi]
4863 call convert_xmm_register
4864 mov bl,al
4865 mov al,[extended_code]
4866 mov ah,[supplemental_code]
4867 cmp al,0C2h
4868 je sse_cmp_nomem_ok
4869 cmp ax,443Ah
4870 je sse_cmp_nomem_ok
4871 cmp [immediate_size],1
4872 je mmx_nomem_imm8
4873 cmp [immediate_size],-1
4874 jne sse_nomem_ok
4875 call take_additional_xmm0
4876 mov [immediate_size],0
4877 sse_nomem_ok:
4878 jmp nomem_instruction_ready
4879 sse_cmp_nomem_ok:
4880 cmp byte [value],-1
4881 je mmx_nomem_imm8
4882 call store_nomem_instruction
4883 mov al,byte [value]
4884 stosb
4885 jmp instruction_assembled
4886 take_additional_xmm0:
4887 cmp byte [esi],','
4888 jne additional_xmm0_ok
4889 inc esi
4890 lods byte [esi]
4891 cmp al,10h
4892 jne invalid_operand
4893 lods byte [esi]
4894 call convert_xmm_register
4895 test al,al
4896 jnz invalid_operand
4897 additional_xmm0_ok:
4898 ret
4899
4900 pslldq_instruction:
4901 mov [postbyte_register],al
4902 mov [opcode_prefix],66h
4903 mov [base_code],0Fh
4904 mov [extended_code],73h
4905 lods byte [esi]
4906 call get_size_operator
4907 cmp al,10h
4908 jne invalid_operand
4909 lods byte [esi]
4910 call convert_xmm_register
4911 mov bl,al
4912 jmp mmx_nomem_imm8
4913 movpd_instruction:
4914 mov [opcode_prefix],66h
4915 movps_instruction:
4916 mov [base_code],0Fh
4917 mov [extended_code],al
4918 mov [mmx_size],16
4919 jmp sse_mov_instruction
4920 movss_instruction:
4921 mov [mmx_size],4
4922 mov [opcode_prefix],0F3h
4923 jmp sse_movs
4924 movsd_instruction:
4925 mov al,0A5h
4926 mov ah,[esi]
4927 or ah,ah
4928 jz simple_instruction_32bit
4929 cmp ah,0Fh
4930 je simple_instruction_32bit
4931 mov [mmx_size],8
4932 mov [opcode_prefix],0F2h
4933 sse_movs:
4934 mov [base_code],0Fh
4935 mov [extended_code],10h
4936 jmp sse_mov_instruction
4937 sse_mov_instruction:
4938 lods byte [esi]
4939 call get_size_operator
4940 cmp al,10h
4941 je sse_xmmreg
4942 sse_mem:
4943 cmp al,'['
4944 jne invalid_operand
4945 inc [extended_code]
4946 call get_address
4947 cmp [operand_size],0
4948 je sse_mem_xmmreg
4949 mov al,[mmx_size]
4950 cmp [operand_size],al
4951 jne invalid_operand_size
4952 mov [operand_size],0
4953 sse_mem_xmmreg:
4954 lods byte [esi]
4955 cmp al,','
4956 jne invalid_operand
4957 lods byte [esi]
4958 call get_size_operator
4959 cmp al,10h
4960 jne invalid_operand
4961 lods byte [esi]
4962 call convert_xmm_register
4963 mov [postbyte_register],al
4964 jmp instruction_ready
4965 movlpd_instruction:
4966 mov [opcode_prefix],66h
4967 movlps_instruction:
4968 mov [base_code],0Fh
4969 mov [extended_code],al
4970 mov [mmx_size],8
4971 lods byte [esi]
4972 call get_size_operator
4973 cmp al,10h
4974 jne sse_mem
4975 lods byte [esi]
4976 call convert_xmm_register
4977 mov [postbyte_register],al
4978 mov [operand_size],0
4979 lods byte [esi]
4980 cmp al,','
4981 jne invalid_operand
4982 lods byte [esi]
4983 call get_size_operator
4984 jmp sse_reg_mem
4985 movhlps_instruction:
4986 mov [base_code],0Fh
4987 mov [extended_code],al
4988 mov [mmx_size],0
4989 lods byte [esi]
4990 call get_size_operator
4991 cmp al,10h
4992 jne invalid_operand
4993 lods byte [esi]
4994 call convert_xmm_register
4995 mov [postbyte_register],al
4996 lods byte [esi]
4997 cmp al,','
4998 jne invalid_operand
4999 lods byte [esi]
5000 call get_size_operator
5001 cmp al,10h
5002 je sse_xmmreg_xmmreg_ok
5003 jmp invalid_operand
5004 maskmovq_instruction:
5005 mov cl,8
5006 jmp maskmov_instruction
5007 maskmovdqu_instruction:
5008 mov cl,16
5009 mov [opcode_prefix],66h
5010 maskmov_instruction:
5011 mov [base_code],0Fh
5012 mov [extended_code],0F7h
5013 lods byte [esi]
5014 call get_size_operator
5015 cmp al,10h
5016 jne invalid_operand
5017 lods byte [esi]
5018 call convert_mmx_register
5019 cmp ah,cl
5020 jne invalid_operand_size
5021 mov [postbyte_register],al
5022 lods byte [esi]
5023 cmp al,','
5024 jne invalid_operand
5025 lods byte [esi]
5026 call get_size_operator
5027 cmp al,10h
5028 jne invalid_operand
5029 lods byte [esi]
5030 call convert_mmx_register
5031 mov bl,al
5032 jmp nomem_instruction_ready
5033 movmskpd_instruction:
5034 mov [opcode_prefix],66h
5035 movmskps_instruction:
5036 mov [base_code],0Fh
5037 mov [extended_code],50h
5038 lods byte [esi]
5039 call get_size_operator
5040 cmp al,10h
5041 jne invalid_operand
5042 lods byte [esi]
5043 call convert_register
5044 mov [postbyte_register],al
5045 cmp ah,4
5046 je movmskps_reg_ok
5047 cmp ah,8
5048 jne invalid_operand_size
5049 cmp [code_type],64
5050 jne invalid_operand
5051 movmskps_reg_ok:
5052 mov [operand_size],0
5053 lods byte [esi]
5054 cmp al,','
5055 jne invalid_operand
5056 lods byte [esi]
5057 call get_size_operator
5058 cmp al,10h
5059 je sse_xmmreg_xmmreg_ok
5060 jmp invalid_operand
5061
5062 cvtpi2pd_instruction:
5063 mov [opcode_prefix],66h
5064 cvtpi2ps_instruction:
5065 mov [base_code],0Fh
5066 mov [extended_code],al
5067 lods byte [esi]
5068 call get_size_operator
5069 cmp al,10h
5070 jne invalid_operand
5071 lods byte [esi]
5072 call convert_xmm_register
5073 mov [postbyte_register],al
5074 mov [operand_size],0
5075 lods byte [esi]
5076 cmp al,','
5077 jne invalid_operand
5078 lods byte [esi]
5079 call get_size_operator
5080 cmp al,10h
5081 je cvtpi_xmmreg_xmmreg
5082 cmp al,'['
5083 jne invalid_operand
5084 call get_address
5085 cmp [operand_size],0
5086 je cvtpi_size_ok
5087 cmp [operand_size],8
5088 jne invalid_operand_size
5089 cvtpi_size_ok:
5090 jmp instruction_ready
5091 cvtpi_xmmreg_xmmreg:
5092 lods byte [esi]
5093 call convert_mmx_register
5094 cmp ah,8
5095 jne invalid_operand_size
5096 mov bl,al
5097 jmp nomem_instruction_ready
5098 cvtsi2ss_instruction:
5099 mov [opcode_prefix],0F3h
5100 jmp cvtsi_instruction
5101 cvtsi2sd_instruction:
5102 mov [opcode_prefix],0F2h
5103 cvtsi_instruction:
5104 mov [base_code],0Fh
5105 mov [extended_code],al
5106 lods byte [esi]
5107 call get_size_operator
5108 cmp al,10h
5109 jne invalid_operand
5110 lods byte [esi]
5111 call convert_xmm_register
5112 mov [postbyte_register],al
5113 cvtsi_xmmreg:
5114 mov [operand_size],0
5115 lods byte [esi]
5116 cmp al,','
5117 jne invalid_operand
5118 lods byte [esi]
5119 call get_size_operator
5120 cmp al,10h
5121 je cvtsi_xmmreg_reg
5122 cmp al,'['
5123 jne invalid_operand
5124 call get_address
5125 cmp [operand_size],0
5126 je cvtsi_size_ok
5127 cmp [operand_size],4
5128 je cvtsi_size_ok
5129 cmp [operand_size],8
5130 jne invalid_operand_size
5131 call operand_64bit
5132 cvtsi_size_ok:
5133 jmp instruction_ready
5134 cvtsi_xmmreg_reg:
5135 lods byte [esi]
5136 call convert_register
5137 cmp ah,4
5138 je cvtsi_xmmreg_reg_store
5139 cmp ah,8
5140 jne invalid_operand_size
5141 call operand_64bit
5142 cvtsi_xmmreg_reg_store:
5143 mov bl,al
5144 jmp nomem_instruction_ready
5145 cvtps2pi_instruction:
5146 mov [mmx_size],8
5147 jmp cvtpd_instruction
5148 cvtpd2pi_instruction:
5149 mov [opcode_prefix],66h
5150 mov [mmx_size],16
5151 cvtpd_instruction:
5152 mov [base_code],0Fh
5153 mov [extended_code],al
5154 lods byte [esi]
5155 call get_size_operator
5156 cmp al,10h
5157 jne invalid_operand
5158 lods byte [esi]
5159 call convert_mmx_register
5160 cmp ah,8
5161 jne invalid_operand_size
5162 mov [operand_size],0
5163 jmp sse_reg
5164 cvtss2si_instruction:
5165 mov [opcode_prefix],0F3h
5166 mov [mmx_size],4
5167 jmp cvt2si_instruction
5168 cvtsd2si_instruction:
5169 mov [opcode_prefix],0F2h
5170 mov [mmx_size],8
5171 cvt2si_instruction:
5172 mov [extended_code],al
5173 mov [base_code],0Fh
5174 lods byte [esi]
5175 call get_size_operator
5176 cmp al,10h
5177 jne invalid_operand
5178 lods byte [esi]
5179 call convert_register
5180 mov [operand_size],0
5181 cmp ah,4
5182 je sse_reg
5183 cmp ah,8
5184 jne invalid_operand_size
5185 call operand_64bit
5186 jmp sse_reg
5187
5188 ssse3_instruction:
5189 mov [base_code],0Fh
5190 mov [extended_code],38h
5191 mov [supplemental_code],al
5192 jmp mmx_instruction
5193 palignr_instruction:
5194 mov [base_code],0Fh
5195 mov [extended_code],3Ah
5196 mov [supplemental_code],0Fh
5197 lods byte [esi]
5198 call get_size_operator
5199 cmp al,10h
5200 jne invalid_operand
5201 lods byte [esi]
5202 call convert_mmx_register
5203 call make_mmx_prefix
5204 mov [postbyte_register],al
5205 lods byte [esi]
5206 cmp al,','
5207 jne invalid_operand
5208 lods byte [esi]
5209 call get_size_operator
5210 cmp al,10h
5211 je palignr_mmreg_mmreg
5212 cmp al,'['
5213 jne invalid_operand
5214 call get_address
5215 jmp mmx_imm8
5216 palignr_mmreg_mmreg:
5217 lods byte [esi]
5218 call convert_mmx_register
5219 mov bl,al
5220 jmp mmx_nomem_imm8
5221 amd3dnow_instruction:
5222 mov [base_code],0Fh
5223 mov [extended_code],0Fh
5224 mov byte [value],al
5225 lods byte [esi]
5226 call get_size_operator
5227 cmp al,10h
5228 jne invalid_operand
5229 lods byte [esi]
5230 call convert_mmx_register
5231 cmp ah,8
5232 jne invalid_operand_size
5233 mov [postbyte_register],al
5234 lods byte [esi]
5235 cmp al,','
5236 jne invalid_operand
5237 lods byte [esi]
5238 call get_size_operator
5239 cmp al,10h
5240 je amd3dnow_mmreg_mmreg
5241 cmp al,'['
5242 jne invalid_operand
5243 call get_address
5244 call store_instruction_with_imm8
5245 jmp instruction_assembled
5246 amd3dnow_mmreg_mmreg:
5247 lods byte [esi]
5248 call convert_mmx_register
5249 cmp ah,8
5250 jne invalid_operand_size
5251 mov bl,al
5252 call store_nomem_instruction
5253 mov al,byte [value]
5254 stos byte [edi]
5255 jmp instruction_assembled
5256
5257 sse4_instruction_38_xmm0:
5258 mov [immediate_size],-1
5259 sse4_instruction_38:
5260 mov [mmx_size],16
5261 mov [opcode_prefix],66h
5262 mov [supplemental_code],al
5263 mov al,38h
5264 jmp sse_instruction
5265 sse4_ss_instruction_3a_imm8:
5266 mov [immediate_size],1
5267 mov [mmx_size],4
5268 jmp sse4_instruction_3a_setup
5269 sse4_sd_instruction_3a_imm8:
5270 mov [immediate_size],1
5271 mov [mmx_size],8
5272 jmp sse4_instruction_3a_setup
5273 sse4_instruction_3a_imm8:
5274 mov [immediate_size],1
5275 mov [mmx_size],16
5276 sse4_instruction_3a_setup:
5277 mov [opcode_prefix],66h
5278 mov [supplemental_code],al
5279 mov al,3Ah
5280 jmp sse_instruction
5281 pclmulqdq_instruction:
5282 mov byte [value],al
5283 mov [mmx_size],16
5284 mov al,44h
5285 jmp sse4_instruction_3a_setup
5286 extractps_instruction:
5287 mov [opcode_prefix],66h
5288 mov [base_code],0Fh
5289 mov [extended_code],3Ah
5290 mov [supplemental_code],17h
5291 lods byte [esi]
5292 call get_size_operator
5293 cmp al,10h
5294 je extractps_reg
5295 cmp al,'['
5296 jne invalid_operand
5297 call get_address
5298 cmp [operand_size],4
5299 je extractps_size_ok
5300 cmp [operand_size],0
5301 jne invalid_operand_size
5302 extractps_size_ok:
5303 push edx ebx ecx
5304 mov [operand_size],0
5305 lods byte [esi]
5306 cmp al,','
5307 jne invalid_operand
5308 lods byte [esi]
5309 call get_size_operator
5310 cmp al,10h
5311 jne invalid_operand
5312 lods byte [esi]
5313 call convert_xmm_register
5314 mov [postbyte_register],al
5315 pop ecx ebx edx
5316 jmp mmx_imm8
5317 extractps_reg:
5318 lods byte [esi]
5319 call convert_register
5320 push eax
5321 mov [operand_size],0
5322 lods byte [esi]
5323 cmp al,','
5324 jne invalid_operand
5325 lods byte [esi]
5326 call get_size_operator
5327 cmp al,10h
5328 jne invalid_operand
5329 lods byte [esi]
5330 call convert_xmm_register
5331 mov [postbyte_register],al
5332 pop ebx
5333 mov al,bh
5334 cmp al,4
5335 je mmx_nomem_imm8
5336 cmp al,8
5337 jne invalid_operand_size
5338 call operand_64bit
5339 jmp mmx_nomem_imm8
5340 insertps_instruction:
5341 lods byte [esi]
5342 call get_size_operator
5343 cmp al,10h
5344 jne invalid_operand
5345 lods byte [esi]
5346 call convert_xmm_register
5347 mov [postbyte_register],al
5348 insertps_xmmreg:
5349 mov [opcode_prefix],66h
5350 mov [base_code],0Fh
5351 mov [extended_code],3Ah
5352 mov [supplemental_code],21h
5353 mov [operand_size],0
5354 lods byte [esi]
5355 cmp al,','
5356 jne invalid_operand
5357 lods byte [esi]
5358 call get_size_operator
5359 cmp al,10h
5360 je insertps_xmmreg_reg
5361 cmp al,'['
5362 jne invalid_operand
5363 call get_address
5364 cmp [operand_size],4
5365 je insertps_size_ok
5366 cmp [operand_size],0
5367 jne invalid_operand_size
5368 insertps_size_ok:
5369 jmp mmx_imm8
5370 insertps_xmmreg_reg:
5371 lods byte [esi]
5372 call convert_mmx_register
5373 mov bl,al
5374 jmp mmx_nomem_imm8
5375 pextrq_instruction:
5376 mov [mmx_size],8
5377 jmp pextr_instruction
5378 pextrd_instruction:
5379 mov [mmx_size],4
5380 jmp pextr_instruction
5381 pextrw_instruction:
5382 mov [mmx_size],2
5383 jmp pextr_instruction
5384 pextrb_instruction:
5385 mov [mmx_size],1
5386 pextr_instruction:
5387 mov [opcode_prefix],66h
5388 mov [base_code],0Fh
5389 mov [extended_code],3Ah
5390 mov [supplemental_code],al
5391 lods byte [esi]
5392 call get_size_operator
5393 cmp al,10h
5394 je pextr_reg
5395 cmp al,'['
5396 jne invalid_operand
5397 call get_address
5398 mov al,[mmx_size]
5399 cmp al,[operand_size]
5400 je pextr_size_ok
5401 cmp [operand_size],0
5402 jne invalid_operand_size
5403 pextr_size_ok:
5404 cmp al,8
5405 jne pextr_prefix_ok
5406 call operand_64bit
5407 pextr_prefix_ok:
5408 push edx ebx ecx
5409 mov [operand_size],0
5410 lods byte [esi]
5411 cmp al,','
5412 jne invalid_operand
5413 lods byte [esi]
5414 call get_size_operator
5415 cmp al,10h
5416 jne invalid_operand
5417 lods byte [esi]
5418 call convert_xmm_register
5419 mov [postbyte_register],al
5420 pop ecx ebx edx
5421 jmp mmx_imm8
5422 pextr_reg:
5423 lods byte [esi]
5424 call convert_register
5425 cmp [mmx_size],4
5426 ja pextrq_reg
5427 cmp ah,4
5428 je pextr_reg_size_ok
5429 cmp [code_type],64
5430 jne pextr_invalid_size
5431 cmp ah,8
5432 je pextr_reg_size_ok
5433 pextr_invalid_size:
5434 jmp invalid_operand_size
5435 pextrq_reg:
5436 cmp ah,8
5437 jne pextr_invalid_size
5438 call operand_64bit
5439 pextr_reg_size_ok:
5440 mov [operand_size],0
5441 push eax
5442 lods byte [esi]
5443 cmp al,','
5444 jne invalid_operand
5445 lods byte [esi]
5446 call get_size_operator
5447 cmp al,10h
5448 jne invalid_operand
5449 lods byte [esi]
5450 call convert_mmx_register
5451 mov ebx,eax
5452 pop eax
5453 mov [postbyte_register],al
5454 mov al,ah
5455 cmp [mmx_size],2
5456 jne pextr_reg_store
5457 mov [opcode_prefix],0
5458 mov [extended_code],0C5h
5459 call make_mmx_prefix
5460 jmp mmx_nomem_imm8
5461 pextr_reg_store:
5462 cmp bh,16
5463 jne invalid_operand_size
5464 xchg bl,[postbyte_register]
5465 call operand_autodetect
5466 jmp mmx_nomem_imm8
5467 pinsrb_instruction:
5468 mov [mmx_size],1
5469 jmp pinsr_instruction
5470 pinsrd_instruction:
5471 mov [mmx_size],4
5472 jmp pinsr_instruction
5473 pinsrq_instruction:
5474 mov [mmx_size],8
5475 call operand_64bit
5476 pinsr_instruction:
5477 mov [opcode_prefix],66h
5478 mov [base_code],0Fh
5479 mov [extended_code],3Ah
5480 mov [supplemental_code],al
5481 lods byte [esi]
5482 call get_size_operator
5483 cmp al,10h
5484 jne invalid_operand
5485 lods byte [esi]
5486 call convert_xmm_register
5487 mov [postbyte_register],al
5488 pinsr_xmmreg:
5489 mov [operand_size],0
5490 lods byte [esi]
5491 cmp al,','
5492 jne invalid_operand
5493 lods byte [esi]
5494 call get_size_operator
5495 cmp al,10h
5496 je pinsr_xmmreg_reg
5497 cmp al,'['
5498 jne invalid_operand
5499 call get_address
5500 cmp [operand_size],0
5501 je mmx_imm8
5502 mov al,[mmx_size]
5503 cmp al,[operand_size]
5504 je mmx_imm8
5505 jmp invalid_operand_size
5506 pinsr_xmmreg_reg:
5507 lods byte [esi]
5508 call convert_register
5509 mov bl,al
5510 cmp [mmx_size],8
5511 je pinsrq_xmmreg_reg
5512 cmp ah,4
5513 je mmx_nomem_imm8
5514 jmp invalid_operand_size
5515 pinsrq_xmmreg_reg:
5516 cmp ah,8
5517 je mmx_nomem_imm8
5518 jmp invalid_operand_size
5519 pmovsxbw_instruction:
5520 mov [mmx_size],8
5521 jmp pmovsx_instruction
5522 pmovsxbd_instruction:
5523 mov [mmx_size],4
5524 jmp pmovsx_instruction
5525 pmovsxbq_instruction:
5526 mov [mmx_size],2
5527 jmp pmovsx_instruction
5528 pmovsxwd_instruction:
5529 mov [mmx_size],8
5530 jmp pmovsx_instruction
5531 pmovsxwq_instruction:
5532 mov [mmx_size],4
5533 jmp pmovsx_instruction
5534 pmovsxdq_instruction:
5535 mov [mmx_size],8
5536 pmovsx_instruction:
5537 mov [opcode_prefix],66h
5538 mov [base_code],0Fh
5539 mov [extended_code],38h
5540 mov [supplemental_code],al
5541 lods byte [esi]
5542 call get_size_operator
5543 cmp al,10h
5544 jne invalid_operand
5545 lods byte [esi]
5546 call convert_xmm_register
5547 mov [postbyte_register],al
5548 lods byte [esi]
5549 cmp al,','
5550 jne invalid_operand
5551 mov [operand_size],0
5552 lods byte [esi]
5553 call get_size_operator
5554 cmp al,10h
5555 je pmovsx_xmmreg_reg
5556 cmp al,'['
5557 jne invalid_operand
5558 call get_address
5559 cmp [operand_size],0
5560 je instruction_ready
5561 mov al,[mmx_size]
5562 cmp al,[operand_size]
5563 jne invalid_operand_size
5564 jmp instruction_ready
5565 pmovsx_xmmreg_reg:
5566 lods byte [esi]
5567 call convert_xmm_register
5568 mov bl,al
5569 jmp nomem_instruction_ready
5570
5571 fxsave_instruction_64bit:
5572 call operand_64bit
5573 fxsave_instruction:
5574 mov [extended_code],0AEh
5575 mov [base_code],0Fh
5576 mov [postbyte_register],al
5577 lods byte [esi]
5578 call get_size_operator
5579 cmp al,'['
5580 jne invalid_operand
5581 call get_address
5582 mov ah,[operand_size]
5583 or ah,ah
5584 jz fxsave_size_ok
5585 mov al,[postbyte_register]
5586 cmp al,111b
5587 je clflush_size_check
5588 cmp al,10b
5589 jb invalid_operand_size
5590 cmp al,11b
5591 ja invalid_operand_size
5592 cmp ah,4
5593 jne invalid_operand_size
5594 jmp fxsave_size_ok
5595 clflush_size_check:
5596 cmp ah,1
5597 jne invalid_operand_size
5598 fxsave_size_ok:
5599 jmp instruction_ready
5600 prefetch_instruction:
5601 mov [extended_code],18h
5602 prefetch_mem_8bit:
5603 mov [base_code],0Fh
5604 mov [postbyte_register],al
5605 lods byte [esi]
5606 call get_size_operator
5607 cmp al,'['
5608 jne invalid_operand
5609 or ah,ah
5610 jz prefetch_size_ok
5611 cmp ah,1
5612 jne invalid_operand_size
5613 prefetch_size_ok:
5614 call get_address
5615 jmp instruction_ready
5616 amd_prefetch_instruction:
5617 mov [extended_code],0Dh
5618 jmp prefetch_mem_8bit
5619 fence_instruction:
5620 mov bl,al
5621 mov ax,0AE0Fh
5622 stos word [edi]
5623 mov al,bl
5624 stos byte [edi]
5625 jmp instruction_assembled
5626 pause_instruction:
5627 mov ax,90F3h
5628 stos word [edi]
5629 jmp instruction_assembled
5630 movntq_instruction:
5631 mov [mmx_size],8
5632 jmp movnt_instruction
5633 movntpd_instruction:
5634 mov [opcode_prefix],66h
5635 movntps_instruction:
5636 mov [mmx_size],16
5637 movnt_instruction:
5638 mov [extended_code],al
5639 mov [base_code],0Fh
5640 lods byte [esi]
5641 call get_size_operator
5642 cmp al,'['
5643 jne invalid_operand
5644 call get_address
5645 lods byte [esi]
5646 cmp al,','
5647 jne invalid_operand
5648 lods byte [esi]
5649 call get_size_operator
5650 cmp al,10h
5651 jne invalid_operand
5652 lods byte [esi]
5653 call convert_mmx_register
5654 cmp ah,[mmx_size]
5655 jne invalid_operand_size
5656 mov [postbyte_register],al
5657 jmp instruction_ready
5658
5659 movntsd_instruction:
5660 mov [opcode_prefix],0F2h
5661 mov [mmx_size],8
5662 jmp movnts_instruction
5663 movntss_instruction:
5664 mov [opcode_prefix],0F3h
5665 mov [mmx_size],4
5666 movnts_instruction:
5667 mov [extended_code],al
5668 mov [base_code],0Fh
5669 lods byte [esi]
5670 call get_size_operator
5671 cmp al,'['
5672 jne invalid_operand
5673 call get_address
5674 mov al,[operand_size]
5675 cmp al,[mmx_size]
5676 je movnts_size_ok
5677 test al,al
5678 jnz invalid_operand_size
5679 movnts_size_ok:
5680 lods byte [esi]
5681 cmp al,','
5682 jne invalid_operand
5683 mov [operand_size],0
5684 lods byte [esi]
5685 call get_size_operator
5686 cmp al,10h
5687 jne invalid_operand
5688 lods byte [esi]
5689 call convert_xmm_register
5690 mov [postbyte_register],al
5691 jmp instruction_ready
5692
5693 movnti_instruction:
5694 mov [base_code],0Fh
5695 mov [extended_code],al
5696 lods byte [esi]
5697 call get_size_operator
5698 cmp al,'['
5699 jne invalid_operand
5700 call get_address
5701 lods byte [esi]
5702 cmp al,','
5703 jne invalid_operand
5704 lods byte [esi]
5705 call get_size_operator
5706 cmp al,10h
5707 jne invalid_operand
5708 lods byte [esi]
5709 call convert_register
5710 cmp ah,4
5711 je movnti_store
5712 cmp ah,8
5713 jne invalid_operand_size
5714 call operand_64bit
5715 movnti_store:
5716 mov [postbyte_register],al
5717 jmp instruction_ready
5718 monitor_instruction:
5719 mov [postbyte_register],al
5720 cmp byte [esi],0
5721 je monitor_instruction_store
5722 cmp byte [esi],0Fh
5723 je monitor_instruction_store
5724 lods byte [esi]
5725 call get_size_operator
5726 cmp al,10h
5727 jne invalid_operand
5728 lods byte [esi]
5729 call convert_register
5730 cmp ax,0400h
5731 jne invalid_operand
5732 lods byte [esi]
5733 cmp al,','
5734 jne invalid_operand
5735 lods byte [esi]
5736 call get_size_operator
5737 cmp al,10h
5738 jne invalid_operand
5739 lods byte [esi]
5740 call convert_register
5741 cmp ax,0401h
5742 jne invalid_operand
5743 cmp [postbyte_register],0C8h
5744 jne monitor_instruction_store
5745 lods byte [esi]
5746 cmp al,','
5747 jne invalid_operand
5748 lods byte [esi]
5749 call get_size_operator
5750 cmp al,10h
5751 jne invalid_operand
5752 lods byte [esi]
5753 call convert_register
5754 cmp ax,0402h
5755 jne invalid_operand
5756 monitor_instruction_store:
5757 mov ax,010Fh
5758 stos word [edi]
5759 mov al,[postbyte_register]
5760 stos byte [edi]
5761 jmp instruction_assembled
5762 movntdqa_instruction:
5763 mov [opcode_prefix],66h
5764 mov [base_code],0Fh
5765 mov [extended_code],38h
5766 mov [supplemental_code],al
5767 lods byte [esi]
5768 call get_size_operator
5769 cmp al,10h
5770 jne invalid_operand
5771 lods byte [esi]
5772 call convert_xmm_register
5773 mov [postbyte_register],al
5774 lods byte [esi]
5775 cmp al,','
5776 jne invalid_operand
5777 lods byte [esi]
5778 call get_size_operator
5779 cmp al,'['
5780 jne invalid_operand
5781 call get_address
5782 jmp instruction_ready
5783
5784 extrq_instruction:
5785 mov [opcode_prefix],66h
5786 mov [base_code],0Fh
5787 mov [extended_code],78h
5788 lods byte [esi]
5789 call get_size_operator
5790 cmp al,10h
5791 jne invalid_operand
5792 lods byte [esi]
5793 call convert_xmm_register
5794 mov [postbyte_register],al
5795 mov [operand_size],0
5796 lods byte [esi]
5797 cmp al,','
5798 jne invalid_operand
5799 lods byte [esi]
5800 call get_size_operator
5801 cmp al,10h
5802 je extrq_xmmreg_xmmreg
5803 test ah,not 1
5804 jnz invalid_operand_size
5805 cmp al,'('
5806 jne invalid_operand
5807 xor bl,bl
5808 xchg bl,[postbyte_register]
5809 call store_nomem_instruction
5810 call get_byte_value
5811 stosb
5812 call append_imm8
5813 jmp instruction_assembled
5814 extrq_xmmreg_xmmreg:
5815 inc [extended_code]
5816 lods byte [esi]
5817 call convert_xmm_register
5818 mov bl,al
5819 jmp nomem_instruction_ready
5820 insertq_instruction:
5821 mov [opcode_prefix],0F2h
5822 mov [base_code],0Fh
5823 mov [extended_code],78h
5824 lods byte [esi]
5825 call get_size_operator
5826 cmp al,10h
5827 jne invalid_operand
5828 lods byte [esi]
5829 call convert_xmm_register
5830 mov [postbyte_register],al
5831 mov [operand_size],0
5832 lods byte [esi]
5833 cmp al,','
5834 jne invalid_operand
5835 lods byte [esi]
5836 call get_size_operator
5837 cmp al,10h
5838 jne invalid_operand
5839 lods byte [esi]
5840 call convert_xmm_register
5841 mov bl,al
5842 cmp byte [esi],','
5843 je insertq_with_imm
5844 inc [extended_code]
5845 jmp nomem_instruction_ready
5846 insertq_with_imm:
5847 call store_nomem_instruction
5848 call append_imm8
5849 call append_imm8
5850 jmp instruction_assembled
5851
5852 crc32_instruction:
5853 mov [opcode_prefix],0F2h
5854 mov [base_code],0Fh
5855 mov [extended_code],38h
5856 mov [supplemental_code],0F0h
5857 lods byte [esi]
5858 call get_size_operator
5859 cmp al,10h
5860 jne invalid_operand
5861 lods byte [esi]
5862 call convert_register
5863 mov [postbyte_register],al
5864 cmp ah,8
5865 je crc32_reg64
5866 cmp ah,4
5867 jne invalid_operand
5868 lods byte [esi]
5869 cmp al,','
5870 jne invalid_operand
5871 mov [operand_size],0
5872 lods byte [esi]
5873 call get_size_operator
5874 cmp al,10h
5875 je crc32_reg32_reg
5876 cmp al,'['
5877 jne invalid_operand
5878 call get_address
5879 mov al,[operand_size]
5880 test al,al
5881 jz crc32_unknown_size
5882 cmp al,1
5883 je crc32_reg32_mem_store
5884 cmp al,4
5885 ja invalid_operand_size
5886 inc [supplemental_code]
5887 call operand_autodetect
5888 crc32_reg32_mem_store:
5889 jmp instruction_ready
5890 crc32_unknown_size:
5891 call recoverable_unknown_size
5892 jmp crc32_reg32_mem_store
5893 crc32_reg32_reg:
5894 lods byte [esi]
5895 call convert_register
5896 mov bl,al
5897 mov al,ah
5898 cmp al,1
5899 je crc32_reg32_reg_store
5900 cmp al,4
5901 ja invalid_operand_size
5902 inc [supplemental_code]
5903 call operand_autodetect
5904 crc32_reg32_reg_store:
5905 jmp nomem_instruction_ready
5906 crc32_reg64:
5907 lods byte [esi]
5908 cmp al,','
5909 jne invalid_operand
5910 mov [operand_size],0
5911 call operand_64bit
5912 lods byte [esi]
5913 call get_size_operator
5914 cmp al,10h
5915 je crc32_reg64_reg
5916 cmp al,'['
5917 jne invalid_operand
5918 call get_address
5919 mov ah,[operand_size]
5920 mov al,8
5921 test ah,ah
5922 jz crc32_unknown_size
5923 cmp ah,1
5924 je crc32_reg32_mem_store
5925 cmp ah,al
5926 jne invalid_operand_size
5927 inc [supplemental_code]
5928 jmp crc32_reg32_mem_store
5929 crc32_reg64_reg:
5930 lods byte [esi]
5931 call convert_register
5932 mov bl,al
5933 mov al,8
5934 cmp ah,1
5935 je crc32_reg32_reg_store
5936 cmp ah,al
5937 jne invalid_operand_size
5938 inc [supplemental_code]
5939 jmp crc32_reg32_reg_store
5940 popcnt_instruction:
5941 mov [opcode_prefix],0F3h
5942 jmp bs_instruction
5943 movbe_instruction:
5944 mov [supplemental_code],al
5945 mov [extended_code],38h
5946 mov [base_code],0Fh
5947 lods byte [esi]
5948 call get_size_operator
5949 cmp al,'['
5950 je movbe_mem
5951 cmp al,10h
5952 jne invalid_operand
5953 lods byte [esi]
5954 call convert_register
5955 mov [postbyte_register],al
5956 lods byte [esi]
5957 cmp al,','
5958 jne invalid_operand
5959 lods byte [esi]
5960 call get_size_operator
5961 cmp al,'['
5962 jne invalid_argument
5963 call get_address
5964 mov al,[operand_size]
5965 call operand_autodetect
5966 jmp instruction_ready
5967 movbe_mem:
5968 inc [supplemental_code]
5969 call get_address
5970 push edx ebx ecx
5971 lods byte [esi]
5972 cmp al,','
5973 jne invalid_operand
5974 lods byte [esi]
5975 call get_size_operator
5976 cmp al,10h
5977 jne invalid_operand
5978 lods byte [esi]
5979 call convert_register
5980 mov [postbyte_register],al
5981 pop ecx ebx edx
5982 mov al,[operand_size]
5983 call operand_autodetect
5984 jmp instruction_ready
5985 adx_instruction:
5986 mov [base_code],0Fh
5987 mov [extended_code],38h
5988 mov [supplemental_code],0F6h
5989 mov [operand_prefix],al
5990 call get_reg_mem
5991 jc adx_reg_reg
5992 mov al,[operand_size]
5993 cmp al,4
5994 je instruction_ready
5995 cmp al,8
5996 jne invalid_operand_size
5997 call operand_64bit
5998 jmp instruction_ready
5999 adx_reg_reg:
6000 cmp ah,4
6001 je nomem_instruction_ready
6002 cmp ah,8
6003 jne invalid_operand_size
6004 call operand_64bit
6005 jmp nomem_instruction_ready
6006
6007 simple_vmx_instruction:
6008 mov ah,al
6009 mov al,0Fh
6010 stos byte [edi]
6011 mov al,1
6012 stos word [edi]
6013 jmp instruction_assembled
6014 vmclear_instruction:
6015 mov [opcode_prefix],66h
6016 jmp vmx_instruction
6017 vmxon_instruction:
6018 mov [opcode_prefix],0F3h
6019 vmx_instruction:
6020 mov [postbyte_register],al
6021 mov [extended_code],0C7h
6022 lods byte [esi]
6023 call get_size_operator
6024 cmp al,'['
6025 jne invalid_operand
6026 call get_address
6027 mov al,[operand_size]
6028 or al,al
6029 jz vmx_size_ok
6030 cmp al,8
6031 jne invalid_operand_size
6032 vmx_size_ok:
6033 mov [base_code],0Fh
6034 jmp instruction_ready
6035 vmread_instruction:
6036 mov [extended_code],78h
6037 lods byte [esi]
6038 call get_size_operator
6039 cmp al,10h
6040 je vmread_nomem
6041 cmp al,'['
6042 jne invalid_operand
6043 call get_address
6044 lods byte [esi]
6045 cmp al,','
6046 jne invalid_operand
6047 lods byte [esi]
6048 call get_size_operator
6049 cmp al,10h
6050 jne invalid_operand
6051 lods byte [esi]
6052 call convert_register
6053 mov [postbyte_register],al
6054 call vmread_check_size
6055 jmp vmx_size_ok
6056 vmread_nomem:
6057 lods byte [esi]
6058 call convert_register
6059 push eax
6060 call vmread_check_size
6061 lods byte [esi]
6062 cmp al,','
6063 jne invalid_operand
6064 lods byte [esi]
6065 call get_size_operator
6066 cmp al,10h
6067 jne invalid_operand
6068 lods byte [esi]
6069 call convert_register
6070 mov [postbyte_register],al
6071 call vmread_check_size
6072 pop ebx
6073 mov [base_code],0Fh
6074 jmp nomem_instruction_ready
6075 vmread_check_size:
6076 cmp [code_type],64
6077 je vmread_long
6078 cmp [operand_size],4
6079 jne invalid_operand_size
6080 ret
6081 vmread_long:
6082 cmp [operand_size],8
6083 jne invalid_operand_size
6084 ret
6085 vmwrite_instruction:
6086 mov [extended_code],79h
6087 lods byte [esi]
6088 call get_size_operator
6089 cmp al,10h
6090 jne invalid_operand
6091 lods byte [esi]
6092 call convert_register
6093 mov [postbyte_register],al
6094 lods byte [esi]
6095 cmp al,','
6096 jne invalid_operand
6097 lods byte [esi]
6098 call get_size_operator
6099 cmp al,10h
6100 je vmwrite_nomem
6101 cmp al,'['
6102 jne invalid_operand
6103 call get_address
6104 call vmread_check_size
6105 jmp vmx_size_ok
6106 vmwrite_nomem:
6107 lods byte [esi]
6108 call convert_register
6109 mov bl,al
6110 mov [base_code],0Fh
6111 jmp nomem_instruction_ready
6112 vmx_inv_instruction:
6113 mov [opcode_prefix],66h
6114 mov [extended_code],38h
6115 mov [supplemental_code],al
6116 lods byte [esi]
6117 call get_size_operator
6118 cmp al,10h
6119 jne invalid_operand
6120 lods byte [esi]
6121 call convert_register
6122 mov [postbyte_register],al
6123 call vmread_check_size
6124 mov [operand_size],0
6125 lods byte [esi]
6126 cmp al,','
6127 jne invalid_operand
6128 lods byte [esi]
6129 call get_size_operator
6130 cmp al,'['
6131 jne invalid_operand
6132 call get_address
6133 mov al,[operand_size]
6134 or al,al
6135 jz vmx_size_ok
6136 cmp al,16
6137 jne invalid_operand_size
6138 jmp vmx_size_ok
6139 simple_svm_instruction:
6140 push eax
6141 mov [base_code],0Fh
6142 mov [extended_code],1
6143 lods byte [esi]
6144 call get_size_operator
6145 cmp al,10h
6146 jne invalid_operand
6147 lods byte [esi]
6148 call convert_register
6149 or al,al
6150 jnz invalid_operand
6151 simple_svm_detect_size:
6152 cmp ah,2
6153 je simple_svm_16bit
6154 cmp ah,4
6155 je simple_svm_32bit
6156 cmp [code_type],64
6157 jne invalid_operand_size
6158 jmp simple_svm_store
6159 simple_svm_16bit:
6160 cmp [code_type],16
6161 je simple_svm_store
6162 cmp [code_type],64
6163 je invalid_operand_size
6164 jmp prefixed_svm_store
6165 simple_svm_32bit:
6166 cmp [code_type],32
6167 je simple_svm_store
6168 prefixed_svm_store:
6169 mov al,67h
6170 stos byte [edi]
6171 simple_svm_store:
6172 call store_instruction_code
6173 pop eax
6174 stos byte [edi]
6175 jmp instruction_assembled
6176 skinit_instruction:
6177 lods byte [esi]
6178 call get_size_operator
6179 cmp al,10h
6180 jne invalid_operand
6181 lods byte [esi]
6182 call convert_register
6183 cmp ax,0400h
6184 jne invalid_operand
6185 mov al,0DEh
6186 jmp simple_vmx_instruction
6187 invlpga_instruction:
6188 push eax
6189 mov [base_code],0Fh
6190 mov [extended_code],1
6191 lods byte [esi]
6192 call get_size_operator
6193 cmp al,10h
6194 jne invalid_operand
6195 lods byte [esi]
6196 call convert_register
6197 or al,al
6198 jnz invalid_operand
6199 mov bl,ah
6200 mov [operand_size],0
6201 lods byte [esi]
6202 cmp al,','
6203 jne invalid_operand
6204 lods byte [esi]
6205 call get_size_operator
6206 cmp al,10h
6207 jne invalid_operand
6208 lods byte [esi]
6209 call convert_register
6210 cmp ax,0401h
6211 jne invalid_operand
6212 mov ah,bl
6213 jmp simple_svm_detect_size
6214
6215 rdrand_instruction:
6216 mov [base_code],0Fh
6217 mov [extended_code],0C7h
6218 mov [postbyte_register],al
6219 lods byte [esi]
6220 call get_size_operator
6221 cmp al,10h
6222 jne invalid_operand
6223 lods byte [esi]
6224 call convert_register
6225 mov bl,al
6226 mov al,ah
6227 call operand_autodetect
6228 jmp nomem_instruction_ready
6229 rdfsbase_instruction:
6230 cmp [code_type],64
6231 jne illegal_instruction
6232 mov [opcode_prefix],0F3h
6233 mov [base_code],0Fh
6234 mov [extended_code],0AEh
6235 mov [postbyte_register],al
6236 lods byte [esi]
6237 call get_size_operator
6238 cmp al,10h
6239 jne invalid_operand
6240 lods byte [esi]
6241 call convert_register
6242 mov bl,al
6243 mov al,ah
6244 cmp ah,2
6245 je invalid_operand_size
6246 call operand_autodetect
6247 jmp nomem_instruction_ready
6248
6249 xabort_instruction:
6250 lods byte [esi]
6251 call get_size_operator
6252 cmp ah,1
6253 ja invalid_operand_size
6254 cmp al,'('
6255 jne invalid_operand
6256 call get_byte_value
6257 mov dl,al
6258 mov ax,0F8C6h
6259 stos word [edi]
6260 mov al,dl
6261 stos byte [edi]
6262 jmp instruction_assembled
6263 xbegin_instruction:
6264 lods byte [esi]
6265 cmp al,'('
6266 jne invalid_operand
6267 mov al,[code_type]
6268 cmp al,64
6269 je xbegin_64bit
6270 cmp al,32
6271 je xbegin_32bit
6272 xbegin_16bit:
6273 call get_address_word_value
6274 add edi,4
6275 mov ebp,[addressing_space]
6276 call calculate_relative_offset
6277 sub edi,4
6278 shl eax,16
6279 mov ax,0F8C7h
6280 stos dword [edi]
6281 jmp instruction_assembled
6282 xbegin_32bit:
6283 call get_address_dword_value
6284 jmp xbegin_address_ok
6285 xbegin_64bit:
6286 call get_address_qword_value
6287 xbegin_address_ok:
6288 add edi,5
6289 mov ebp,[addressing_space]
6290 call calculate_relative_offset
6291 sub edi,5
6292 mov edx,eax
6293 cwde
6294 cmp eax,edx
6295 jne xbegin_rel32
6296 mov al,66h
6297 stos byte [edi]
6298 mov eax,edx
6299 shl eax,16
6300 mov ax,0F8C7h
6301 stos dword [edi]
6302 jmp instruction_assembled
6303 xbegin_rel32:
6304 sub edx,1
6305 jno xbegin_rel32_ok
6306 cmp [code_type],64
6307 je jump_out_of_range
6308 xbegin_rel32_ok:
6309 mov ax,0F8C7h
6310 stos word [edi]
6311 mov eax,edx
6312 stos dword [edi]
6313 jmp instruction_assembled
6314
6315 convert_register:
6316 mov ah,al
6317 shr ah,4
6318 and al,0Fh
6319 cmp ah,8
6320 je match_register_size
6321 cmp ah,4
6322 ja invalid_operand
6323 cmp ah,1
6324 ja match_register_size
6325 cmp al,4
6326 jb match_register_size
6327 or ah,ah
6328 jz high_byte_register
6329 or [rex_prefix],40h
6330 match_register_size:
6331 cmp ah,[operand_size]
6332 je register_size_ok
6333 cmp [operand_size],0
6334 jne operand_sizes_do_not_match
6335 mov [operand_size],ah
6336 register_size_ok:
6337 ret
6338 high_byte_register:
6339 mov ah,1
6340 or [rex_prefix],80h
6341 jmp match_register_size
6342 convert_fpu_register:
6343 mov ah,al
6344 shr ah,4
6345 and al,111b
6346 cmp ah,10
6347 jne invalid_operand
6348 jmp match_register_size
6349 convert_mmx_register:
6350 mov ah,al
6351 shr ah,4
6352 cmp ah,0Ch
6353 je xmm_register
6354 ja invalid_operand
6355 and al,111b
6356 cmp ah,0Bh
6357 jne invalid_operand
6358 mov ah,8
6359 cmp [vex_required],0
6360 jne invalid_operand
6361 jmp match_register_size
6362 xmm_register:
6363 and al,0Fh
6364 mov ah,16
6365 cmp al,8
6366 jb match_register_size
6367 cmp [code_type],64
6368 jne invalid_operand
6369 jmp match_register_size
6370 convert_xmm_register:
6371 mov ah,al
6372 shr ah,4
6373 cmp ah,0Ch
6374 je xmm_register
6375 jmp invalid_operand
6376 get_size_operator:
6377 xor ah,ah
6378 cmp al,11h
6379 jne no_size_operator
6380 mov [size_declared],1
6381 lods word [esi]
6382 xchg al,ah
6383 mov [size_override],1
6384 cmp ah,[operand_size]
6385 je size_operator_ok
6386 cmp [operand_size],0
6387 jne operand_sizes_do_not_match
6388 mov [operand_size],ah
6389 size_operator_ok:
6390 ret
6391 no_size_operator:
6392 mov [size_declared],0
6393 cmp al,'['
6394 jne size_operator_ok
6395 mov [size_override],0
6396 ret
6397 get_jump_operator:
6398 mov [jump_type],0
6399 cmp al,12h
6400 jne jump_operator_ok
6401 lods word [esi]
6402 mov [jump_type],al
6403 mov al,ah
6404 jump_operator_ok:
6405 ret
6406 get_address:
6407 mov [segment_register],0
6408 mov [address_size],0
6409 mov [free_address_range],0
6410 mov al,[code_type]
6411 shr al,3
6412 mov [value_size],al
6413 mov al,[esi]
6414 and al,11110000b
6415 cmp al,60h
6416 jne get_size_prefix
6417 lods byte [esi]
6418 sub al,60h
6419 mov [segment_register],al
6420 mov al,[esi]
6421 and al,11110000b
6422 get_size_prefix:
6423 cmp al,70h
6424 jne address_size_prefix_ok
6425 lods byte [esi]
6426 sub al,70h
6427 cmp al,2
6428 jb invalid_address_size
6429 cmp al,8
6430 ja invalid_address_size
6431 mov [address_size],al
6432 mov [value_size],al
6433 address_size_prefix_ok:
6434 call calculate_address
6435 cmp byte [esi-1],']'
6436 jne invalid_address
6437 mov [address_high],edx
6438 mov edx,eax
6439 cmp [code_type],64
6440 jne address_ok
6441 or bx,bx
6442 jnz address_ok
6443 test ch,0Fh
6444 jnz address_ok
6445 calculate_relative_address:
6446 mov edx,[address_symbol]
6447 mov [symbol_identifier],edx
6448 mov edx,[address_high]
6449 mov ebp,[addressing_space]
6450 call calculate_relative_offset
6451 mov [address_high],edx
6452 cdq
6453 cmp edx,[address_high]
6454 je address_high_ok
6455 call recoverable_overflow
6456 address_high_ok:
6457 mov edx,eax
6458 ror ecx,16
6459 mov cl,[value_type]
6460 rol ecx,16
6461 mov bx,0FF00h
6462 address_ok:
6463 ret
6464 operand_16bit:
6465 cmp [code_type],16
6466 je size_prefix_ok
6467 mov [operand_prefix],66h
6468 ret
6469 operand_32bit:
6470 cmp [code_type],16
6471 jne size_prefix_ok
6472 mov [operand_prefix],66h
6473 size_prefix_ok:
6474 ret
6475 operand_64bit:
6476 cmp [code_type],64
6477 jne illegal_instruction
6478 or [rex_prefix],48h
6479 ret
6480 operand_autodetect:
6481 cmp al,2
6482 je operand_16bit
6483 cmp al,4
6484 je operand_32bit
6485 cmp al,8
6486 je operand_64bit
6487 jmp invalid_operand_size
6488 store_segment_prefix_if_necessary:
6489 mov al,[segment_register]
6490 or al,al
6491 jz segment_prefix_ok
6492 cmp al,4
6493 ja segment_prefix_386
6494 cmp [code_type],64
6495 je segment_prefix_ok
6496 cmp al,3
6497 je ss_prefix
6498 jb segment_prefix_86
6499 cmp bl,25h
6500 je segment_prefix_86
6501 cmp bh,25h
6502 je segment_prefix_86
6503 cmp bh,45h
6504 je segment_prefix_86
6505 cmp bh,44h
6506 je segment_prefix_86
6507 ret
6508 ss_prefix:
6509 cmp bl,25h
6510 je segment_prefix_ok
6511 cmp bh,25h
6512 je segment_prefix_ok
6513 cmp bh,45h
6514 je segment_prefix_ok
6515 cmp bh,44h
6516 je segment_prefix_ok
6517 jmp segment_prefix_86
6518 store_segment_prefix:
6519 mov al,[segment_register]
6520 or al,al
6521 jz segment_prefix_ok
6522 cmp al,5
6523 jae segment_prefix_386
6524 segment_prefix_86:
6525 dec al
6526 shl al,3
6527 add al,26h
6528 stos byte [edi]
6529 jmp segment_prefix_ok
6530 segment_prefix_386:
6531 add al,64h-5
6532 stos byte [edi]
6533 segment_prefix_ok:
6534 ret
6535 store_instruction_code:
6536 cmp [vex_required],0
6537 jne store_vex_instruction_code
6538 mov al,[operand_prefix]
6539 or al,al
6540 jz operand_prefix_ok
6541 stos byte [edi]
6542 operand_prefix_ok:
6543 mov al,[opcode_prefix]
6544 or al,al
6545 jz opcode_prefix_ok
6546 stos byte [edi]
6547 opcode_prefix_ok:
6548 mov al,[rex_prefix]
6549 test al,40h
6550 jz rex_prefix_ok
6551 cmp [code_type],64
6552 jne invalid_operand
6553 test al,0B0h
6554 jnz disallowed_combination_of_registers
6555 stos byte [edi]
6556 rex_prefix_ok:
6557 mov al,[base_code]
6558 stos byte [edi]
6559 cmp al,0Fh
6560 jne instruction_code_ok
6561 store_extended_code:
6562 mov al,[extended_code]
6563 stos byte [edi]
6564 cmp al,38h
6565 je store_supplemental_code
6566 cmp al,3Ah
6567 je store_supplemental_code
6568 instruction_code_ok:
6569 ret
6570 store_supplemental_code:
6571 mov al,[supplemental_code]
6572 stos byte [edi]
6573 ret
6574 store_nomem_instruction:
6575 test [postbyte_register],1000b
6576 jz nomem_reg_code_ok
6577 or [rex_prefix],44h
6578 and [postbyte_register],111b
6579 nomem_reg_code_ok:
6580 test bl,1000b
6581 jz nomem_rm_code_ok
6582 or [rex_prefix],41h
6583 and bl,111b
6584 nomem_rm_code_ok:
6585 call store_instruction_code
6586 mov al,[postbyte_register]
6587 shl al,3
6588 or al,bl
6589 or al,11000000b
6590 stos byte [edi]
6591 ret
6592 store_instruction:
6593 mov [current_offset],edi
6594 test [postbyte_register],1000b
6595 jz reg_code_ok
6596 or [rex_prefix],44h
6597 and [postbyte_register],111b
6598 reg_code_ok:
6599 cmp [code_type],64
6600 jne address_value_ok
6601 xor eax,eax
6602 bt edx,31
6603 sbb eax,[address_high]
6604 jz address_value_ok
6605 cmp [address_high],0
6606 jne address_value_out_of_range
6607 test ch,44h
6608 jnz address_value_ok
6609 test bx,8080h
6610 jz address_value_ok
6611 address_value_out_of_range:
6612 call recoverable_overflow
6613 address_value_ok:
6614 call store_segment_prefix_if_necessary
6615 test [vex_required],4
6616 jnz address_vsib
6617 or bx,bx
6618 jz address_immediate
6619 cmp bx,0F800h
6620 je address_rip_based
6621 cmp bx,0F400h
6622 je address_eip_based
6623 cmp bx,0FF00h
6624 je address_relative
6625 mov al,bl
6626 or al,bh
6627 and al,11110000b
6628 cmp al,80h
6629 je postbyte_64bit
6630 cmp al,40h
6631 je postbyte_32bit
6632 cmp al,20h
6633 jne invalid_address
6634 cmp [code_type],64
6635 je invalid_address_size
6636 call address_16bit_prefix
6637 call store_instruction_code
6638 cmp bl,bh
6639 jbe determine_16bit_address
6640 xchg bl,bh
6641 determine_16bit_address:
6642 cmp bx,2600h
6643 je address_si
6644 cmp bx,2700h
6645 je address_di
6646 cmp bx,2300h
6647 je address_bx
6648 cmp bx,2500h
6649 je address_bp
6650 cmp bx,2625h
6651 je address_bp_si
6652 cmp bx,2725h
6653 je address_bp_di
6654 cmp bx,2723h
6655 je address_bx_di
6656 cmp bx,2623h
6657 jne invalid_address
6658 address_bx_si:
6659 xor al,al
6660 jmp postbyte_16bit
6661 address_bx_di:
6662 mov al,1
6663 jmp postbyte_16bit
6664 address_bp_si:
6665 mov al,10b
6666 jmp postbyte_16bit
6667 address_bp_di:
6668 mov al,11b
6669 jmp postbyte_16bit
6670 address_si:
6671 mov al,100b
6672 jmp postbyte_16bit
6673 address_di:
6674 mov al,101b
6675 jmp postbyte_16bit
6676 address_bx:
6677 mov al,111b
6678 jmp postbyte_16bit
6679 address_bp:
6680 mov al,110b
6681 postbyte_16bit:
6682 test ch,22h
6683 jnz address_16bit_value
6684 or ch,ch
6685 jnz address_sizes_do_not_agree
6686 cmp edx,10000h
6687 jge value_out_of_range
6688 cmp edx,-8000h
6689 jl value_out_of_range
6690 or dx,dx
6691 jz address
6692 cmp dx,80h
6693 jb address_8bit_value
6694 cmp dx,-80h
6695 jae address_8bit_value
6696 address_16bit_value:
6697 or al,10000000b
6698 mov cl,[postbyte_register]
6699 shl cl,3
6700 or al,cl
6701 stos byte [edi]
6702 mov eax,edx
6703 stos word [edi]
6704 ret
6705 address_8bit_value:
6706 or al,01000000b
6707 mov cl,[postbyte_register]
6708 shl cl,3
6709 or al,cl
6710 stos byte [edi]
6711 mov al,dl
6712 stos byte [edi]
6713 cmp dx,80h
6714 jge value_out_of_range
6715 cmp dx,-80h
6716 jl value_out_of_range
6717 ret
6718 address:
6719 cmp al,110b
6720 je address_8bit_value
6721 mov cl,[postbyte_register]
6722 shl cl,3
6723 or al,cl
6724 stos byte [edi]
6725 ret
6726 address_vsib:
6727 mov al,bl
6728 shr al,4
6729 cmp al,0Ch
6730 je vector_index_ok
6731 cmp al,0Dh
6732 jne invalid_address
6733 vector_index_ok:
6734 mov al,bh
6735 shr al,4
6736 cmp al,4
6737 je postbyte_32bit
6738 cmp [code_type],64
6739 je address_prefix_ok
6740 test al,al
6741 jnz invalid_address
6742 postbyte_32bit:
6743 call address_32bit_prefix
6744 jmp address_prefix_ok
6745 postbyte_64bit:
6746 cmp [code_type],64
6747 jne invalid_address_size
6748 address_prefix_ok:
6749 cmp bl,44h
6750 je invalid_address
6751 cmp bl,84h
6752 je invalid_address
6753 test bh,1000b
6754 jz base_code_ok
6755 or [rex_prefix],41h
6756 base_code_ok:
6757 test bl,1000b
6758 jz index_code_ok
6759 or [rex_prefix],42h
6760 index_code_ok:
6761 call store_instruction_code
6762 or cl,cl
6763 jz only_base_register
6764 base_and_index:
6765 mov al,100b
6766 xor ah,ah
6767 cmp cl,1
6768 je scale_ok
6769 cmp cl,2
6770 je scale_1
6771 cmp cl,4
6772 je scale_2
6773 or ah,11000000b
6774 jmp scale_ok
6775 scale_2:
6776 or ah,10000000b
6777 jmp scale_ok
6778 scale_1:
6779 or ah,01000000b
6780 scale_ok:
6781 or bh,bh
6782 jz only_index_register
6783 and bl,111b
6784 shl bl,3
6785 or ah,bl
6786 and bh,111b
6787 or ah,bh
6788 sib_ready:
6789 test ch,44h
6790 jnz sib_address_32bit_value
6791 test ch,88h
6792 jnz sib_address_32bit_value
6793 or ch,ch
6794 jnz address_sizes_do_not_agree
6795 cmp bh,5
6796 je address_value
6797 or edx,edx
6798 jz sib_address
6799 address_value:
6800 cmp edx,80h
6801 jb sib_address_8bit_value
6802 cmp edx,-80h
6803 jae sib_address_8bit_value
6804 sib_address_32bit_value:
6805 or al,10000000b
6806 mov cl,[postbyte_register]
6807 shl cl,3
6808 or al,cl
6809 stos word [edi]
6810 jmp store_address_32bit_value
6811 sib_address_8bit_value:
6812 or al,01000000b
6813 mov cl,[postbyte_register]
6814 shl cl,3
6815 or al,cl
6816 stos word [edi]
6817 mov al,dl
6818 stos byte [edi]
6819 cmp edx,80h
6820 jge value_out_of_range
6821 cmp edx,-80h
6822 jl value_out_of_range
6823 ret
6824 sib_address:
6825 mov cl,[postbyte_register]
6826 shl cl,3
6827 or al,cl
6828 stos word [edi]
6829 ret
6830 only_index_register:
6831 or ah,101b
6832 and bl,111b
6833 shl bl,3
6834 or ah,bl
6835 mov cl,[postbyte_register]
6836 shl cl,3
6837 or al,cl
6838 stos word [edi]
6839 test ch,44h
6840 jnz store_address_32bit_value
6841 test ch,88h
6842 jnz store_address_32bit_value
6843 or ch,ch
6844 jnz invalid_address_size
6845 jmp store_address_32bit_value
6846 zero_index_register:
6847 mov bl,4
6848 mov cl,1
6849 jmp base_and_index
6850 only_base_register:
6851 mov al,bh
6852 and al,111b
6853 cmp al,4
6854 je zero_index_register
6855 test ch,44h
6856 jnz simple_address_32bit_value
6857 test ch,88h
6858 jnz simple_address_32bit_value
6859 or ch,ch
6860 jnz address_sizes_do_not_agree
6861 or edx,edx
6862 jz simple_address
6863 cmp edx,80h
6864 jb simple_address_8bit_value
6865 cmp edx,-80h
6866 jae simple_address_8bit_value
6867 simple_address_32bit_value:
6868 or al,10000000b
6869 mov cl,[postbyte_register]
6870 shl cl,3
6871 or al,cl
6872 stos byte [edi]
6873 jmp store_address_32bit_value
6874 simple_address_8bit_value:
6875 or al,01000000b
6876 mov cl,[postbyte_register]
6877 shl cl,3
6878 or al,cl
6879 stos byte [edi]
6880 mov al,dl
6881 stos byte [edi]
6882 cmp edx,80h
6883 jge value_out_of_range
6884 cmp edx,-80h
6885 jl value_out_of_range
6886 ret
6887 simple_address:
6888 cmp al,5
6889 je simple_address_8bit_value
6890 mov cl,[postbyte_register]
6891 shl cl,3
6892 or al,cl
6893 stos byte [edi]
6894 ret
6895 address_immediate:
6896 cmp [code_type],64
6897 je address_immediate_sib
6898 test ch,44h
6899 jnz address_immediate_32bit
6900 test ch,88h
6901 jnz address_immediate_32bit
6902 test ch,22h
6903 jnz address_immediate_16bit
6904 or ch,ch
6905 jnz invalid_address_size
6906 cmp [code_type],16
6907 je addressing_16bit
6908 address_immediate_32bit:
6909 call address_32bit_prefix
6910 call store_instruction_code
6911 store_immediate_address:
6912 mov al,101b
6913 mov cl,[postbyte_register]
6914 shl cl,3
6915 or al,cl
6916 stos byte [edi]
6917 store_address_32bit_value:
6918 test ch,0F0h
6919 jz address_32bit_relocation_ok
6920 mov eax,ecx
6921 shr eax,16
6922 cmp al,4
6923 jne address_32bit_relocation
6924 mov al,2
6925 address_32bit_relocation:
6926 xchg [value_type],al
6927 mov ebx,[address_symbol]
6928 xchg ebx,[symbol_identifier]
6929 call mark_relocation
6930 mov [value_type],al
6931 mov [symbol_identifier],ebx
6932 address_32bit_relocation_ok:
6933 mov eax,edx
6934 stos dword [edi]
6935 ret
6936 store_address_64bit_value:
6937 test ch,0F0h
6938 jz address_64bit_relocation_ok
6939 mov eax,ecx
6940 shr eax,16
6941 xchg [value_type],al
6942 mov ebx,[address_symbol]
6943 xchg ebx,[symbol_identifier]
6944 call mark_relocation
6945 mov [value_type],al
6946 mov [symbol_identifier],ebx
6947 address_64bit_relocation_ok:
6948 mov eax,edx
6949 stos dword [edi]
6950 mov eax,[address_high]
6951 stos dword [edi]
6952 ret
6953 address_immediate_sib:
6954 test ch,44h
6955 jnz address_immediate_sib_32bit
6956 test ch,not 88h
6957 jnz invalid_address_size
6958 address_immediate_sib_store:
6959 call store_instruction_code
6960 mov al,100b
6961 mov ah,100101b
6962 mov cl,[postbyte_register]
6963 shl cl,3
6964 or al,cl
6965 stos word [edi]
6966 jmp store_address_32bit_value
6967 address_immediate_sib_32bit:
6968 test ecx,0FF0000h
6969 jnz address_immediate_sib_nosignextend
6970 test edx,80000000h
6971 jz address_immediate_sib_store
6972 address_immediate_sib_nosignextend:
6973 call address_32bit_prefix
6974 jmp address_immediate_sib_store
6975 address_eip_based:
6976 mov al,67h
6977 stos byte [edi]
6978 address_rip_based:
6979 cmp [code_type],64
6980 jne invalid_address
6981 call store_instruction_code
6982 jmp store_immediate_address
6983 address_relative:
6984 call store_instruction_code
6985 movzx eax,[immediate_size]
6986 add eax,edi
6987 sub eax,[current_offset]
6988 add eax,5
6989 sub edx,eax
6990 jo value_out_of_range
6991 mov al,101b
6992 mov cl,[postbyte_register]
6993 shl cl,3
6994 or al,cl
6995 stos byte [edi]
6996 shr ecx,16
6997 xchg [value_type],cl
6998 mov ebx,[address_symbol]
6999 xchg ebx,[symbol_identifier]
7000 mov eax,edx
7001 call mark_relocation
7002 mov [value_type],cl
7003 mov [symbol_identifier],ebx
7004 stos dword [edi]
7005 ret
7006 addressing_16bit:
7007 cmp edx,10000h
7008 jge address_immediate_32bit
7009 cmp edx,-8000h
7010 jl address_immediate_32bit
7011 movzx edx,dx
7012 address_immediate_16bit:
7013 call address_16bit_prefix
7014 call store_instruction_code
7015 mov al,110b
7016 mov cl,[postbyte_register]
7017 shl cl,3
7018 or al,cl
7019 stos byte [edi]
7020 mov eax,edx
7021 stos word [edi]
7022 cmp edx,10000h
7023 jge value_out_of_range
7024 cmp edx,-8000h
7025 jl value_out_of_range
7026 ret
7027 address_16bit_prefix:
7028 cmp [code_type],16
7029 je instruction_prefix_ok
7030 mov al,67h
7031 stos byte [edi]
7032 ret
7033 address_32bit_prefix:
7034 cmp [code_type],32
7035 je instruction_prefix_ok
7036 mov al,67h
7037 stos byte [edi]
7038 instruction_prefix_ok:
7039 ret
7040 store_instruction_with_imm8:
7041 mov [immediate_size],1
7042 call store_instruction
7043 mov al,byte [value]
7044 stos byte [edi]
7045 ret
7046 store_instruction_with_imm16:
7047 mov [immediate_size],2
7048 call store_instruction
7049 mov ax,word [value]
7050 call mark_relocation
7051 stos word [edi]
7052 ret
7053 store_instruction_with_imm32:
7054 mov [immediate_size],4
7055 call store_instruction
7056 mov eax,dword [value]
7057 call mark_relocation
7058 stos dword [edi]
7059 ret
0
1 format MZ
2 heap 0
3 stack 8000h
4 entry loader:init
5
6 include 'loader.inc'
7
8 segment main use32
9
10 start:
11
12 call get_params
13 jnc make_listing
14
15 mov esi,_usage
16 call display_string
17 mov ax,4C02h
18 int 21h
19
20 make_listing:
21 call listing
22 mov ax,4C00h
23 int 21h
24
25 error:
26 mov esi,_error_prefix
27 call display_string
28 pop esi
29 call display_string
30 mov esi,_error_suffix
31 call display_string
32 mov ax,4C00h
33 int 21h
34
35 get_params:
36 push ds
37 mov ds,[psp_selector]
38 mov esi,81h
39 mov edi,params
40 find_param:
41 lodsb
42 cmp al,20h
43 je find_param
44 cmp al,'-'
45 je option_param
46 cmp al,0Dh
47 je all_params
48 or al,al
49 jz all_params
50 cmp [es:input_file],0
51 jne get_output_file
52 mov [es:input_file],edi
53 jmp process_param
54 get_output_file:
55 cmp [es:output_file],0
56 jne bad_params
57 mov [es:output_file],edi
58 process_param:
59 cmp al,22h
60 je string_param
61 copy_param:
62 stosb
63 lodsb
64 cmp al,20h
65 je param_end
66 cmp al,0Dh
67 je param_end
68 or al,al
69 jz param_end
70 jmp copy_param
71 string_param:
72 lodsb
73 cmp al,22h
74 je string_param_end
75 cmp al,0Dh
76 je param_end
77 or al,al
78 jz param_end
79 stosb
80 jmp string_param
81 option_param:
82 lodsb
83 cmp al,'a'
84 je addresses_option
85 cmp al,'A'
86 je addresses_option
87 cmp al,'b'
88 je bytes_per_line_option
89 cmp al,'B'
90 je bytes_per_line_option
91 invalid_option:
92 pop ds
93 stc
94 ret
95 get_option_value:
96 xor eax,eax
97 mov edx,eax
98 get_option_digit:
99 lodsb
100 cmp al,20h
101 je option_value_ok
102 cmp al,0Dh
103 je option_value_ok
104 or al,al
105 jz option_value_ok
106 sub al,30h
107 jc bad_params_value
108 cmp al,9
109 ja bad_params_value
110 imul edx,10
111 jo bad_params_value
112 add edx,eax
113 jc bad_params_value
114 jmp get_option_digit
115 option_value_ok:
116 dec esi
117 clc
118 ret
119 bad_params_value:
120 stc
121 ret
122 bytes_per_line_option:
123 lodsb
124 cmp al,20h
125 je bytes_per_line_option
126 cmp al,0Dh
127 je invalid_option
128 or al,al
129 jz invalid_option
130 dec esi
131 call get_option_value
132 jc bad_params
133 or edx,edx
134 jz invalid_option
135 cmp edx,1000
136 ja invalid_option
137 mov [es:code_bytes_per_line],edx
138 jmp find_param
139 addresses_option:
140 lodsb
141 cmp al,20h
142 je set_addresses_option
143 cmp al,0Dh
144 je set_addresses_option
145 or al,al
146 jnz bad_params
147 set_addresses_option:
148 dec esi
149 mov [es:show_addresses],1
150 jmp find_param
151 param_end:
152 dec esi
153 string_param_end:
154 xor al,al
155 stosb
156 jmp find_param
157 all_params:
158 xor al,al
159 stosb
160 pop ds
161 cmp [input_file],0
162 je bad_params
163 cmp [output_file],0
164 je bad_params
165 clc
166 ret
167 bad_params:
168 stc
169 ret
170
171 include 'system.inc'
172
173 include '..\listing.inc'
174
175 _usage db 'listing generator for flat assembler',0Dh,0Ah
176 db 'usage: listing <input> <output>',0Dh,0Ah
177 db 'optional settings:',0Dh,0Ah
178 db ' -a show target addresses for assembled code',0Dh,0Ah
179 db ' -b <number> set the amount of bytes listed per line',0Dh,0Ah
180 db 0
181 _error_prefix db 'error: ',0
182 _error_suffix db '.',0Dh,0Ah,0
183
184 input_file dd 0
185 output_file dd 0
186 code_bytes_per_line dd 16
187 show_addresses db 0
188
189 line_break db 0Dh,0Ah
190
191 input dd ?
192 assembled_code dd ?
193 assembled_code_length dd ?
194 code_end dd ?
195 code_offset dd ?
196 code_length dd ?
197 output_handle dd ?
198 output_buffer dd ?
199 current_source_file dd ?
200 current_source_line dd ?
201 source dd ?
202 source_length dd ?
203 maximum_address_length dd ?
204 address_start dd ?
205 last_listed_address dd ?
206
207 psp_selector dw ?
208 environment_selector dw ?
209
210 memory_handles_count dd ?
211 memory_handles rd 400h
212
213 params rb 1000h
214 characters rb 100h
215
216 segment buffer_segment
217
218 buffer = (buffer_segment-main) shl 4
219
220 db 1000h dup ?
221
222 segment stack_segment
223
224 stack_bottom = (stack_segment-main) shl 4
225
226 db 4000h dup ?
227
228 stack_top = stack_bottom + $
0
1 segment loader use16
2
3 init:
4
5 mov ax,1687h
6 int 2Fh
7 or ax,ax ; DPMI installed?
8 jnz short no_dpmi
9 test bl,1 ; 32-bit programs supported?
10 jz short no_dpmi
11 mov word [cs:mode_switch],di
12 mov word [cs:mode_switch+2],es
13 mov bx,si ; allocate memory for DPMI data
14 mov ah,48h
15 int 21h
16 jnc init_protected_mode
17 init_failed:
18 call init_error
19 db 'error: DPMI initialization failed.',0Dh,0Ah,0
20 no_dpmi:
21 call init_error
22 db 'error: 32-bit DPMI services are not available.',0Dh,0Ah,0
23 init_error:
24 pop si
25 push cs
26 pop ds
27 display_error:
28 lodsb
29 test al,al
30 jz short error_finish
31 mov dl,al
32 mov ah,2
33 int 21h
34 jmp short display_error
35 error_finish:
36 mov ax,4CFFh
37 int 21h
38 init_protected_mode:
39 mov es,ax
40 mov ds,[ds:2Ch]
41 mov ax,1
42 call far [cs:mode_switch] ; switch to protected mode
43 jc init_failed
44 mov cx,1
45 xor ax,ax
46 int 31h ; allocate descriptor for code
47 jc init_failed
48 mov si,ax
49 xor ax,ax
50 int 31h ; allocate descriptor for data
51 jc init_failed
52 mov di,ax
53 mov dx,cs
54 lar cx,dx
55 shr cx,8
56 or cx,0C000h
57 mov bx,si
58 mov ax,9
59 int 31h ; set code descriptor access rights
60 jc init_failed
61 mov dx,ds
62 lar cx,dx
63 shr cx,8
64 or cx,0C000h
65 mov bx,di
66 int 31h ; set data descriptor access rights
67 jc init_failed
68 mov ecx,main
69 shl ecx,4
70 mov dx,cx
71 shr ecx,16
72 mov ax,7
73 int 31h ; set data descriptor base address
74 jc init_failed
75 mov bx,si
76 int 31h ; set code descriptor base address
77 jc init_failed
78 mov cx,0FFFFh
79 mov dx,0FFFFh
80 mov ax,8 ; set segment limit to 4 GB
81 int 31h
82 jc init_failed
83 mov bx,di
84 int 31h
85 jc init_failed
86 mov ax,ds
87 mov ds,di
88 mov [psp_selector],es
89 mov [environment_selector],ax
90 cli
91 mov ss,di
92 mov esp,stack_top
93 sti
94 mov es,di
95 xor eax,eax
96 mov [memory_handles_count],eax
97 push si
98 push start
99 retf
100
101 mode_switch dd ?
0
1 format MZ
2 heap 0
3 stack 8000h
4 entry loader:init
5
6 include 'loader.inc'
7
8 segment main use32
9
10 start:
11
12 call get_params
13 jnc make_dump
14
15 mov esi,_usage
16 call display_string
17 mov ax,4C02h
18 int 21h
19
20 make_dump:
21 call preprocessed_source
22 mov ax,4C00h
23 int 21h
24
25 error:
26 mov esi,_error_prefix
27 call display_string
28 pop esi
29 call display_string
30 mov esi,_error_suffix
31 call display_string
32 mov ax,4C00h
33 int 21h
34
35 get_params:
36 push ds
37 mov ds,[psp_selector]
38 mov esi,81h
39 mov edi,params
40 find_param:
41 lodsb
42 cmp al,20h
43 je find_param
44 cmp al,0Dh
45 je all_params
46 or al,al
47 jz all_params
48 cmp [es:input_file],0
49 jne get_output_file
50 mov [es:input_file],edi
51 jmp process_param
52 get_output_file:
53 cmp [es:output_file],0
54 jne bad_params
55 mov [es:output_file],edi
56 process_param:
57 cmp al,22h
58 je string_param
59 copy_param:
60 stosb
61 lodsb
62 cmp al,20h
63 je param_end
64 cmp al,0Dh
65 je param_end
66 or al,al
67 jz param_end
68 jmp copy_param
69 string_param:
70 lodsb
71 cmp al,22h
72 je string_param_end
73 cmp al,0Dh
74 je param_end
75 or al,al
76 jz param_end
77 stosb
78 jmp string_param
79 bad_params_value:
80 stc
81 ret
82 param_end:
83 dec esi
84 string_param_end:
85 xor al,al
86 stosb
87 jmp find_param
88 all_params:
89 xor al,al
90 stosb
91 pop ds
92 cmp [input_file],0
93 je bad_params
94 cmp [output_file],0
95 je bad_params
96 clc
97 ret
98 bad_params:
99 stc
100 ret
101
102 include 'system.inc'
103
104 include '..\prepsrc.inc'
105
106 _usage db 'preprocessed source dumper for flat assembler',0Dh,0Ah
107 db 'usage: prepsrc <input> <output>',0Dh,0Ah
108 db 0
109 _error_prefix db 'error: ',0
110 _error_suffix db '.',0Dh,0Ah,0
111
112 input_file dd 0
113 output_file dd 0
114
115 psp_selector dw ?
116 environment_selector dw ?
117
118 memory_handles_count dd ?
119 memory_handles rd 400h
120
121 params rb 1000h
122
123 segment buffer_segment
124
125 buffer = (buffer_segment-main) shl 4
126
127 db 1000h dup ?
128
129 segment stack_segment
130
131 stack_bottom = (stack_segment-main) shl 4
132
133 db 4000h dup ?
134
135 stack_top = stack_bottom + $
0
1 format MZ
2 heap 0
3 stack 8000h
4 entry loader:init
5
6 include 'loader.inc'
7
8 segment main use32
9
10 start:
11
12 call get_params
13 jnc make_dump
14
15 mov esi,_usage
16 call display_string
17 mov ax,4C02h
18 int 21h
19
20 make_dump:
21 call symbols
22 mov ax,4C00h
23 int 21h
24
25 error:
26 mov esi,_error_prefix
27 call display_string
28 pop esi
29 call display_string
30 mov esi,_error_suffix
31 call display_string
32 mov ax,4C00h
33 int 21h
34
35 get_params:
36 push ds
37 mov ds,[psp_selector]
38 mov esi,81h
39 mov edi,params
40 find_param:
41 lodsb
42 cmp al,20h
43 je find_param
44 cmp al,0Dh
45 je all_params
46 or al,al
47 jz all_params
48 cmp [es:input_file],0
49 jne get_output_file
50 mov [es:input_file],edi
51 jmp process_param
52 get_output_file:
53 cmp [es:output_file],0
54 jne bad_params
55 mov [es:output_file],edi
56 process_param:
57 cmp al,22h
58 je string_param
59 copy_param:
60 stosb
61 lodsb
62 cmp al,20h
63 je param_end
64 cmp al,0Dh
65 je param_end
66 or al,al
67 jz param_end
68 jmp copy_param
69 string_param:
70 lodsb
71 cmp al,22h
72 je string_param_end
73 cmp al,0Dh
74 je param_end
75 or al,al
76 jz param_end
77 stosb
78 jmp string_param
79 bad_params_value:
80 stc
81 ret
82 param_end:
83 dec esi
84 string_param_end:
85 xor al,al
86 stosb
87 jmp find_param
88 all_params:
89 xor al,al
90 stosb
91 pop ds
92 cmp [input_file],0
93 je bad_params
94 cmp [output_file],0
95 je bad_params
96 clc
97 ret
98 bad_params:
99 stc
100 ret
101
102 include 'system.inc'
103
104 include '..\symbols.inc'
105
106 _usage db 'symbols dumper for flat assembler',0Dh,0Ah
107 db 'usage: symbols <input> <output>',0Dh,0Ah
108 db 0
109 _error_prefix db 'error: ',0
110 _error_suffix db '.',0Dh,0Ah,0
111
112 input_file dd 0
113 output_file dd 0
114
115 input dd ?
116 output_buffer dd ?
117 output_handle dd ?
118
119 psp_selector dw ?
120 environment_selector dw ?
121
122 memory_handles_count dd ?
123 memory_handles rd 400h
124
125 params rb 1000h
126
127 segment buffer_segment
128
129 buffer = (buffer_segment-main) shl 4
130
131 db 1000h dup ?
132
133 segment stack_segment
134
135 stack_bottom = (stack_segment-main) shl 4
136
137 db 4000h dup ?
138
139 stack_top = stack_bottom + $
0
1 display_string:
2 lods byte [esi]
3 or al,al
4 jz string_end
5 mov dl,al
6 mov ah,2
7 int 21h
8 jmp display_string
9 string_end:
10 ret
11 alloc:
12 push ebx esi edi
13 mov cx,ax
14 shr eax,16
15 mov bx,ax
16 mov ax,501h
17 int 31h
18 jc dpmi_allocation_failed
19 mov ax,bx
20 shl eax,16
21 mov ax,cx
22 mov edx,main
23 shl edx,4
24 sub eax,edx
25 mov bx,si
26 shl ebx,16
27 mov bx,di
28 mov ecx,[memory_handles_count]
29 inc [memory_handles_count]
30 shl ecx,3
31 add ecx,memory_handles
32 mov [ecx],eax
33 mov [ecx+4],ebx
34 pop edi esi ebx
35 clc
36 ret
37 dpmi_allocation_failed:
38 pop edi esi ebx
39 stc
40 ret
41 free:
42 push ebx esi edi
43 mov esi,memory_handles
44 mov ecx,[memory_handles_count]
45 find_memory_handle:
46 cmp eax,[esi]
47 je memory_handle_found
48 add esi,8
49 loop find_memory_handle
50 pop edi esi
51 ret
52 memory_handle_found:
53 mov ebx,[esi+4]
54 dec [memory_handles_count]
55 dec ecx
56 jz free_memory
57 remove_memory_handle:
58 mov edx,[esi+8]
59 mov edi,[esi+8+4]
60 mov [esi],edx
61 mov [esi+4],edi
62 add esi,8
63 loop remove_memory_handle
64 free_memory:
65 mov esi,ebx
66 shr esi,16
67 mov di,bx
68 mov ax,502h
69 int 31h
70 pop edi esi ebx
71 ret
72 open:
73 push esi edi ebp
74 call adapt_path
75 mov ax,716Ch
76 mov bx,100000b
77 mov dx,1
78 xor cx,cx
79 xor si,si
80 call dos_int
81 jnc open_done
82 cmp ax,7100h
83 je old_open
84 stc
85 jmp open_done
86 old_open:
87 mov ax,3D00h
88 xor dx,dx
89 call dos_int
90 open_done:
91 mov bx,ax
92 pop ebp edi esi
93 ret
94 adapt_path:
95 mov esi,edx
96 mov edi,buffer
97 copy_path:
98 lodsb
99 cmp al,'/'
100 jne path_char_ok
101 mov al,'\'
102 path_char_ok:
103 stosb
104 or al,al
105 jnz copy_path
106 ret
107 dos_int:
108 push 0 0 0
109 pushw buffer_segment buffer_segment
110 stc
111 pushfw
112 push eax
113 push ecx
114 push edx
115 push ebx
116 push 0
117 push ebp
118 push esi
119 push edi
120 mov ax,300h
121 mov bx,21h
122 xor cx,cx
123 mov edi,esp
124 push es ss
125 pop es
126 int 31h
127 pop es
128 mov edi,[esp]
129 mov esi,[esp+4]
130 mov ebp,[esp+8]
131 mov ebx,[esp+10h]
132 mov edx,[esp+14h]
133 mov ecx,[esp+18h]
134 mov ah,[esp+20h]
135 add esp,32h
136 sahf
137 mov eax,[esp-32h+1Ch]
138 ret
139 create:
140 push esi edi ebp
141 call adapt_path
142 mov ax,716Ch
143 mov bx,100001b
144 mov dx,10010b
145 xor cx,cx
146 xor si,si
147 xor di,di
148 call dos_int
149 jnc create_done
150 cmp ax,7100h
151 je old_create
152 stc
153 jmp create_done
154 old_create:
155 mov ah,3Ch
156 xor cx,cx
157 xor dx,dx
158 call dos_int
159 create_done:
160 mov bx,ax
161 pop ebp edi esi
162 ret
163 write:
164 push edx esi edi ebp
165 mov ebp,ecx
166 mov esi,edx
167 write_loop:
168 mov ecx,1000h
169 sub ebp,1000h
170 jnc do_write
171 add ebp,1000h
172 mov ecx,ebp
173 xor ebp,ebp
174 do_write:
175 push ecx
176 mov edi,buffer
177 shr ecx,2
178 rep movsd
179 mov ecx,[esp]
180 and ecx,11b
181 rep movsb
182 pop ecx
183 mov ah,40h
184 xor dx,dx
185 call dos_int
186 or ebp,ebp
187 jnz write_loop
188 pop ebp edi esi edx
189 ret
190 read:
191 push edx esi edi ebp
192 mov ebp,ecx
193 mov edi,edx
194 read_loop:
195 mov ecx,1000h
196 sub ebp,1000h
197 jnc do_read
198 add ebp,1000h
199 mov ecx,ebp
200 xor ebp,ebp
201 do_read:
202 push ecx
203 mov ah,3Fh
204 xor dx,dx
205 call dos_int
206 cmp ax,cx
207 jne eof
208 mov esi,buffer
209 mov ecx,[esp]
210 shr ecx,2
211 rep movsd
212 pop ecx
213 and ecx,11b
214 rep movsb
215 or ebp,ebp
216 jnz read_loop
217 read_done:
218 pop ebp edi esi edx
219 ret
220 eof:
221 pop ecx
222 stc
223 jmp read_done
224 close:
225 mov ah,3Eh
226 int 21h
227 ret
228 lseek:
229 mov ah,42h
230 mov ecx,edx
231 shr ecx,16
232 int 21h
233 pushf
234 shl edx,16
235 popf
236 mov dx,ax
237 mov eax,edx
238 ret
0
1 macro ccall proc,[arg]
2 { common
3 push ebp
4 mov ebp,esp
5 local size
6 size = 0
7 if ~ arg eq
8 forward
9 size = size + 4
10 common
11 sub esp,size
12 end if
13 and esp,-16
14 if ~ arg eq
15 add esp,size
16 reverse
17 pushd arg
18 common
19 end if
20 call proc
21 leave }
22
0
1 format ELF
2 public main
3
4 include 'ccall.inc'
5
6 section '.text' executable align 16
7
8 main:
9 mov ecx,[esp+4]
10 mov [argc],ecx
11 mov ebx,[esp+8]
12 mov [argv],ebx
13
14 mov [display_handle],1
15
16 call get_params
17 jnc make_listing
18
19 mov esi,_usage
20 call display_string
21 ccall exit,2
22
23 make_listing:
24 call listing
25 ccall exit,0
26
27 error:
28 mov [display_handle],2
29 mov esi,_error_prefix
30 call display_string
31 pop esi
32 call display_string
33 mov esi,_error_suffix
34 call display_string
35 ccall exit,0
36
37 get_params:
38 mov ecx,[argc]
39 mov ebx,[argv]
40 add ebx,4
41 dec ecx
42 jz bad_params
43 get_param:
44 mov esi,[ebx]
45 mov al,[esi]
46 cmp al,'-'
47 je option_param
48 cmp [input_file],0
49 jne get_output_file
50 mov [input_file],esi
51 jmp next_param
52 get_output_file:
53 cmp [output_file],0
54 jne bad_params
55 mov [output_file],esi
56 jmp next_param
57 option_param:
58 inc esi
59 lodsb
60 cmp al,'a'
61 je addresses_option
62 cmp al,'A'
63 je addresses_option
64 cmp al,'b'
65 je bytes_per_line_option
66 cmp al,'B'
67 je bytes_per_line_option
68 bad_params:
69 stc
70 ret
71 addresses_option:
72 cmp byte [esi],0
73 jne bad_params
74 mov [show_addresses],1
75 jmp next_param
76 bytes_per_line_option:
77 cmp byte [esi],0
78 jne get_bytes_per_line_setting
79 dec ecx
80 jz bad_params
81 add ebx,4
82 mov esi,[ebx]
83 get_bytes_per_line_setting:
84 call get_option_value
85 or edx,edx
86 jz bad_params
87 cmp edx,1000
88 ja bad_params
89 mov [code_bytes_per_line],edx
90 next_param:
91 add ebx,4
92 dec ecx
93 jnz get_param
94 cmp [input_file],0
95 je bad_params
96 cmp [output_file],0
97 je bad_params
98 clc
99 ret
100 get_option_value:
101 xor eax,eax
102 mov edx,eax
103 get_option_digit:
104 lodsb
105 cmp al,20h
106 je option_value_ok
107 cmp al,0Dh
108 je option_value_ok
109 or al,al
110 jz option_value_ok
111 sub al,30h
112 jc invalid_option_value
113 cmp al,9
114 ja invalid_option_value
115 imul edx,10
116 jo invalid_option_value
117 add edx,eax
118 jc invalid_option_value
119 jmp get_option_digit
120 option_value_ok:
121 dec esi
122 clc
123 ret
124 invalid_option_value:
125 stc
126 ret
127
128 include 'system.inc'
129
130 include '..\listing.inc'
131
132 section '.data' writeable align 4
133
134 input_file dd 0
135 output_file dd 0
136 code_bytes_per_line dd 16
137 show_addresses db 0
138
139 line_break db 0Dh,0Ah
140
141 _usage db 'listing generator for flat assembler',0Dh,0Ah
142 db 'usage: listing <input> <output>',0Dh,0Ah
143 db 'optional settings:',0Dh,0Ah
144 db ' -a show target addresses for assembled code',0Dh,0Ah
145 db ' -b <number> set the amount of bytes listed per line',0Dh,0Ah
146 db 0
147 _error_prefix db 'error: ',0
148 _error_suffix db '.',0Dh,0Ah,0
149
150 section '.bss' writeable align 4
151
152 argc dd ?
153 argv dd ?
154
155 input dd ?
156 assembled_code dd ?
157 assembled_code_length dd ?
158 code_end dd ?
159 code_offset dd ?
160 code_length dd ?
161 output_handle dd ?
162 output_buffer dd ?
163 current_source_file dd ?
164 current_source_line dd ?
165 source dd ?
166 source_length dd ?
167 maximum_address_length dd ?
168 address_start dd ?
169 last_listed_address dd ?
170
171 display_handle dd ?
172 character db ?
173
174 params rb 1000h
175 characters rb 100h
176 buffer rb 1000h
0
1 format ELF
2 public main
3
4 include 'ccall.inc'
5
6 section '.text' executable align 16
7
8 main:
9 mov ecx,[esp+4]
10 mov [argc],ecx
11 mov ebx,[esp+8]
12 mov [argv],ebx
13
14 mov [display_handle],1
15
16 call get_params
17 jnc make_dump
18
19 mov esi,_usage
20 call display_string
21 ccall exit,2
22
23 make_dump:
24 call preprocessed_source
25 ccall exit,0
26
27 error:
28 mov [display_handle],2
29 mov esi,_error_prefix
30 call display_string
31 pop esi
32 call display_string
33 mov esi,_error_suffix
34 call display_string
35 ccall exit,0
36
37 get_params:
38 mov ecx,[argc]
39 mov ebx,[argv]
40 add ebx,4
41 dec ecx
42 jz bad_params
43 get_param:
44 mov esi,[ebx]
45 mov al,[esi]
46 cmp [input_file],0
47 jne get_output_file
48 mov [input_file],esi
49 jmp next_param
50 get_output_file:
51 cmp [output_file],0
52 jne bad_params
53 mov [output_file],esi
54 jmp next_param
55 bad_params:
56 stc
57 ret
58 next_param:
59 add ebx,4
60 dec ecx
61 jnz get_param
62 cmp [input_file],0
63 je bad_params
64 cmp [output_file],0
65 je bad_params
66 clc
67 ret
68
69 include 'system.inc'
70
71 include '..\prepsrc.inc'
72
73 section '.data' writeable align 4
74
75 input_file dd 0
76 output_file dd 0
77
78 _usage db 'preprocessed source dumper for flat assembler',0Dh,0Ah
79 db 'usage: prepsrc <input> <output>',0Dh,0Ah
80 db 0
81 _error_prefix db 'error: ',0
82 _error_suffix db '.',0Dh,0Ah,0
83
84 section '.bss' writeable align 4
85
86 argc dd ?
87 argv dd ?
88
89 display_handle dd ?
90 character db ?
91
92 params rb 1000h
93 buffer rb 1000h
0
1 format ELF
2 public main
3
4 include 'ccall.inc'
5
6 section '.text' executable align 16
7
8 main:
9 mov ecx,[esp+4]
10 mov [argc],ecx
11 mov ebx,[esp+8]
12 mov [argv],ebx
13
14 mov [display_handle],1
15
16 call get_params
17 jnc make_dump
18
19 mov esi,_usage
20 call display_string
21 ccall exit,2
22
23 make_dump:
24 call symbols
25 ccall exit,0
26
27 error:
28 mov [display_handle],2
29 mov esi,_error_prefix
30 call display_string
31 pop esi
32 call display_string
33 mov esi,_error_suffix
34 call display_string
35 ccall exit,0
36
37 get_params:
38 mov ecx,[argc]
39 mov ebx,[argv]
40 add ebx,4
41 dec ecx
42 jz bad_params
43 get_param:
44 mov esi,[ebx]
45 mov al,[esi]
46 cmp [input_file],0
47 jne get_output_file
48 mov [input_file],esi
49 jmp next_param
50 get_output_file:
51 cmp [output_file],0
52 jne bad_params
53 mov [output_file],esi
54 jmp next_param
55 bad_params:
56 stc
57 ret
58 next_param:
59 add ebx,4
60 dec ecx
61 jnz get_param
62 cmp [input_file],0
63 je bad_params
64 cmp [output_file],0
65 je bad_params
66 clc
67 ret
68
69 include 'system.inc'
70
71 include '..\symbols.inc'
72
73 section '.data' writeable align 4
74
75 input_file dd 0
76 output_file dd 0
77
78 _usage db 'symbols dumper for flat assembler',0Dh,0Ah
79 db 'usage: symbols <input> <output>',0Dh,0Ah
80 db 0
81 _error_prefix db 'error: ',0
82 _error_suffix db '.',0Dh,0Ah,0
83
84 section '.bss' writeable align 4
85
86 input dd ?
87 output_buffer dd ?
88 output_handle dd ?
89
90 argc dd ?
91 argv dd ?
92
93 display_handle dd ?
94 character db ?
95
96 params rb 1000h
97 buffer rb 1000h
0
1 extrn malloc
2 extrn getenv
3 extrn fopen
4 extrn fclose
5 extrn fread
6 extrn fwrite
7 extrn fseek
8 extrn ftell
9 extrn time
10 extrn exit
11 extrn 'free' as libc_free
12 extrn 'write' as libc_write
13
14 alloc:
15 ccall malloc,eax
16 test eax,eax
17 jz allocation_failed
18 clc
19 ret
20 allocation_failed:
21 stc
22 ret
23 free:
24 ccall libc_free,eax
25 ret
26 display_string:
27 lodsb
28 or al,al
29 jz string_displayed
30 mov dl,al
31 call display_character
32 jmp display_string
33 string_displayed:
34 ret
35 display_character:
36 mov [character],dl
37 ccall libc_write,[display_handle],character,1
38 ret
39 open:
40 push esi edi ebp
41 call adapt_path
42 ccall fopen,buffer,open_mode
43 pop ebp edi esi
44 or eax,eax
45 jz file_error
46 mov ebx,eax
47 clc
48 ret
49 adapt_path:
50 mov esi,edx
51 mov edi,buffer
52 copy_path:
53 lods byte [esi]
54 cmp al,'\'
55 jne path_char_ok
56 mov al,'/'
57 path_char_ok:
58 stos byte [edi]
59 or al,al
60 jnz copy_path
61 cmp edi,buffer+1000h
62 ja not_enough_memory
63 ret
64 create:
65 push esi edi ebp
66 call adapt_path
67 ccall fopen,buffer,create_mode
68 pop ebp edi esi
69 or eax,eax
70 jz file_error
71 mov ebx,eax
72 clc
73 ret
74 close:
75 ccall fclose,ebx
76 ret
77 read:
78 push ebx ecx edx esi edi
79 ccall fread,edx,1,ecx,ebx
80 pop edi esi edx ecx ebx
81 cmp eax,ecx
82 jne file_error
83 clc
84 ret
85 file_error:
86 stc
87 ret
88 write:
89 push ebx ecx edx esi edi
90 ccall fwrite,edx,1,ecx,ebx
91 pop edi esi edx ecx ebx
92 cmp eax,ecx
93 jne file_error
94 clc
95 ret
96 lseek:
97 push ebx
98 movzx eax,al
99 ccall fseek,ebx,edx,eax
100 mov ebx,[esp]
101 ccall ftell,ebx
102 pop ebx
103 ret
104
105 open_mode db 'r',0
106 create_mode db 'w',0
0
1 listing:
2 mov edx,[input_file]
3 call open
4 jc input_not_found
5 call load_file
6 mov [input],eax
7 cmp ecx,38h
8 jb invalid_input
9 cmp dword [eax],1A736166h
10 jne invalid_input
11 cmp dword [eax+44],0
12 je incomplete_input
13 add [eax+16],eax
14 add [eax+24],eax
15 add [eax+32],eax
16 add [eax+40],eax
17 add [eax+48],eax
18 mov edx,[eax+16]
19 add [eax+8],edx
20 add [eax+12],edx
21 mov edx,[eax+12]
22 call open
23 jc code_not_found
24 call load_file
25 mov [assembled_code],eax
26 mov [assembled_code_length],ecx
27 call close
28 mov [maximum_address_length],0
29 mov ebx,[input]
30 mov esi,[ebx+40]
31 lea ebp,[esi-4]
32 add ebp,[ebx+44]
33 get_offsets_for_lines:
34 cmp esi,ebp
35 je offsets_prepared
36 mov edx,[esi+4]
37 add edx,[ebx+32]
38 find_line_loaded_from_source:
39 test byte [edx+7],1 shl 7
40 jz store_offset_in_line
41 mov edx,[edx+8]
42 add edx,[ebx+32]
43 jmp find_line_loaded_from_source
44 store_offset_in_line:
45 cmp dword [edx+12],0
46 jne get_next_offset
47 mov [edx+12],esi
48 movzx ecx,byte [esi+27]
49 and cl,1
50 mov edi,[esi+20]
51 test edi,edi
52 jz base_name_length_ok
53 xor ecx,ecx
54 btr edi,31
55 jc count_base_name_characters
56 dec edi
57 shl edi,2
58 add edi,[ebx+48]
59 mov edi,[edi]
60 count_base_name_characters:
61 mov ecx,[ebx+20]
62 sub ecx,edi
63 add edi,[ebx+16]
64 mov edx,edi
65 xor al,al
66 repne scasb
67 mov ecx,edi
68 sub ecx,edx
69 base_name_length_ok:
70 cmp byte [esi+18],1
71 jb first_register_length_ok
72 ja first_register_with_scale
73 add ecx,5
74 jmp first_register_length_ok
75 first_register_with_scale:
76 add ecx,5+3
77 first_register_length_ok:
78 cmp byte [esi+19],1
79 jb second_register_length_ok
80 ja second_register_with_scale
81 add ecx,5
82 jmp second_register_length_ok
83 second_register_with_scale:
84 add ecx,5+3
85 second_register_length_ok:
86 cmp ecx,[maximum_address_length]
87 jb get_next_offset
88 mov [maximum_address_length],ecx
89 get_next_offset:
90 add esi,28
91 jmp get_offsets_for_lines
92 offsets_prepared:
93 mov eax,[esi]
94 mov [code_end],eax
95 add [maximum_address_length],19
96 mov edi,characters
97 xor al,al
98 make_characters_table:
99 stosb
100 inc al
101 jnz make_characters_table
102 mov edi,characters
103 mov esi,symbol_characters+1
104 movzx ecx,byte [esi-1]
105 xor eax,eax
106 mark_symbol_characters:
107 lodsb
108 mov byte [edi+eax],0
109 loop mark_symbol_characters
110 mov eax,[code_bytes_per_line]
111 imul eax,3
112 add eax,[maximum_address_length]
113 add eax,18
114 call alloc
115 jc not_enough_memory
116 mov [output_buffer],eax
117 mov esi,[ebx+32]
118 mov ebp,esi
119 add ebp,[ebx+36]
120 mov edx,[output_file]
121 call create
122 jc writing_error
123 mov [output_handle],ebx
124 xor eax,eax
125 mov [current_source_file],eax
126 mov [last_listed_address],eax
127 mov [code_length],eax
128 generate_listing:
129 cmp esi,ebp
130 jae listing_done
131 mov edi,[output_buffer]
132 test byte [esi+7],1 shl 7
133 jnz next_line
134 mov ebx,[esi+12]
135 test ebx,ebx
136 jz no_code_listing
137 test byte [ebx+26],11b
138 jnz no_code_listing
139 push esi
140 mov edx,[esi]
141 mov ecx,[esi+4]
142 find_next_code_point:
143 add esi,16
144 call skip_preprocessed_line
145 cmp esi,ebp
146 je last_code_point
147 cmp edx,[esi]
148 jne next_line_ok
149 cmp ecx,[esi+4]
150 je find_next_code_point
151 next_line_ok:
152 test byte [esi+7],1 shl 7
153 jnz find_next_code_point
154 mov eax,[esi+12]
155 test eax,eax
156 jz find_next_code_point
157 test byte [eax+26],11b
158 jnz find_next_code_point
159 mov eax,[eax]
160 jmp calculate_code_length
161 last_code_point:
162 mov eax,[code_end]
163 calculate_code_length:
164 pop esi
165 mov edx,[ebx]
166 sub eax,edx
167 jz no_code_listing
168 mov [code_length],eax
169 mov [code_offset],edx
170 add eax,edx
171 cmp eax,[assembled_code_length]
172 jbe write_file_offset
173 mov [code_length],0
174 write_file_offset:
175 call write_hex_dword
176 mov ax,': '
177 stosw
178 call list_address
179 call list_code
180 jmp code_listing_ok
181 no_code_listing:
182 mov al,20h
183 mov ecx,8+2
184 rep stosb
185 call list_address
186 mov ecx,[code_bytes_per_line]
187 imul ecx,3
188 mov al,20h
189 rep stosb
190 code_listing_ok:
191 call write_listing_data
192 mov eax,[input]
193 mov edx,[esi]
194 test edx,edx
195 jz main_source_file
196 add edx,[eax+32]
197 jmp source_name_ok
198 main_source_file:
199 mov edx,[eax+8]
200 source_name_ok:
201 cmp edx,[current_source_file]
202 je source_loaded
203 push ebx
204 push edx
205 call open
206 jc source_not_found
207 pop eax
208 xchg eax,[current_source_file]
209 test eax,eax
210 jz load_source
211 mov eax,[source]
212 call free
213 load_source:
214 call load_file
215 mov [source],eax
216 mov [source_length],ecx
217 call close
218 pop ebx
219 source_loaded:
220 mov eax,[source]
221 add eax,[esi+8]
222 mov [current_source_line],eax
223 push esi ebp
224 call write_source_line
225 pop ebp esi
226 write_supplemental_rows:
227 mov eax,[code_length]
228 or eax,[current_source_line]
229 jz next_line
230 mov edi,[output_buffer]
231 mov ecx,8+2
232 movzx eax,[show_addresses]
233 imul eax,[maximum_address_length]
234 add ecx,eax
235 mov al,20h
236 rep stosb
237 call list_code
238 call write_listing_data
239 push esi ebp
240 call write_source_line
241 pop ebp esi
242 jmp write_supplemental_rows
243 next_line:
244 mov edx,[esi]
245 mov ecx,[esi+4]
246 find_next_line:
247 add esi,16
248 call skip_preprocessed_line
249 cmp edx,[esi]
250 jne generate_listing
251 cmp ecx,[esi+4]
252 jne generate_listing
253 jmp find_next_line
254 list_address:
255 cmp [show_addresses],0
256 je address_ok
257 mov [address_start],edi
258 mov eax,[esi+12]
259 test eax,eax
260 jz address_finished
261 cmp [last_listed_address],0
262 je make_address
263 push esi edi
264 lea esi,[eax+8]
265 mov edi,[last_listed_address]
266 mov ecx,17
267 repe cmpsb
268 pop edi esi
269 je address_finished
270 make_address:
271 mov ebx,[esi+12]
272 lea eax,[ebx+8]
273 mov [last_listed_address],eax
274 mov al,'['
275 stosb
276 mov edx,[ebx+20]
277 test edx,edx
278 jz write_main_address
279 push esi
280 mov esi,edx
281 mov eax,[input]
282 btr esi,31
283 jc base_name_ready
284 dec esi
285 shl esi,2
286 add esi,[eax+48]
287 mov esi,[esi]
288 base_name_ready:
289 add esi,[eax+16]
290 copy_section_name:
291 lodsb
292 test al,al
293 jz section_name_ok
294 stosb
295 jmp copy_section_name
296 section_name_ok:
297 pop esi
298 mov al,':'
299 test edx,80000000h
300 jz address_separator_ok
301 cmp byte [ebx+27],0
302 jne address_separator_ok
303 mov al,'+'
304 address_separator_ok:
305 stosb
306 write_main_address:
307 cmp byte [ebx+27],0
308 jne write_negative_address
309 mov edx,[ebx+8+4]
310 call write_hex_dword
311 mov edx,[ebx+8]
312 call write_hex_dword
313 jmp write_address_registers
314 write_negative_address:
315 mov al,'-'
316 stosb
317 mov eax,[ebx+8]
318 mov edx,[ebx+8+4]
319 not eax
320 not edx
321 add eax,1
322 adc edx,0
323 push eax
324 call write_hex_dword
325 pop edx
326 call write_hex_dword
327 write_address_registers:
328 mov dl,[ebx+16]
329 mov dh,[ebx+18]
330 call address_register
331 mov dl,[ebx+17]
332 mov dh,[ebx+19]
333 call address_register
334 mov ax,']'
335 stosb
336 address_finished:
337 mov ecx,[maximum_address_length]
338 sub ecx,edi
339 add ecx,[address_start]
340 mov al,20h
341 rep stosb
342 address_ok:
343 ret
344 address_register:
345 cmp dh,0
346 je register_ok
347 jl negative_register
348 mov al,'+'
349 jmp register_sign_ok
350 negative_register:
351 mov al,'-'
352 register_sign_ok:
353 stosb
354 push esi
355 mov esi,address_registers
356 find_register:
357 lodsb
358 test al,al
359 jz register_found
360 cmp al,dl
361 je register_found
362 cmp dl,[esi]
363 je register_found
364 lodsb
365 movzx eax,al
366 add esi,eax
367 jmp find_register
368 register_found:
369 lodsb
370 movzx ecx,al
371 rep movsb
372 pop esi
373 cmp dh,1
374 je register_ok
375 mov al,'*'
376 stosb
377 test dh,0F0h
378 jz first_scale_digit_ok
379 mov al,dh
380 shr al,4
381 cmp al,10
382 sbb al,69h
383 das
384 stosb
385 first_scale_digit_ok:
386 mov al,dh
387 and al,1111b
388 cmp al,10
389 sbb al,69h
390 das
391 stosb
392 register_ok:
393 ret
394 list_code:
395 mov ecx,[code_length]
396 cmp ecx,[code_bytes_per_line]
397 jb code_bytes_count_ready
398 mov ecx,[code_bytes_per_line]
399 code_bytes_count_ready:
400 sub [code_length],ecx
401 mov edx,[code_offset]
402 add [code_offset],ecx
403 jecxz code_bytes_ok
404 push ecx
405 add edx,[assembled_code]
406 list_code_bytes:
407 mov al,[edx]
408 and al,1111b
409 cmp al,10
410 sbb al,69h
411 das
412 mov ah,al
413 mov al,[edx]
414 shr al,4
415 cmp al,10
416 sbb al,69h
417 das
418 stosw
419 mov al,20h
420 stosb
421 inc edx
422 loop list_code_bytes
423 pop ecx
424 code_bytes_ok:
425 neg ecx
426 add ecx,[code_bytes_per_line]
427 imul ecx,3
428 mov al,20h
429 rep stosb
430 ret
431 write_listing_data:
432 mov ecx,[output_buffer]
433 sub ecx,edi
434 and ecx,111b
435 mov al,20h
436 rep stosb
437 mov edx,[output_buffer]
438 mov ecx,edi
439 sub ecx,edx
440 mov ebx,[output_handle]
441 call write
442 jc writing_error
443 ret
444 write_source_line:
445 mov esi,[current_source_line]
446 test esi,esi
447 je write_line_break
448 mov ebp,[source_length]
449 add ebp,[source]
450 mov ebx,characters
451 xor cl,cl
452 start_cutting:
453 xor dl,dl
454 cut_source_line:
455 cmp esi,ebp
456 je end_of_file
457 lodsb
458 cmp al,0Dh
459 je cr_character
460 cmp al,0Ah
461 je lf_character
462 cmp al,1Ah
463 je end_of_line
464 or al,al
465 jz end_of_line
466 cmp dl,3Bh
467 je cut_source_line
468 cmp al,3Bh
469 je start_special_block
470 cmp dl,22h
471 je inside_string
472 cmp dl,27h
473 je inside_string
474 cmp al,'\'
475 je check_for_line_continuation
476 xlatb
477 test al,al
478 jz start_cutting
479 cmp dl,0FFh
480 je cut_source_line
481 cmp al,22h
482 je start_special_block
483 cmp al,27h
484 je start_special_block
485 mov dl,0FFh
486 jmp cut_source_line
487 start_special_block:
488 mov dl,al
489 jmp cut_source_line
490 inside_string:
491 cmp al,dl
492 jne cut_source_line
493 jmp start_cutting
494 check_for_line_continuation:
495 or cl,0FFh
496 cmp esi,ebp
497 je end_of_file
498 mov al,[esi]
499 cmp al,20h
500 je start_cutting
501 cmp al,0Dh
502 je start_cutting
503 cmp al,0Ah
504 je start_cutting
505 cmp al,3Bh
506 je start_cutting
507 xor cl,cl
508 jmp start_cutting
509 cr_character:
510 mov edx,esi
511 mov word [line_break],0Dh
512 cmp esi,ebp
513 je line_with_break
514 mov al,[esi]
515 cmp al,0Ah
516 jne line_with_break
517 inc edx
518 mov [line_break+1],al
519 jmp line_with_break
520 lf_character:
521 mov edx,esi
522 mov word [line_break],0Ah
523 cmp esi,ebp
524 je line_with_break
525 mov al,[esi]
526 cmp al,0Dh
527 jne line_with_break
528 inc edx
529 mov [line_break+1],al
530 line_with_break:
531 dec esi
532 jmp write_line
533 end_of_line:
534 dec esi
535 end_of_file:
536 mov edx,esi
537 write_line:
538 cmp cl,0FFh
539 je continued_line
540 xor edx,edx
541 continued_line:
542 xchg edx,[current_source_line]
543 mov ecx,esi
544 sub ecx,edx
545 mov ebx,[output_handle]
546 call write
547 jc writing_error
548 write_line_break:
549 mov edx,line_break
550 mov ecx,2
551 cmp [line_break+1],0
552 jne line_break_size_ok
553 dec ecx
554 line_break_size_ok:
555 call write
556 jc writing_error
557 ret
558 listing_done:
559 mov ebx,[output_handle]
560 call close
561 ret
562
563 load_file:
564 push ebx
565 mov al,2
566 xor edx,edx
567 call lseek
568 test eax,eax
569 jz empty_file
570 push eax
571 call alloc
572 jc not_enough_memory
573 push eax
574 xor al,al
575 xor edx,edx
576 call lseek
577 mov ecx,[esp+4]
578 mov edx,[esp]
579 call read
580 jc reading_error
581 pop eax ecx
582 pop ebx
583 ret
584 empty_file:
585 pop ebx
586 mov ecx,eax
587 ret
588
589 write_hex_dword:
590 mov ecx,8
591 write_hex_digits:
592 xor al,al
593 shld eax,edx,4
594 cmp al,10
595 sbb al,69h
596 das
597 stosb
598 shl edx,4
599 loop write_hex_digits
600 ret
601
602 skip_preprocessed_line:
603 lods byte [esi]
604 cmp al,1Ah
605 je skip_preprocessed_symbol
606 cmp al,3Bh
607 je skip_preprocessed_symbol
608 cmp al,22h
609 je skip_preprocessed_string
610 or al,al
611 jnz skip_preprocessed_line
612 ret
613 skip_preprocessed_symbol:
614 lods byte [esi]
615 movzx eax,al
616 add esi,eax
617 jmp skip_preprocessed_line
618 skip_preprocessed_string:
619 lods dword [esi]
620 add esi,eax
621 jmp skip_preprocessed_line
622
623
624 not_enough_memory:
625 call error
626 db 'not enough memory to load the required data',0
627 input_not_found:
628 call error
629 db 'the input file was not found',0
630 code_not_found:
631 call error
632 db 'the assembled file was not found',0
633 source_not_found:
634 call error
635 db 'could not find some of the source files',0
636 reading_error:
637 call error
638 db 'some error occured while trying to read file',0
639 writing_error:
640 call error
641 db 'some error occured while trying to write file',0
642 invalid_input:
643 call error
644 db 'input file is not a recognized assembly information format',0
645 incomplete_input:
646 call error
647 db 'input file does not contain an assembly dump',0
648
649 symbol_characters db 27, 9,0Ah,0Dh,1Ah,20h,'+-/*=<>()[]{}:,|&~#`;\'
650
651 address_registers db 23h,2,'bx'
652 db 25h,2,'bp'
653 db 26h,2,'si'
654 db 27h,2,'di'
655 db 40h,3,'eax'
656 db 41h,3,'ecx'
657 db 42h,3,'edx'
658 db 43h,3,'ebx'
659 db 44h,3,'esp'
660 db 45h,3,'ebp'
661 db 46h,3,'esi'
662 db 47h,3,'edi'
663 db 48h,3,'r8d'
664 db 49h,3,'r9d'
665 db 4Ah,4,'r10d'
666 db 4Bh,4,'r11d'
667 db 4Ch,4,'r12d'
668 db 4Dh,4,'r13d'
669 db 4Eh,4,'r14d'
670 db 4Fh,4,'r15d'
671 db 80h,3,'rax'
672 db 81h,3,'rcx'
673 db 82h,3,'rdx'
674 db 83h,3,'rbx'
675 db 84h,3,'rsp'
676 db 85h,3,'rbp'
677 db 86h,3,'rsi'
678 db 87h,3,'rdi'
679 db 88h,2,'r8'
680 db 89h,2,'r9'
681 db 8Ah,3,'r10'
682 db 8Bh,3,'r11'
683 db 8Ch,3,'r12'
684 db 8Dh,3,'r13'
685 db 8Eh,3,'r14'
686 db 8Fh,3,'r15'
687 db 0F4h,3,'eip'
688 db 0F8h,3,'rip'
689 db 0,1,'?'
0
1 preprocessed_source:
2 mov edx,[input_file]
3 call open
4 jc input_not_found
5 mov al,2
6 xor edx,edx
7 call lseek
8 cmp eax,30h
9 jb invalid_input
10 push eax
11 call alloc
12 jc not_enough_memory
13 push eax
14 xor al,al
15 xor edx,edx
16 call lseek
17 mov ecx,[esp+4]
18 mov edx,[esp]
19 call read
20 jc reading_error
21 pop eax ecx
22 cmp dword [eax],1A736166h
23 jne invalid_input
24 mov esi,[eax+32]
25 add esi,eax
26 mov ebp,[eax+36]
27 add ebp,esi
28 mov edi,eax
29 push eax
30 preprocessed_to_text:
31 cmp esi,ebp
32 jae conversion_done
33 add esi,16
34 xor dl,dl
35 convert_preprocessed_line:
36 lodsb
37 cmp al,1Ah
38 je copy_symbol
39 cmp al,22h
40 je copy_symbol
41 cmp al,3Bh
42 je preprocessor_symbols
43 or al,al
44 jz line_converted
45 stosb
46 xor dl,dl
47 jmp convert_preprocessed_line
48 copy_symbol:
49 or dl,dl
50 jz space_ok
51 mov byte [edi],20h
52 inc edi
53 space_ok:
54 cmp al,22h
55 je quoted
56 lodsb
57 movzx ecx,al
58 rep movsb
59 or dl,-1
60 jmp convert_preprocessed_line
61 quoted:
62 mov al,27h
63 stosb
64 lodsd
65 mov ecx,eax
66 jecxz quoted_copied
67 copy_quoted:
68 lodsb
69 stosb
70 cmp al,27h
71 jne quote_ok
72 stosb
73 quote_ok:
74 loop copy_quoted
75 quoted_copied:
76 mov al,27h
77 stosb
78 or dl,-1
79 jmp convert_preprocessed_line
80 preprocessor_symbols:
81 mov al,3Bh
82 stosb
83 jmp copy_symbol
84 line_converted:
85 mov ax,0A0Dh
86 stosw
87 jmp preprocessed_to_text
88 conversion_done:
89 mov edx,[output_file]
90 call create
91 jc writing_error
92 pop edx
93 mov ecx,edi
94 sub ecx,edx
95 call write
96 jc writing_error
97 call close
98 ret
99
100 not_enough_memory:
101 call error
102 db 'not enough memory to load the required data',0
103 input_not_found:
104 call error
105 db 'the input file was not found',0
106 reading_error:
107 call error
108 db 'some error occured while trying to read file',0
109 writing_error:
110 call error
111 db 'some error occured while trying to write file',0
112 invalid_input:
113 call error
114 db 'input file is not a recognized assembly information format',0
0
1 This directory contains some tools, which extract various types of information
2 from the symbolic information file generated by flat assembler, and present
3 them in a human-readable form.
4
5 The listing tool creates a listing of assembled code - this tool needs to be
6 executed in the exact configuration, in which the assembly was taking place.
7 All the source files and the output file aswell must not have been moved or
8 modified - if any of them was altered before generating the listing, it is
9 going to contain garbage instead of useful information. For example, if you
10 assembled the file with the command like:
11
12 fasm example.asm example.exe -s example.fas
13
14 you should generate listing by immediately running this command from the same
15 directory:
16
17 listing example.fas example.lst
18
19 In addition, the "-a" switch is recommended to use in the case of executable
20 formats, as it allows to get the run-time addresses for all the assembled code
21 and data.
22
23 The preprocessed source and symbols dump tools are simpler ones - they only
24 need the symbolic information file as input and generate proper output text
25 regardless of the availability of other files.
0
1 symbols:
2 mov edx,[input_file]
3 call open
4 jc input_not_found
5 mov al,2
6 xor edx,edx
7 call lseek
8 cmp eax,30h
9 jb invalid_input
10 push eax
11 call alloc
12 jc not_enough_memory
13 push eax
14 xor al,al
15 xor edx,edx
16 call lseek
17 mov ecx,[esp+4]
18 mov edx,[esp]
19 call read
20 jc reading_error
21 pop eax ecx
22 cmp dword [eax],1A736166h
23 jne invalid_input
24 mov [input],eax
25 add [eax+16],eax
26 add [eax+24],eax
27 add [eax+32],eax
28 add [eax+48],eax
29 mov edx,[eax+16]
30 add [eax+8],edx
31
32 mov ebx,eax
33 mov eax,[ebx+20]
34 add eax,[ebx+36]
35 cmp eax,1000h
36 ja allocate_output_buffer
37 mov eax,1000h
38 allocate_output_buffer:
39 call alloc
40 jc not_enough_memory
41 mov [output_buffer],eax
42
43 mov edx,[output_file]
44 call create
45 jc writing_error
46 mov [output_handle],ebx
47
48 mov ebx,[input]
49 mov edx,[ebx+24]
50 mov ebp,[ebx+28]
51 add ebp,edx
52 dump_symbols:
53 cmp edx,ebp
54 je dump_done
55 test byte [edx+8],1
56 jz next_symbol
57 test byte [edx+9],4
58 jnz next_symbol
59 mov edi,[output_buffer]
60 mov esi,[edx+24]
61 test esi,esi
62 jz anonymous_symbol
63 mov ebx,[input]
64 btr esi,31
65 jc symbol_name_in_strings_table
66 add esi,[ebx+32]
67 lodsb
68 movzx ecx,al
69 rep movsb
70 jmp symbol_name_ok
71 symbol_name_in_strings_table:
72 add esi,[ebx+16]
73 call write_string
74 jmp symbol_name_ok
75 anonymous_symbol:
76 mov al,'@'
77 stosb
78 stosb
79 symbol_name_ok:
80 test byte [edx+9],2
81 jnz negative_value
82 mov eax,': 0x'
83 stosd
84 mov eax,[edx+4]
85 call write_hex_dword
86 mov eax,[edx]
87 call write_hex_dword
88 jmp write_address_registers
89 negative_value:
90 mov eax,': -0'
91 stosd
92 mov al,'x'
93 stosb
94 mov ecx,[edx]
95 mov eax,[edx+4]
96 not ecx
97 not eax
98 add ecx,1
99 adc eax,0
100 push ecx
101 or ecx,eax
102 jnz negative_value_ok
103 mov byte [edi],'1'
104 inc edi
105 negative_value_ok:
106 call write_hex_dword
107 pop eax
108 call write_hex_dword
109 write_address_registers:
110 mov bl,[edx+12]
111 mov bh,[edx+14]
112 call write_address_register
113 mov bl,[edx+13]
114 mov bh,[edx+15]
115 call write_address_register
116 mov bl,[edx+11]
117 cmp bl,0
118 je symbol_type_ok
119 jl negated_symbol
120 mov ax,', '
121 stosw
122 jmp write_symbol_type
123 negated_symbol:
124 mov ax,', '
125 stosw
126 mov esi,_negated
127 call write_string
128 neg bl
129 write_symbol_type:
130 cmp bl,1
131 je segment_type
132 cmp bl,5
133 je rva_type
134 cmp bl,6
135 je plt_type
136 test byte [edx+20+3],80h
137 jnz external
138 mov esi,_relocatable
139 call write_string
140 cmp dword [edx+20],0
141 je symbol_type_ok
142 mov esi,_in_section
143 call write_string
144 jmp write_symbol_base
145 simple_relocatable:
146 mov esi,_relocatable
147 call write_string
148 jmp symbol_type_ok
149 external:
150 mov esi,_relative_to_external
151 call write_string
152 jmp write_symbol_base
153 segment_type:
154 mov esi,_relocatable_segment
155 call write_string
156 jmp symbol_type_ok
157 rva_type:
158 mov esi,_rva
159 call write_string
160 jmp write_symbol_base
161 plt_type:
162 mov esi,_plt
163 call write_string
164 write_symbol_base:
165 mov esi,[edx+20]
166 btr esi,31
167 jc write_external_name
168 dec esi
169 shl esi,2
170 mov ebx,[input]
171 add esi,[ebx+48]
172 mov esi,[esi]
173 add esi,[ebx+16]
174 call write_string
175 mov al,'('
176 stosb
177 mov eax,[edx+20]
178 call write_dec_number
179 mov al,')'
180 stosb
181 jmp symbol_type_ok
182 write_external_name:
183 mov ebx,[input]
184 add esi,[ebx+16]
185 call write_string
186 jmp symbol_type_ok
187 symbol_type_ok:
188 mov esi,_defined
189 call write_string
190 mov ebx,[edx+28]
191 mov eax,[input]
192 add ebx,[eax+32]
193 call write_line_identifier
194 mov ax,0A0Dh
195 stosw
196 push edx
197 mov ebx,[output_handle]
198 mov ecx,edi
199 mov edx,[output_buffer]
200 sub ecx,edx
201 call write
202 pop edx
203 next_symbol:
204 add edx,32
205 jmp dump_symbols
206 dump_done:
207 mov ebx,[output_handle]
208 call close
209 ret
210
211 write_string:
212 lodsb
213 test al,al
214 jz string_ok
215 stosb
216 jmp write_string
217 string_ok:
218 ret
219 write_hex_dword:
220 mov ebx,eax
221 mov ecx,8
222 write_hex_digits:
223 xor al,al
224 shld eax,ebx,4
225 cmp al,10
226 sbb al,69h
227 das
228 stosb
229 shl ebx,4
230 loop write_hex_digits
231 ret
232 write_dec_number:
233 push ebx edx
234 mov ecx,1000000000
235 xor edx,edx
236 xor bl,bl
237 dec_number_loop:
238 div ecx
239 push edx
240 cmp ecx,1
241 je write_dec_digit
242 or bl,bl
243 jnz write_dec_digit
244 or al,al
245 jz dec_digit_ok
246 not bl
247 write_dec_digit:
248 add al,30h
249 stosb
250 dec_digit_ok:
251 mov eax,ecx
252 xor edx,edx
253 mov ecx,10
254 div ecx
255 mov ecx,eax
256 pop eax
257 or ecx,ecx
258 jnz dec_number_loop
259 pop edx ebx
260 ret
261 write_address_register:
262 cmp bh,0
263 je register_ok
264 jl negative_register
265 mov al,'+'
266 jmp register_sign_ok
267 negative_register:
268 mov al,'-'
269 register_sign_ok:
270 stosb
271 push esi
272 mov esi,address_registers
273 find_register:
274 lodsb
275 test al,al
276 jz register_found
277 cmp al,bl
278 je register_found
279 cmp bl,[esi]
280 je register_found
281 lodsb
282 movzx eax,al
283 add esi,eax
284 jmp find_register
285 register_found:
286 lodsb
287 movzx ecx,al
288 rep movsb
289 pop esi
290 cmp bh,1
291 je register_ok
292 mov al,'*'
293 stosb
294 movzx eax,bh
295 call write_dec_number
296 register_ok:
297 ret
298 write_line_identifier:
299 test dword [ebx+4],80000000h
300 jnz identify_macro_generated_line
301 mov esi,[ebx]
302 mov eax,[input]
303 test esi,esi
304 jz main_file
305 add esi,[eax+32]
306 jmp file_name_ok
307 main_file:
308 mov esi,[eax+8]
309 file_name_ok:
310 call write_string
311 mov al,'['
312 stosb
313 mov eax,[ebx+4]
314 call write_dec_number
315 mov al,']'
316 stosb
317 ret
318 identify_macro_generated_line:
319 mov al,'{'
320 stosb
321 mov esi,_generated_by
322 call write_string
323 push ebx
324 mov ebx,[ebx+8]
325 mov eax,[input]
326 add ebx,[eax+32]
327 call write_line_identifier
328 pop ebx
329 mov eax,[ebx+8]
330 cmp eax,[ebx+12]
331 je macro_generated_line_identifier_ok
332 mov esi,_from
333 call write_string
334 push ebx
335 mov ebx,[ebx+12]
336 mov eax,[input]
337 add ebx,[eax+32]
338 call write_line_identifier
339 pop ebx
340 macro_generated_line_identifier_ok:
341 mov al,'}'
342 stosb
343 ret
344
345 not_enough_memory:
346 call error
347 db 'not enough memory to load the required data',0
348 input_not_found:
349 call error
350 db 'the input file was not found',0
351 code_not_found:
352 call error
353 db 'the assembled file was not found',0
354 source_not_found:
355 call error
356 db 'could not find some of the source files',0
357 reading_error:
358 call error
359 db 'some error occured while trying to read file',0
360 writing_error:
361 call error
362 db 'some error occured while trying to write file',0
363 invalid_input:
364 call error
365 db 'input file is not a recognized assembly information format',0
366
367 address_registers db 23h,2,'bx'
368 db 25h,2,'bp'
369 db 26h,2,'si'
370 db 27h,2,'di'
371 db 40h,3,'eax'
372 db 41h,3,'ecx'
373 db 42h,3,'edx'
374 db 43h,3,'ebx'
375 db 44h,3,'esp'
376 db 45h,3,'ebp'
377 db 46h,3,'esi'
378 db 47h,3,'edi'
379 db 48h,3,'r8d'
380 db 49h,3,'r9d'
381 db 4Ah,4,'r10d'
382 db 4Bh,4,'r11d'
383 db 4Ch,4,'r12d'
384 db 4Dh,4,'r13d'
385 db 4Eh,4,'r14d'
386 db 4Fh,4,'r15d'
387 db 80h,3,'rax'
388 db 81h,3,'rcx'
389 db 82h,3,'rdx'
390 db 83h,3,'rbx'
391 db 84h,3,'rsp'
392 db 85h,3,'rbp'
393 db 86h,3,'rsi'
394 db 87h,3,'rdi'
395 db 88h,2,'r8'
396 db 89h,2,'r9'
397 db 8Ah,3,'r10'
398 db 8Bh,3,'r11'
399 db 8Ch,3,'r12'
400 db 8Dh,3,'r13'
401 db 8Eh,3,'r14'
402 db 8Fh,3,'r15'
403 db 0F4h,3,'eip'
404 db 0F8h,3,'rip'
405 db 0,1,'?'
406
407 _negated db 'negated ',0
408 _relocatable_segment db 'relocatable segment',0
409 _relocatable db 'relocatable',0
410 _in_section db ' in section ',0
411 _relative_to_external db 'relative to external ',0
412 _rva db 'relative to RVA or GOT-based offset of ',0
413 _plt db 'relative to address of PLT entry for ',0
414 _defined db ', defined in ',0
415 _generated_by db 'line generated by ',0
416 _from db ' from ',0
0
1 format PE console 4.0
2 entry start
3
4 include 'win32a.inc'
5
6 section '.data' data readable writeable
7
8 _usage db 'listing generator for flat assembler',0Dh,0Ah
9 db 'usage: listing <input> <output>',0Dh,0Ah
10 db 'optional settings:',0Dh,0Ah
11 db ' -a show target addresses for assembled code',0Dh,0Ah
12 db ' -b <number> set the amount of bytes listed per line',0Dh,0Ah
13 db 0
14 _error_prefix db 'error: ',0
15 _error_suffix db '.',0Dh,0Ah,0
16
17 line_break db 0Dh,0Ah
18
19 input_file dd 0
20 output_file dd 0
21 code_bytes_per_line dd 16
22 show_addresses db 0
23
24 input dd ?
25 assembled_code dd ?
26 assembled_code_length dd ?
27 code_end dd ?
28 code_offset dd ?
29 code_length dd ?
30 output_handle dd ?
31 output_buffer dd ?
32 current_source_file dd ?
33 current_source_line dd ?
34 source dd ?
35 source_length dd ?
36 maximum_address_length dd ?
37 address_start dd ?
38 last_listed_address dd ?
39
40 display_handle dd ?
41 bytes_count dd ?
42
43 params rb 1000h
44 characters rb 100h
45
46 section '.text' code readable executable
47
48 start:
49
50 mov [display_handle],STD_OUTPUT_HANDLE
51
52 call get_params
53 jnc make_listing
54
55 mov esi,_usage
56 call display_string
57 invoke ExitProcess,2
58
59 make_listing:
60 call listing
61 invoke ExitProcess,0
62
63 error:
64 mov [display_handle],STD_ERROR_HANDLE
65 mov esi,_error_prefix
66 call display_string
67 pop esi
68 call display_string
69 mov esi,_error_suffix
70 call display_string
71 invoke ExitProcess,1
72
73 get_params:
74 invoke GetCommandLine
75 mov esi,eax
76 mov edi,params
77 find_command_start:
78 lodsb
79 cmp al,20h
80 je find_command_start
81 cmp al,22h
82 je skip_quoted_name
83 skip_name:
84 lodsb
85 cmp al,20h
86 je find_param
87 or al,al
88 jz all_params
89 jmp skip_name
90 skip_quoted_name:
91 lodsb
92 cmp al,22h
93 je find_param
94 or al,al
95 jz all_params
96 jmp skip_quoted_name
97 find_param:
98 lodsb
99 cmp al,20h
100 je find_param
101 cmp al,'-'
102 je option_param
103 cmp al,0Dh
104 je all_params
105 or al,al
106 jz all_params
107 cmp [input_file],0
108 jne get_output_file
109 mov [input_file],edi
110 jmp process_param
111 get_output_file:
112 cmp [output_file],0
113 jne bad_params
114 mov [output_file],edi
115 process_param:
116 cmp al,22h
117 je string_param
118 copy_param:
119 stosb
120 lodsb
121 cmp al,20h
122 je param_end
123 cmp al,0Dh
124 je param_end
125 or al,al
126 jz param_end
127 jmp copy_param
128 string_param:
129 lodsb
130 cmp al,22h
131 je string_param_end
132 cmp al,0Dh
133 je param_end
134 or al,al
135 jz param_end
136 stosb
137 jmp string_param
138 option_param:
139 lodsb
140 cmp al,'a'
141 je addresses_option
142 cmp al,'A'
143 je addresses_option
144 cmp al,'b'
145 je bytes_per_line_option
146 cmp al,'B'
147 je bytes_per_line_option
148 bad_params:
149 stc
150 ret
151 get_option_value:
152 xor eax,eax
153 mov edx,eax
154 get_option_digit:
155 lodsb
156 cmp al,20h
157 je option_value_ok
158 cmp al,0Dh
159 je option_value_ok
160 or al,al
161 jz option_value_ok
162 sub al,30h
163 jc invalid_option_value
164 cmp al,9
165 ja invalid_option_value
166 imul edx,10
167 jo invalid_option_value
168 add edx,eax
169 jc invalid_option_value
170 jmp get_option_digit
171 option_value_ok:
172 dec esi
173 clc
174 ret
175 invalid_option_value:
176 stc
177 ret
178 bytes_per_line_option:
179 lodsb
180 cmp al,20h
181 je bytes_per_line_option
182 cmp al,0Dh
183 je bad_params
184 or al,al
185 jz bad_params
186 dec esi
187 call get_option_value
188 or edx,edx
189 jz bad_params
190 cmp edx,1000
191 ja bad_params
192 mov [code_bytes_per_line],edx
193 jmp find_param
194 addresses_option:
195 lodsb
196 cmp al,20h
197 je set_addresses_option
198 cmp al,0Dh
199 je set_addresses_option
200 or al,al
201 jnz bad_params
202 set_addresses_option:
203 dec esi
204 mov [show_addresses],1
205 jmp find_param
206 param_end:
207 dec esi
208 string_param_end:
209 xor al,al
210 stosb
211 jmp find_param
212 all_params:
213 cmp [input_file],0
214 je bad_params
215 cmp [output_file],0
216 je bad_params
217 clc
218 ret
219
220 include 'system.inc'
221
222 include '..\listing.inc'
223
224 section '.idata' import data readable writeable
225
226 library kernel32,'KERNEL32.DLL'
227
228 include 'api\kernel32.inc'
0
1 format PE console 4.0
2 entry start
3
4 include 'win32a.inc'
5
6 section '.data' data readable writeable
7
8 _usage db 'preprocessed source dumper for flat assembler',0Dh,0Ah
9 db 'usage: prepsrc <input> <output>',0Dh,0Ah
10 db 0
11 _error_prefix db 'error: ',0
12 _error_suffix db '.',0Dh,0Ah,0
13
14 input_file dd 0
15 output_file dd 0
16
17 display_handle dd ?
18 bytes_count dd ?
19
20 params rb 1000h
21
22 section '.text' code readable executable
23
24 start:
25
26 mov [display_handle],STD_OUTPUT_HANDLE
27
28 call get_params
29 jnc make_dump
30
31 mov esi,_usage
32 call display_string
33 invoke ExitProcess,2
34
35 make_dump:
36 call preprocessed_source
37 invoke ExitProcess,0
38
39 error:
40 mov [display_handle],STD_ERROR_HANDLE
41 mov esi,_error_prefix
42 call display_string
43 pop esi
44 call display_string
45 mov esi,_error_suffix
46 call display_string
47 invoke ExitProcess,1
48
49 get_params:
50 invoke GetCommandLine
51 mov esi,eax
52 mov edi,params
53 find_command_start:
54 lodsb
55 cmp al,20h
56 je find_command_start
57 cmp al,22h
58 je skip_quoted_name
59 skip_name:
60 lodsb
61 cmp al,20h
62 je find_param
63 or al,al
64 jz all_params
65 jmp skip_name
66 skip_quoted_name:
67 lodsb
68 cmp al,22h
69 je find_param
70 or al,al
71 jz all_params
72 jmp skip_quoted_name
73 find_param:
74 lodsb
75 cmp al,20h
76 je find_param
77 cmp al,0Dh
78 je all_params
79 or al,al
80 jz all_params
81 cmp [input_file],0
82 jne get_output_file
83 mov [input_file],edi
84 jmp process_param
85 get_output_file:
86 cmp [output_file],0
87 jne bad_params
88 mov [output_file],edi
89 process_param:
90 cmp al,22h
91 je string_param
92 copy_param:
93 stosb
94 lodsb
95 cmp al,20h
96 je param_end
97 cmp al,0Dh
98 je param_end
99 or al,al
100 jz param_end
101 jmp copy_param
102 string_param:
103 lodsb
104 cmp al,22h
105 je string_param_end
106 cmp al,0Dh
107 je param_end
108 or al,al
109 jz param_end
110 stosb
111 jmp string_param
112 bad_params:
113 stc
114 ret
115 param_end:
116 dec esi
117 string_param_end:
118 xor al,al
119 stosb
120 jmp find_param
121 all_params:
122 cmp [input_file],0
123 je bad_params
124 cmp [output_file],0
125 je bad_params
126 clc
127 ret
128
129 include 'system.inc'
130
131 include '..\prepsrc.inc'
132
133 section '.idata' import data readable writeable
134
135 library kernel32,'KERNEL32.DLL'
136
137 include 'api\kernel32.inc'
0
1 format PE console 4.0
2 entry start
3
4 include 'win32a.inc'
5
6 section '.data' data readable writeable
7
8 _usage db 'symbols dumper for flat assembler',0Dh,0Ah
9 db 'usage: symbols <input> <output>',0Dh,0Ah
10 db 0
11 _error_prefix db 'error: ',0
12 _error_suffix db '.',0Dh,0Ah,0
13
14 input_file dd 0
15 output_file dd 0
16
17 input dd ?
18 output_buffer dd ?
19 output_handle dd ?
20
21 display_handle dd ?
22 bytes_count dd ?
23
24 params rb 1000h
25
26 section '.text' code readable executable
27
28 start:
29
30 mov [display_handle],STD_OUTPUT_HANDLE
31
32 call get_params
33 jnc make_dump
34
35 mov esi,_usage
36 call display_string
37 invoke ExitProcess,2
38
39 make_dump:
40 call symbols
41 invoke ExitProcess,0
42
43 error:
44 mov [display_handle],STD_ERROR_HANDLE
45 mov esi,_error_prefix
46 call display_string
47 pop esi
48 call display_string
49 mov esi,_error_suffix
50 call display_string
51 invoke ExitProcess,1
52
53 get_params:
54 invoke GetCommandLine
55 mov esi,eax
56 mov edi,params
57 find_command_start:
58 lodsb
59 cmp al,20h
60 je find_command_start
61 cmp al,22h
62 je skip_quoted_name
63 skip_name:
64 lodsb
65 cmp al,20h
66 je find_param
67 or al,al
68 jz all_params
69 jmp skip_name
70 skip_quoted_name:
71 lodsb
72 cmp al,22h
73 je find_param
74 or al,al
75 jz all_params
76 jmp skip_quoted_name
77 find_param:
78 lodsb
79 cmp al,20h
80 je find_param
81 cmp al,0Dh
82 je all_params
83 or al,al
84 jz all_params
85 cmp [input_file],0
86 jne get_output_file
87 mov [input_file],edi
88 jmp process_param
89 get_output_file:
90 cmp [output_file],0
91 jne bad_params
92 mov [output_file],edi
93 process_param:
94 cmp al,22h
95 je string_param
96 copy_param:
97 stosb
98 lodsb
99 cmp al,20h
100 je param_end
101 cmp al,0Dh
102 je param_end
103 or al,al
104 jz param_end
105 jmp copy_param
106 string_param:
107 lodsb
108 cmp al,22h
109 je string_param_end
110 cmp al,0Dh
111 je param_end
112 or al,al
113 jz param_end
114 stosb
115 jmp string_param
116 bad_params:
117 stc
118 ret
119 param_end:
120 dec esi
121 string_param_end:
122 xor al,al
123 stosb
124 jmp find_param
125 all_params:
126 cmp [input_file],0
127 je bad_params
128 cmp [output_file],0
129 je bad_params
130 clc
131 ret
132
133 include 'system.inc'
134
135 include '..\symbols.inc'
136
137 section '.idata' import data readable writeable
138
139 library kernel32,'KERNEL32.DLL'
140
141 include 'api\kernel32.inc'
0
1 display_string:
2 invoke GetStdHandle,[display_handle]
3 mov edx,eax
4 mov edi,esi
5 or ecx,-1
6 xor al,al
7 repne scasb
8 neg ecx
9 sub ecx,2
10 invoke WriteFile,edx,esi,ecx,bytes_count,0
11 retn
12 alloc:
13 invoke VirtualAlloc,0,eax,MEM_COMMIT,PAGE_READWRITE
14 or eax,eax
15 jz allocation_error
16 clc
17 retn
18 allocation_error:
19 stc
20 retn
21 free:
22 invoke VirtualFree,eax,0,MEM_RELEASE
23 retn
24 open:
25 invoke CreateFile,edx,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0
26 cmp eax,-1
27 je file_error
28 mov ebx,eax
29 clc
30 retn
31 file_error:
32 stc
33 retn
34 create:
35 invoke CreateFile,edx,GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0
36 cmp eax,-1
37 je file_error
38 mov ebx,eax
39 clc
40 retn
41 write:
42 invoke WriteFile,ebx,edx,ecx,bytes_count,0
43 or eax,eax
44 jz file_error
45 clc
46 retn
47 read:
48 push ecx
49 invoke ReadFile,ebx,edx,ecx,bytes_count,0
50 pop edx
51 or eax,eax
52 jz file_error
53 cmp edx,[bytes_count]
54 jne file_error
55 clc
56 retn
57 close:
58 invoke CloseHandle,ebx
59 retn
60 lseek:
61 movzx eax,al
62 invoke SetFilePointer,ebx,edx,0,eax
63 cmp eax,-1
64 je file_error
65 retn
0
1 Visit http://flatassembler.net/ for more information.
2
3
4 version 1.71.22 (Sep 28, 2014)
5
6 [-] Format MZ no longer allows the table of relocations to overflow.
7
8
9 version 1.71.21 (May 27, 2014)
10
11 [-] Fixed a bug in the 64-bit floating points value converter.
12
13
14 version 1.71.20 (Feb 27, 2014)
15
16 [-] Fixed a bug in the backward patching of PE fixups.
17
18
19 version 1.71.19 (Feb 09, 2014)
20
21 [-] Corrected some of the range errors in intermediate passes to be correctly
22 resolvable.
23
24
25 version 1.71.18 (Feb 02, 2014)
26
27 [+] Added "irpv" directive.
28
29
30 version 1.71.17 (Jan 27, 2014)
31
32 [-] Minor corrections.
33
34
35 version 1.71.16 (Oct 30, 2013)
36
37 [-] Fixed some bugs in the ELF executable formatter.
38
39
40 version 1.71.15 (Oct 26, 2013)
41
42 [-] Fixed some bugs inadvertently introduced in the previous release.
43
44
45 version 1.71.14 (Oct 25, 2013)
46
47 [+] Added "postpone" directive to preprocessor.
48
49
50 version 1.71.13 (Sep 09, 2013)
51
52 [-] Fixed a bug that caused the expressions containing external symbols
53 to overflow from time to time.
54
55
56 version 1.71.12 (Aug 04, 2013)
57
58 [-] Expressions in square brackets were incorrectly treated as valid numerical
59 values when used in some logical expressions.
60
61 [-] A previous fix to "store" directive did not apply to all the cases when it
62 was incorrectly leaving the data marked as uninitialized. The new fix
63 addresses this issue.
64
65
66 version 1.71.11 (Jul 09, 2013)
67
68 [-] Modifying a value in uninitialized data block with "store" directive will
69 now correctly mark this data as initialized when it is in a different
70 addressing space.
71
72 [-] Missing quote will no longer cause the symbols generator to hang or crash.
73
74 [-] Address range restrictions for addressing modes no longer apply to addresses
75 provided to assembler directives like "label", "virtual" or "load".
76
77
78 version 1.71.10 (Apr 03, 2013)
79
80 [-] Fixed a crashing "heap" directive in 64-bit PE format.
81
82
83 version 1.71.09 (Mar 30, 2013)
84
85 [-] "use16","use32" and "use64" no longer allow to put another instruction in
86 the same line.
87
88 [-] Fixed a bug in parser that caused it to hang while processing some
89 specific ill-structured preprocessed lines.
90
91 [-] Modified memory allocation algorithm on Windows machines with large RAM.
92
93
94 version 1.71.08 (Mar 08, 2013)
95
96 [-] Fixed a bug that caused "irp" to skip processing a list with one empty
97 element when default value for iterating variable was specified.
98
99
100 version 1.71.07 (Dec 23, 2012)
101
102 [-] Fixed a bug that was causing "used" operator to give incorrect results
103 in some very specific cases.
104
105
106 version 1.71.06 (Nov 22, 2012)
107
108 [-] Fixed a few bugs caused by unnecesarily strong restrictions on allowed
109 types of relocatable values in some places (like "label" directive).
110
111
112 version 1.71.05 (Oct 15, 2012)
113
114 [-] Fixed a bug which caused "load" and "store" directives to sometimes
115 fail when assembler had preallocated very large amount of memory.
116
117
118 version 1.71.04 (Oct 10, 2012)
119
120 [-] Fixed another bug in "org" directive, which was causing it to deal
121 incorrectly with negative addresses.
122
123
124 version 1.71.03 (Sep 27, 2012)
125
126 [-] Fixed a bug in "org" directive introduced by recent changes, which
127 was manifesting with bases larger than 31-bit.
128
129
130 version 1.71.02 (Sep 26, 2012)
131
132 [-] Expression calculator now allows to calculate the difference of
133 relocatable addresses in a reverse order (first substracting/negating
134 and then adding the other one).
135
136
137 version 1.71.01 (Sep 23, 2012)
138
139 [+] Added support for ADX, RDSEED and SMAP instruction sets.
140
141 [-] Fixed the bugs related to creating a new addressing space inside the
142 virtual block with "org" directive.
143
144
145 version 1.71.00 (Sep 21, 2012)
146
147 [+] Added ability to define a special kind of label identifying the
148 addressing space. This label can the be used with "load" or "store"
149 directives to allow operations on bytes in any addressing space,
150 not just the current one. This special label is defined by following
151 its name with double colon, and can only be used with "load" and
152 "store" directive, where address can now be specified in two parts,
153 first the adressing space label, then the colon and then the
154 address inside that addressing space.
155
156
157 version 1.70.03 (Jun 29, 2012)
158
159 [-] Allowed to freely upgrade or downgrade the relocatable addresses in
160 object format between the 32-bit or 64-bit size.
161
162
163 version 1.70.02 (May 22, 2012)
164
165 [-] Corrected the optimization of segment prefixes when the extended syntax
166 of some string instructions ("cmps", "lods", "movs" and "outs") is
167 used in long mode. Now it is consistent with optimizations done with
168 all the other instructions.
169
170
171 version 1.70.01 (Apr 30, 2012)
172
173 [-] Corrected a recently introduced bug that caused some illegal
174 address expressions to cause an error prematurely during the
175 parsing stage.
176
177
178 version 1.70 (Apr 17, 2012)
179
180 [+] Added support for AVX, AVX2, AES, CLMUL, FMA, RDRAND, FSGSBASE, F16C,
181 FMA4, XOP, MOVBE, BMI, TBM, INVPCID, HLE and RTM instruction sets.
182
183 [+] Added half-precision floating point values support.
184
185 [+] Extended the syntax of "rept" directive to allow numerical expressions
186 to be calculated by preprocessor in its arguments.
187
188 [+] Added "large" and "NX" settings for PE format.
189
190 [+] Allowed PE fixups to be resolved anywhere in the generated executable.
191
192 [+] Allowed to specify branding value (use 3 for Linux) after the
193 "format ELF executable" setting.
194
195 [+] Added "intepreter", "dynamic" and "note" keywords for creation of
196 special segments in ELF executables.
197
198 [-] Fixed long mode opcode generator to allow absolute addresses to be
199 generated with "qword" keyword inside square brackets.
200
201 [-] Disallowed negative immediates with "int", "enter", "ret" instructions.
202
203 [+] Allowed symbolic information dump file to be created even in case of error.
204 In such case it contains only the preprocessed source that can be extracted
205 with PREPSRC tool. If error occured during preprocessing, only the source up
206 to the point of error is provided.
207
208 [+] Added symbol references table to symbolic dump file.
209
210 [-] Corrected the "defined" and "used" flags in the symbols dump to reflect the
211 state from the final assembly pass.
212
213 [+] Added "assert" directive.
214
215 [-] Formatter symbols like "PE" or "readable" are now recognized only in the
216 context of formatter directives, and thus are no longer disallowed as
217 labels.
218
219 [+] Macroinstruction argument now can have default value, defined with "="
220 symbol followed by value after the argument name in definition.
221
222 [+] Added "relativeto" operator, which can be used in logical expressions
223 to test whether two values differ only by a constant and not relocatable
224 amount.
225
226 [-] Revised the expression calculator, it now is able to correctly perform
227 calculations in signed and unsigned ranges in full 64-bit. This fixes
228 a number of issues - the overflow will now be correctly detected for
229 64-bit values in cases, where previous versions could not distinguish
230 whether it was an overflow or not. The effect of these corrections is
231 that "dq" directive will now behave consistently with behavior of the
232 data directives for smaller sizes, and the same applies to all the
233 places where "qword" size for value is used.
234
235
236 version 1.68 (Jun 13, 2009)
237
238 [+] Added SSSE3 (Supplemental SSE3), SSE4.1, SSE4.2 and SSE4a instructions.
239
240 [+] Added the AMD SVM and Intel SMX instructions.
241
242 [+] Added "rdmsrq", "wrmsrq", "sysexitq" and "sysretq" mnemonics for the
243 64-bit variants of respective instructions.
244
245 [+] Added "fstenvw", "fstenvd", "fsavew", "fsaved", "frstorw" and "frstord"
246 mnemonics to allow choosing between 16-bit and 32-bit variants of
247 structures used by the "fstenv", "fsave" and "frstor" instructions.
248
249 [+] Added "plt" operator for the ELF output format.
250
251 [+] Allowed "rva" operator to be used in MS COFF object format, and also
252 added "static" keyword for the "public" directive.
253
254 [+] Added Intel-style aliases for the additional long mode 8-bit registers.
255
256 [-] The PE formatter now automatically detects whether relocatable labels
257 should be used, depending on whether the fixups directory is placed
258 somewhere into executable by programer, or not. This makes possible the
259 more flexible use of the addressing symbols in case of PE executable fixed
260 at some position.
261
262 [-] Added support for outputting the 32-bit address relocations in case of
263 64-bit object formats and PE executable. This makes some specific
264 instructions compilable, but it also forces linker to put such
265 generated code into the low 2 gigabytes of addressing space.
266
267 [+] Added "EFI", "EFIboot" and "EFIruntime" subsystem keywords for PE format.
268
269 [-] Corrected the precedence of operators of macroinstruction line maker.
270 The symbol escaping now has always the higher priority than symbol conversion,
271 and both have higher precedence than concatenation.
272
273 [+] Allowed to check "@b" and "@f" symbols with "defined" operator.
274
275 [+] Allowed "as" operator to specify the output file extension when
276 placed at the end of the "format" directive line.
277
278 [-] Definition of macro with the same name as one of the preprocessor's directives
279 is no longer allowed.
280
281 [+] Allowed single quote character to be put inside the number value,
282 to help improve long numbers readability.
283
284 [+] Added optional symbolic information output, and a set of tools that extract
285 various kinds of information from it.
286
287 [+] Added "err" directive that allows to signalize error from the source.
288
289
290 version 1.66 (May 7, 2006)
291
292 [+] Added "define" directive to preprocessor, which defines symbolic constants,
293 the same kind as "equ" directive, however there's an important difference
294 that "define" doesn't process symbolic constants in the value before
295 assigning it. For example:
296
297 a equ 1
298 a equ a+a
299
300 define b 1
301 define b b+b
302
303 defines the "a" constant with value "1+1", but the "b" is defined with
304 value "b+b". This directive may be useful in some advanced
305 macroinstructions.
306
307 [-] Moved part of the conditional expression processing into parser,
308 for slightly better performance and lesser memory usage by assembler.
309 The logical values defined with "eq", "eqtype" and "in" operators are now
310 evaluated by the parser and if they are enough to determine the condition,
311 the whole block is processed accordingly. Thus this block:
312
313 if eax eq EAX | 0/0
314 nop
315 end if
316
317 is parsed into just "nop" instruction, since parser is able to determine
318 that the condition is true, even though one of the logical values makes no
319 sense - but since this is none of the "eq", "eqtype" and "in" expressions,
320 the parser doesn't investigate.
321
322 [-] Also the assembler is now calculating only as many logical values as it
323 needs to determine the condition. So this block:
324
325 if defined alpha & alpha
326
327 end if
328
329 will not cause error when "alpha" is not defined, as it would with previous
330 versions. This is because after checking that "defined alpha" is false
331 condition it doesn't need to know the second logical value to determine the
332 value of conjunction.
333
334 [+] Added "short" keyword for specifying jump type, the "jmp byte" form is now
335 obsolete and no longer correct - use "jmp short" instead.
336
337 [-] The size operator applied to jump no longer applies to the size of relative
338 displacement - now it applies to the size of target address.
339
340 [-] The "ret" instruction with 0 parameter is now assembled into short form,
341 unless you force using the 16-bit immediate with "word" operator.
342
343 [+] Added missing extended registers for the 32-bit addressing in long mode.
344
345 [+] Added "linkremove" and "linkinfo" section flags for MS COFF output.
346
347 [+] Added support for GOT offsets in ELF object formatter, which can be useful
348 when making position-independent code for shared libraries. For any label
349 you can get its offset relative to GOT by preceding it with "rva" operator
350 (the same keyword as for PE format is used, to avoid adding a new one,
351 while this one has very similar meaning).
352
353 [-] Changed ELF executable to use "segment" directive in place of "section",
354 to make the distinction between the run-time segments and linkable
355 sections. If you had a "section" directive in your ELF executables and they
356 no longer assemble, replace it with "segment".
357
358 [-] The PE formatter now always creates the fixups directory when told to -
359 even when there are no fixups to be put there (in such case it creates the
360 directory with one empty block).
361
362 [-] Some of the internal structures have been extended to provide the
363 possibility of making extensive symbol dumps.
364
365 [-] Corrected "fix" directive to keep the value intact before assigning it to the
366 prioritized constant.
367
368 [+] The ` operator now works with any kind of symbol; when used with quoted
369 string it simply does nothing. Thus the sequence of ` operators applied to
370 one symbol work the same as if there was just one. In similar manner, the
371 sequence of # operators now works as if it was a single one - using such a
372 sequence instead of escaping, which was kept for some backward
373 compatibility, is now deprecated.
374
375 [-] Corrected order of identifying assembler directives ("if db eq db" was
376 incorrectly interpreted as data definition).
377
378 [-] Many other small bugs fixed.
379
380
381 version 1.64 (Aug 8, 2005)
382
383 [+] Output of PE executables for Win64 architecture (with "format PE64"
384 setting).
385
386 [+] Added "while" and "break" directives.
387
388 [+] Added "irp" and "irps" directives.
389
390 [+] The macro arguments can be marked as required with the "*" character.
391
392 [-] Fixed checking for overflow when multiplying 64-bit values - the result
393 must always fit in the range of signed 64 integer now.
394
395 [-] Segment prefixes were generated incorrectly in 16-bit mode when BP was used
396 as a second addressing register - fixed.
397
398 [-] The "local" directive was not creating unique labels in some cases - fixed.
399
400 [-] The "not encodable with long immediate" error in 64-bit mode was sometimes
401 wrongly signaled - fixed.
402
403 [-] Other minor fixes and corrections.
404
405
406 version 1.62 (Jun 14, 2005)
407
408 [+] Escaping of symbols inside macroinstructions with backslash.
409
410 [+] Ability of outputting the COFF object files for Win64 architecture
411 (with "format MS64 COFF" setting).
412
413 [+] New preprocessor directives: "restruc", "rept" and "match"
414
415 [+] VMX instructions support (not documented).
416
417 [+] Extended data directives to allow use of the "dup" operator.
418
419 [+] Extended "struc" features to allow custom definitions of main structure's
420 label.
421
422 [-] When building resources from the the .RES file that contained more
423 than one resource of the same string name, the separate resource
424 directories were created with the same names - fixed.
425
426 [-] Several bugs in the ELF64 object output has been fixed.
427
428 [-] Corrected behavior of "fix" directive to more straightforward.
429
430 [-] Fixed bug in "include" directive, which caused files included from within
431 macros to be processed the wrong way.