Merge tag 'upstream/1.71.58'
Upstream version 1.71.58
Tomasz Buchert
7 years ago
0 | ||
1 | ; flat assembler interface for Linux x64 | |
2 | ; Copyright (c) 1999-2016, Tomasz Grysztar. | |
3 | ; All rights reserved. | |
4 | ||
5 | format ELF64 executable 3 at 400000h | |
6 | entry start | |
7 | ||
8 | include 'modes.inc' | |
9 | ||
10 | segment readable executable | |
11 | ||
12 | start: | |
13 | ||
14 | mov [con_handle],1 | |
15 | mov esi,_logo | |
16 | call display_string | |
17 | ||
18 | mov [command_line],rsp | |
19 | mov rcx,[rsp] | |
20 | mov rbx,[rsp+8+rcx*8+8] | |
21 | mov [environment],rbx | |
22 | call get_params | |
23 | jc information | |
24 | ||
25 | call init_memory | |
26 | ||
27 | mov esi,_memory_prefix | |
28 | call display_string | |
29 | mov eax,[memory_end] | |
30 | sub eax,[memory_start] | |
31 | add eax,[additional_memory_end] | |
32 | sub eax,[additional_memory] | |
33 | shr eax,10 | |
34 | call display_number | |
35 | mov esi,_memory_suffix | |
36 | call display_string | |
37 | ||
38 | mov eax,96 | |
39 | mov edi,buffer | |
40 | xor esi,esi | |
41 | syscall | |
42 | mov eax,dword [buffer] | |
43 | mov ecx,1000 | |
44 | mul ecx | |
45 | mov ebx,eax | |
46 | mov eax,dword [buffer+4] | |
47 | div ecx | |
48 | add eax,ebx | |
49 | mov [start_time],eax | |
50 | ||
51 | and [preprocessing_done],0 | |
52 | call preprocessor | |
53 | or [preprocessing_done],-1 | |
54 | call parser | |
55 | call assembler | |
56 | call formatter | |
57 | ||
58 | call display_user_messages | |
59 | movzx eax,[current_pass] | |
60 | inc eax | |
61 | call display_number | |
62 | mov esi,_passes_suffix | |
63 | call display_string | |
64 | mov eax,96 | |
65 | mov edi,buffer | |
66 | xor esi,esi | |
67 | syscall | |
68 | mov eax,dword [buffer] | |
69 | mov ecx,1000 | |
70 | mul ecx | |
71 | mov ebx,eax | |
72 | mov eax,dword [buffer+4] | |
73 | div ecx | |
74 | add eax,ebx | |
75 | sub eax,[start_time] | |
76 | jnc time_ok | |
77 | add eax,3600000 | |
78 | time_ok: | |
79 | xor edx,edx | |
80 | mov ebx,100 | |
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 dl,'.' | |
90 | call display_character | |
91 | pop eax | |
92 | call display_number | |
93 | mov esi,_seconds_suffix | |
94 | call display_string | |
95 | display_bytes_count: | |
96 | mov eax,[written_size] | |
97 | call display_number | |
98 | mov esi,_bytes_suffix | |
99 | call display_string | |
100 | xor al,al | |
101 | jmp exit_program | |
102 | ||
103 | information: | |
104 | mov esi,_usage | |
105 | call display_string | |
106 | mov al,1 | |
107 | jmp exit_program | |
108 | ||
109 | get_params: | |
110 | mov rbx,[command_line] | |
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 | mov rcx,[rbx] | |
117 | add rbx,8*2 | |
118 | dec rcx | |
119 | jz bad_params | |
120 | mov [definitions_pointer],predefinitions | |
121 | mov [path_pointer],paths | |
122 | get_param: | |
123 | mov rsi,[rbx] | |
124 | mov al,[rsi] | |
125 | cmp al,'-' | |
126 | je option_param | |
127 | cmp [input_file],0 | |
128 | jne get_output_file | |
129 | call collect_path | |
130 | mov [input_file],edx | |
131 | jmp next_param | |
132 | get_output_file: | |
133 | cmp [output_file],0 | |
134 | jne bad_params | |
135 | call collect_path | |
136 | mov [output_file],edx | |
137 | jmp next_param | |
138 | option_param: | |
139 | inc rsi | |
140 | lodsb | |
141 | cmp al,'m' | |
142 | je memory_option | |
143 | cmp al,'M' | |
144 | je memory_option | |
145 | cmp al,'p' | |
146 | je passes_option | |
147 | cmp al,'P' | |
148 | je passes_option | |
149 | cmp al,'d' | |
150 | je definition_option | |
151 | cmp al,'D' | |
152 | je definition_option | |
153 | cmp al,'s' | |
154 | je symbols_option | |
155 | cmp al,'S' | |
156 | je symbols_option | |
157 | bad_params: | |
158 | stc | |
159 | ret | |
160 | memory_option: | |
161 | cmp byte [rsi],0 | |
162 | jne get_memory_setting | |
163 | dec rcx | |
164 | jz bad_params | |
165 | add rbx,8 | |
166 | mov rsi,[rbx] | |
167 | get_memory_setting: | |
168 | call get_option_value | |
169 | or edx,edx | |
170 | jz bad_params | |
171 | cmp edx,1 shl (32-10) | |
172 | jae bad_params | |
173 | mov [memory_setting],edx | |
174 | jmp next_param | |
175 | passes_option: | |
176 | cmp byte [rsi],0 | |
177 | jne get_passes_setting | |
178 | dec rcx | |
179 | jz bad_params | |
180 | add rbx,8 | |
181 | mov rsi,[rbx] | |
182 | get_passes_setting: | |
183 | call get_option_value | |
184 | or edx,edx | |
185 | jz bad_params | |
186 | cmp edx,10000h | |
187 | ja bad_params | |
188 | mov [passes_limit],dx | |
189 | next_param: | |
190 | add rbx,8 | |
191 | dec rcx | |
192 | jnz get_param | |
193 | cmp [input_file],0 | |
194 | je bad_params | |
195 | mov eax,[definitions_pointer] | |
196 | mov byte [eax],0 | |
197 | mov [initial_definitions],predefinitions | |
198 | clc | |
199 | ret | |
200 | definition_option: | |
201 | cmp byte [rsi],0 | |
202 | jne get_definition | |
203 | dec rcx | |
204 | jz bad_params | |
205 | add rbx,8 | |
206 | mov rsi,[rbx] | |
207 | get_definition: | |
208 | mov r12d,edi | |
209 | mov edi,[definitions_pointer] | |
210 | call convert_definition_option | |
211 | mov [definitions_pointer],edi | |
212 | mov edi,r12d | |
213 | jc bad_params | |
214 | jmp next_param | |
215 | symbols_option: | |
216 | cmp byte [rsi],0 | |
217 | jne get_symbols_setting | |
218 | dec rcx | |
219 | jz bad_params | |
220 | add rbx,8 | |
221 | mov rsi,[rbx] | |
222 | get_symbols_setting: | |
223 | call collect_path | |
224 | mov [symbols_file],edx | |
225 | jmp next_param | |
226 | get_option_value: | |
227 | xor eax,eax | |
228 | mov edx,eax | |
229 | get_option_digit: | |
230 | lodsb | |
231 | cmp al,20h | |
232 | je option_value_ok | |
233 | or al,al | |
234 | jz option_value_ok | |
235 | sub al,30h | |
236 | jc invalid_option_value | |
237 | cmp al,9 | |
238 | ja invalid_option_value | |
239 | imul edx,10 | |
240 | jo invalid_option_value | |
241 | add edx,eax | |
242 | jc invalid_option_value | |
243 | jmp get_option_digit | |
244 | option_value_ok: | |
245 | dec rsi | |
246 | clc | |
247 | ret | |
248 | invalid_option_value: | |
249 | stc | |
250 | ret | |
251 | convert_definition_option: | |
252 | mov edx,edi | |
253 | xor al,al | |
254 | stosb | |
255 | copy_definition_name: | |
256 | lodsb | |
257 | cmp al,'=' | |
258 | je copy_definition_value | |
259 | cmp al,20h | |
260 | je bad_definition_option | |
261 | or al,al | |
262 | jz bad_definition_option | |
263 | stosb | |
264 | inc byte [edx] | |
265 | jnz copy_definition_name | |
266 | bad_definition_option: | |
267 | stc | |
268 | ret | |
269 | copy_definition_value: | |
270 | lodsb | |
271 | cmp al,20h | |
272 | je definition_value_end | |
273 | or al,al | |
274 | jz definition_value_end | |
275 | stosb | |
276 | jmp copy_definition_value | |
277 | definition_value_end: | |
278 | dec rsi | |
279 | xor al,al | |
280 | stosb | |
281 | clc | |
282 | ret | |
283 | collect_path: | |
284 | mov edi,[path_pointer] | |
285 | mov edx,edi | |
286 | copy_path_to_low_memory: | |
287 | lodsb | |
288 | stosb | |
289 | test al,al | |
290 | jnz copy_path_to_low_memory | |
291 | mov [path_pointer],edi | |
292 | retn | |
293 | ||
294 | include 'system.inc' | |
295 | ||
296 | include '..\..\version.inc' | |
297 | ||
298 | _copyright db 'Copyright (c) 1999-2016, Tomasz Grysztar',0xA,0 | |
299 | ||
300 | _logo db 'flat assembler version ',VERSION_STRING,0 | |
301 | _usage db 0xA | |
302 | db 'usage: fasm <source> [output]',0xA | |
303 | db 'optional settings:',0xA | |
304 | db ' -m <limit> set the limit in kilobytes for the available memory',0xA | |
305 | db ' -p <limit> set the maximum allowed number of passes',0xA | |
306 | db ' -d <name>=<value> define symbolic variable',0xA | |
307 | db ' -s <file> dump symbolic information for debugging',0xA | |
308 | db 0 | |
309 | _memory_prefix db ' (',0 | |
310 | _memory_suffix db ' kilobytes memory, x64)',0xA,0 | |
311 | _passes_suffix db ' passes, ',0 | |
312 | _seconds_suffix db ' seconds, ',0 | |
313 | _bytes_suffix db ' bytes.',0xA,0 | |
314 | _no_low_memory db 'failed to allocate memory within 32-bit addressing range',0 | |
315 | ||
316 | include '..\..\errors.inc' | |
317 | include '..\..\symbdump.inc' | |
318 | include '..\..\preproce.inc' | |
319 | include '..\..\parser.inc' | |
320 | include '..\..\exprpars.inc' | |
321 | include '..\..\assemble.inc' | |
322 | include '..\..\exprcalc.inc' | |
323 | include '..\..\formats.inc' | |
324 | include '..\..\avx.inc' | |
325 | include '..\..\x86_64.inc' | |
326 | ||
327 | include '..\..\tables.inc' | |
328 | include '..\..\messages.inc' | |
329 | ||
330 | segment readable writeable | |
331 | ||
332 | align 4 | |
333 | ||
334 | include '..\..\variable.inc' | |
335 | ||
336 | command_line dq ? | |
337 | memory_setting dd ? | |
338 | path_pointer dd ? | |
339 | definitions_pointer dd ? | |
340 | environment dq ? | |
341 | timestamp dq ? | |
342 | start_time dd ? | |
343 | con_handle dd ? | |
344 | displayed_count dd ? | |
345 | last_displayed db ? | |
346 | character db ? | |
347 | preprocessing_done db ? | |
348 | ||
349 | buffer rb 1000h | |
350 | predefinitions rb 1000h | |
351 | paths rb 10000h |
0 | ||
1 | esp equ +rsp | |
2 | ||
3 | macro pushD [arg] | |
4 | { | |
5 | common | |
6 | local offset,total | |
7 | offset = 0 | |
8 | lea rsp,[rsp-total] | |
9 | forward | |
10 | offset = offset + 4 | |
11 | if arg eqtype eax | |
12 | mov dword [rsp+total-offset],arg | |
13 | else | |
14 | mov r8d,dword arg | |
15 | mov [rsp+total-offset],r8d | |
16 | end if | |
17 | common | |
18 | total = offset | |
19 | } | |
20 | ||
21 | macro popD [arg] | |
22 | { | |
23 | common | |
24 | local offset | |
25 | offset = 0 | |
26 | forward | |
27 | if arg eqtype [mem] | |
28 | mov r8d,[rsp+offset] | |
29 | mov dword arg,r8d | |
30 | else | |
31 | mov arg,dword [rsp+offset] | |
32 | end if | |
33 | offset = offset + 4 | |
34 | common | |
35 | lea rsp,[rsp+offset] | |
36 | } | |
37 | ||
38 | macro add dest,src | |
39 | { | |
40 | if dest eq esp | |
41 | add rsp,src | |
42 | else | |
43 | add dest,src | |
44 | end if | |
45 | } | |
46 | ||
47 | macro mov dest,src | |
48 | { | |
49 | if src eq esp | |
50 | mov dest,ESP | |
51 | else | |
52 | mov dest,src | |
53 | end if | |
54 | } | |
55 | ||
56 | macro cmp dest,src | |
57 | { | |
58 | if dest eq esp | |
59 | cmp ESP,src | |
60 | else | |
61 | cmp dest,src | |
62 | end if | |
63 | } | |
64 | ||
65 | macro use32 | |
66 | { | |
67 | ||
68 | macro push args | |
69 | \{ | |
70 | local list,arg,status | |
71 | define list | |
72 | define arg | |
73 | irps sym, args \\{ | |
74 | define status | |
75 | match =dword, sym \\\{ | |
76 | define status : | |
77 | \\\} | |
78 | match [any, status arg sym \\\{ | |
79 | define arg [any | |
80 | match [mem], arg \\\\{ | |
81 | match previous, list \\\\\{ define list previous,[mem] \\\\\} | |
82 | match , list \\\\\{ define list [mem] \\\\\} | |
83 | define arg | |
84 | \\\\} | |
85 | define status : | |
86 | \\\} | |
87 | match [, status arg sym \\\{ | |
88 | define arg [ | |
89 | define status : | |
90 | \\\} | |
91 | match , status \\\{ | |
92 | match previous, list \\\\{ define list previous,sym \\\\} | |
93 | match , list \\\\{ define list sym \\\\} | |
94 | \\\} | |
95 | \\} | |
96 | match arg, list \\{ pushD arg \\} | |
97 | \} | |
98 | ||
99 | macro pop args | |
100 | \{ | |
101 | local list,arg,status | |
102 | define list | |
103 | define arg | |
104 | irps sym, args \\{ | |
105 | define status | |
106 | match =dword, sym \\\{ | |
107 | define status : | |
108 | \\\} | |
109 | match [any, status arg sym \\\{ | |
110 | define arg [any | |
111 | match [mem], arg \\\\{ | |
112 | match previous, list \\\\\{ define list previous,[mem] \\\\\} | |
113 | match , list \\\\\{ define list [mem] \\\\\} | |
114 | define arg | |
115 | \\\\} | |
116 | define status : | |
117 | \\\} | |
118 | match [, status arg sym \\\{ | |
119 | define arg [ | |
120 | define status : | |
121 | \\\} | |
122 | match , status \\\{ | |
123 | match previous, list \\\\{ define list previous,sym \\\\} | |
124 | match , list \\\\{ define list sym \\\\} | |
125 | \\\} | |
126 | \\} | |
127 | match arg, list \\{ popD arg \\} | |
128 | \} | |
129 | ||
130 | macro jmp arg | |
131 | \{ | |
132 | if arg eq near eax | |
133 | jmp near rax | |
134 | else if arg eq near edx | |
135 | jmp near rdx | |
136 | else if arg eqtype [mem] | |
137 | mov r8d,arg | |
138 | jmp near r8 | |
139 | else | |
140 | jmp arg | |
141 | end if | |
142 | \} | |
143 | ||
144 | macro call arg | |
145 | \{ | |
146 | if 1 | |
147 | match =near =dword [mem], arg \\{ | |
148 | mov r8d,[mem] | |
149 | call near r8 | |
150 | else | |
151 | \\} | |
152 | call arg | |
153 | end if | |
154 | \} | |
155 | ||
156 | macro salc ; for fasm's core it does not need to preserve flags | |
157 | \{ | |
158 | setc al | |
159 | neg al | |
160 | \} | |
161 | ||
162 | macro jcxz target ; for fasm's core it does not need to preserve flags | |
163 | \{ | |
164 | test cx,cx | |
165 | jz target | |
166 | \} | |
167 | ||
168 | use64 | |
169 | ||
170 | } | |
171 | ||
172 | macro use16 | |
173 | { | |
174 | ||
175 | purge push,pop,jmp,call,salc,jcxz | |
176 | ||
177 | use16 | |
178 | ||
179 | } | |
180 | ||
181 | use32 |
0 | ||
1 | ; flat assembler interface for Linux x64 | |
2 | ; Copyright (c) 1999-2016, 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 edi,edi | |
35 | mov eax,12 | |
36 | syscall | |
37 | mov r9,not 0FFFFFFFFh | |
38 | test rax,r9 | |
39 | jnz no_low_memory | |
40 | mov [additional_memory],eax | |
41 | mov ecx,[memory_setting] | |
42 | shl ecx,10 | |
43 | jnz allocate_memory | |
44 | mov ecx,1000000h | |
45 | allocate_memory: | |
46 | mov edi,[additional_memory] | |
47 | add edi,ecx | |
48 | mov eax,12 | |
49 | syscall | |
50 | mov r9,not 0FFFFFFFFh | |
51 | test rax,r9 | |
52 | jnz no_low_memory | |
53 | mov [memory_end],eax | |
54 | sub eax,[additional_memory] | |
55 | shr eax,2 | |
56 | add eax,[additional_memory] | |
57 | mov [additional_memory_end],eax | |
58 | mov [memory_start],eax | |
59 | ret | |
60 | ||
61 | no_low_memory: | |
62 | push _no_low_memory | |
63 | jmp fatal_error | |
64 | ||
65 | exit_program: | |
66 | movzx edi,al | |
67 | mov eax,60 | |
68 | syscall | |
69 | ||
70 | get_environment_variable: | |
71 | mov ebx,esi | |
72 | mov rsi,[environment] | |
73 | compare_variable_names: | |
74 | mov edx,ebx | |
75 | compare_character: | |
76 | lodsb | |
77 | mov ah,[edx] | |
78 | inc edx | |
79 | cmp al,'=' | |
80 | je end_of_variable_name | |
81 | or ah,ah | |
82 | jz next_variable | |
83 | sub ah,al | |
84 | jz compare_character | |
85 | cmp ah,20h | |
86 | jne next_variable | |
87 | cmp al,41h | |
88 | jb next_variable | |
89 | cmp al,5Ah | |
90 | jna compare_character | |
91 | next_variable: | |
92 | lodsb | |
93 | or al,al | |
94 | jnz next_variable | |
95 | cmp byte [rsi],0 | |
96 | jne compare_variable_names | |
97 | ret | |
98 | end_of_variable_name: | |
99 | or ah,ah | |
100 | jnz next_variable | |
101 | copy_variable_value: | |
102 | lodsb | |
103 | cmp edi,[memory_end] | |
104 | jae out_of_memory | |
105 | stosb | |
106 | or al,al | |
107 | jnz copy_variable_value | |
108 | dec edi | |
109 | ret | |
110 | ||
111 | open: | |
112 | mov r12d,esi | |
113 | mov r13d,edi | |
114 | call adapt_path | |
115 | mov eax,2 | |
116 | mov edi,buffer | |
117 | mov esi,O_RDONLY | |
118 | xor edx,edx | |
119 | syscall | |
120 | mov esi,r12d | |
121 | mov edi,r13d | |
122 | test eax,eax | |
123 | js file_error | |
124 | mov ebx,eax | |
125 | clc | |
126 | ret | |
127 | adapt_path: | |
128 | mov esi,edx | |
129 | mov edi,buffer | |
130 | copy_path: | |
131 | lods byte [esi] | |
132 | cmp al,'\' | |
133 | jne path_char_ok | |
134 | mov al,'/' | |
135 | path_char_ok: | |
136 | stos byte [edi] | |
137 | or al,al | |
138 | jnz copy_path | |
139 | cmp edi,buffer+1000h | |
140 | ja out_of_memory | |
141 | ret | |
142 | create: | |
143 | mov r12d,esi | |
144 | mov r13d,edi | |
145 | mov r15d,edx | |
146 | call adapt_path | |
147 | mov edi,buffer | |
148 | mov esi,O_CREAT+O_TRUNC+O_WRONLY | |
149 | mov edx,S_IRUSR+S_IWUSR+S_IRGRP+S_IROTH | |
150 | cmp r15d,[output_file] | |
151 | jne do_create | |
152 | cmp [output_format],5 | |
153 | jne do_create | |
154 | bt [format_flags],0 | |
155 | jnc do_create | |
156 | or edx,S_IXUSR+S_IXGRP+S_IXOTH | |
157 | do_create: | |
158 | mov eax,2 | |
159 | syscall | |
160 | mov esi,r12d | |
161 | mov edi,r13d | |
162 | test eax,eax | |
163 | js file_error | |
164 | mov ebx,eax | |
165 | clc | |
166 | ret | |
167 | close: | |
168 | mov r13d,edi | |
169 | mov edi,ebx | |
170 | mov eax,3 | |
171 | syscall | |
172 | mov edi,r13d | |
173 | ret | |
174 | read: | |
175 | mov r12d,esi | |
176 | mov r13d,edi | |
177 | mov eax,0 | |
178 | mov edi,ebx | |
179 | mov esi,edx | |
180 | mov edx,ecx | |
181 | syscall | |
182 | mov ecx,edx | |
183 | mov edx,esi | |
184 | mov esi,r12d | |
185 | mov edi,r13d | |
186 | test eax,eax | |
187 | js file_error | |
188 | cmp eax,ecx | |
189 | jne file_error | |
190 | clc | |
191 | ret | |
192 | file_error: | |
193 | stc | |
194 | ret | |
195 | write: | |
196 | mov r12d,esi | |
197 | mov r13d,edi | |
198 | mov eax,1 | |
199 | mov edi,ebx | |
200 | mov esi,edx | |
201 | mov edx,ecx | |
202 | syscall | |
203 | mov ecx,edx | |
204 | mov edx,esi | |
205 | mov esi,r12d | |
206 | mov edi,r13d | |
207 | test eax,eax | |
208 | js file_error | |
209 | clc | |
210 | ret | |
211 | lseek: | |
212 | mov r12d,esi | |
213 | mov r13d,edi | |
214 | mov edi,ebx | |
215 | mov esi,edx | |
216 | xor edx,edx | |
217 | mov dl,al | |
218 | mov eax,8 | |
219 | syscall | |
220 | mov esi,r12d | |
221 | mov edi,r13d | |
222 | ret | |
223 | ||
224 | display_string: | |
225 | mov edi,esi | |
226 | mov edx,esi | |
227 | or ecx,-1 | |
228 | xor al,al | |
229 | repne scasb | |
230 | neg ecx | |
231 | sub ecx,2 | |
232 | mov eax,1 | |
233 | mov edi,[con_handle] | |
234 | mov esi,edx | |
235 | mov edx,ecx | |
236 | syscall | |
237 | ret | |
238 | display_character: | |
239 | mov r12d,esi | |
240 | mov r13d,edi | |
241 | mov [character],dl | |
242 | mov eax,1 | |
243 | mov edi,[con_handle] | |
244 | mov esi,character | |
245 | mov edx,1 | |
246 | syscall | |
247 | mov esi,r12d | |
248 | mov edi,r13d | |
249 | ret | |
250 | display_number: | |
251 | mov r14d,ebx | |
252 | mov ecx,1000000000 | |
253 | xor edx,edx | |
254 | xor bl,bl | |
255 | display_loop: | |
256 | div ecx | |
257 | mov r15d,edx | |
258 | cmp ecx,1 | |
259 | je display_digit | |
260 | or bl,bl | |
261 | jnz display_digit | |
262 | or al,al | |
263 | jz digit_ok | |
264 | not bl | |
265 | display_digit: | |
266 | mov dl,al | |
267 | add dl,30h | |
268 | mov r10d,ecx | |
269 | call display_character | |
270 | mov ecx,r10d | |
271 | digit_ok: | |
272 | mov eax,ecx | |
273 | xor edx,edx | |
274 | mov ecx,10 | |
275 | div ecx | |
276 | mov ecx,eax | |
277 | mov eax,r15d | |
278 | or ecx,ecx | |
279 | jnz display_loop | |
280 | mov ebx,r14d | |
281 | ret | |
282 | ||
283 | display_user_messages: | |
284 | mov [displayed_count],0 | |
285 | call show_display_buffer | |
286 | cmp [displayed_count],0 | |
287 | je line_break_ok | |
288 | cmp [last_displayed],0Ah | |
289 | je line_break_ok | |
290 | mov dl,0Ah | |
291 | call display_character | |
292 | line_break_ok: | |
293 | ret | |
294 | display_block: | |
295 | jecxz block_displayed | |
296 | add [displayed_count],ecx | |
297 | mov al,[esi+ecx-1] | |
298 | mov [last_displayed],al | |
299 | mov r13d,edi | |
300 | mov eax,1 | |
301 | mov edi,[con_handle] | |
302 | mov edx,ecx | |
303 | syscall | |
304 | mov edi,r13d | |
305 | block_displayed: | |
306 | ret | |
307 | ||
308 | fatal_error: | |
309 | mov [con_handle],2 | |
310 | mov esi,error_prefix | |
311 | call display_string | |
312 | pop esi | |
313 | call display_string | |
314 | mov esi,error_suffix | |
315 | call display_string | |
316 | mov al,0FFh | |
317 | jmp exit_program | |
318 | assembler_error: | |
319 | mov [con_handle],2 | |
320 | call display_user_messages | |
321 | mov ebx,[current_line] | |
322 | test ebx,ebx | |
323 | jz display_error_message | |
324 | push dword 0 | |
325 | get_error_lines: | |
326 | mov eax,[ebx] | |
327 | cmp byte [eax],0 | |
328 | je get_next_error_line | |
329 | push ebx | |
330 | test byte [ebx+7],80h | |
331 | jz display_error_line | |
332 | mov edx,ebx | |
333 | find_definition_origin: | |
334 | mov edx,[edx+12] | |
335 | test byte [edx+7],80h | |
336 | jnz find_definition_origin | |
337 | push edx | |
338 | get_next_error_line: | |
339 | mov ebx,[ebx+8] | |
340 | jmp get_error_lines | |
341 | display_error_line: | |
342 | mov esi,[ebx] | |
343 | call display_string | |
344 | mov esi,line_number_start | |
345 | call display_string | |
346 | mov eax,[ebx+4] | |
347 | and eax,7FFFFFFFh | |
348 | call display_number | |
349 | mov dl,']' | |
350 | call display_character | |
351 | pop esi | |
352 | cmp ebx,esi | |
353 | je line_number_ok | |
354 | mov dl,20h | |
355 | call display_character | |
356 | push esi | |
357 | mov esi,[esi] | |
358 | movzx ecx,byte [esi] | |
359 | inc esi | |
360 | call display_block | |
361 | mov esi,line_number_start | |
362 | call display_string | |
363 | pop esi | |
364 | mov eax,[esi+4] | |
365 | and eax,7FFFFFFFh | |
366 | call display_number | |
367 | mov dl,']' | |
368 | call display_character | |
369 | line_number_ok: | |
370 | mov esi,line_data_start | |
371 | call display_string | |
372 | mov esi,ebx | |
373 | mov edx,[esi] | |
374 | call open | |
375 | mov al,2 | |
376 | xor edx,edx | |
377 | call lseek | |
378 | mov edx,[esi+8] | |
379 | sub eax,edx | |
380 | jz line_data_displayed | |
381 | push eax | |
382 | xor al,al | |
383 | call lseek | |
384 | mov ecx,[esp] | |
385 | mov edx,[additional_memory] | |
386 | lea eax,[edx+ecx] | |
387 | cmp eax,[additional_memory_end] | |
388 | ja out_of_memory | |
389 | call read | |
390 | call close | |
391 | pop ecx | |
392 | mov esi,[additional_memory] | |
393 | get_line_data: | |
394 | mov al,[esi] | |
395 | cmp al,0Ah | |
396 | je display_line_data | |
397 | cmp al,0Dh | |
398 | je display_line_data | |
399 | cmp al,1Ah | |
400 | je display_line_data | |
401 | or al,al | |
402 | jz display_line_data | |
403 | inc esi | |
404 | loop get_line_data | |
405 | display_line_data: | |
406 | mov ecx,esi | |
407 | mov esi,[additional_memory] | |
408 | sub ecx,esi | |
409 | call display_block | |
410 | line_data_displayed: | |
411 | mov esi,lf | |
412 | call display_string | |
413 | pop ebx | |
414 | or ebx,ebx | |
415 | jnz display_error_line | |
416 | cmp [preprocessing_done],0 | |
417 | je display_error_message | |
418 | mov esi,preprocessed_instruction_prefix | |
419 | call display_string | |
420 | mov esi,[current_line] | |
421 | add esi,16 | |
422 | mov edi,[additional_memory] | |
423 | xor dl,dl | |
424 | convert_instruction: | |
425 | lodsb | |
426 | cmp al,1Ah | |
427 | je copy_symbol | |
428 | cmp al,22h | |
429 | je copy_symbol | |
430 | cmp al,3Bh | |
431 | je instruction_converted | |
432 | stosb | |
433 | or al,al | |
434 | jz instruction_converted | |
435 | xor dl,dl | |
436 | jmp convert_instruction | |
437 | copy_symbol: | |
438 | or dl,dl | |
439 | jz space_ok | |
440 | mov byte [edi],20h | |
441 | inc edi | |
442 | space_ok: | |
443 | cmp al,22h | |
444 | je quoted | |
445 | lodsb | |
446 | movzx ecx,al | |
447 | rep movsb | |
448 | or dl,-1 | |
449 | jmp convert_instruction | |
450 | quoted: | |
451 | mov al,27h | |
452 | stosb | |
453 | lodsd | |
454 | mov ecx,eax | |
455 | jecxz quoted_copied | |
456 | copy_quoted: | |
457 | lodsb | |
458 | stosb | |
459 | cmp al,27h | |
460 | jne quote_ok | |
461 | stosb | |
462 | quote_ok: | |
463 | loop copy_quoted | |
464 | quoted_copied: | |
465 | mov al,27h | |
466 | stosb | |
467 | or dl,-1 | |
468 | jmp convert_instruction | |
469 | instruction_converted: | |
470 | xor al,al | |
471 | stosb | |
472 | mov esi,[additional_memory] | |
473 | call display_string | |
474 | mov esi,lf | |
475 | call display_string | |
476 | display_error_message: | |
477 | mov esi,error_prefix | |
478 | call display_string | |
479 | pop esi | |
480 | call display_string | |
481 | mov esi,error_suffix | |
482 | call display_string | |
483 | mov al,2 | |
484 | jmp exit_program | |
485 | ||
486 | make_timestamp: | |
487 | mov r13d,edi | |
488 | mov eax,201 | |
489 | mov edi,timestamp | |
490 | syscall | |
491 | mov eax,dword [timestamp] | |
492 | mov edx,dword [timestamp+4] | |
493 | mov edi,r13d | |
494 | ret | |
495 | ||
496 | error_prefix db 'error: ',0 | |
497 | error_suffix db '.' | |
498 | lf db 0xA,0 | |
499 | line_number_start db ' [',0 | |
500 | line_data_start db ':',0xA,0 | |
501 | preprocessed_instruction_prefix db 'processed: ',0 |
809 | 809 | mov [counter],1 |
810 | 810 | times_loop: |
811 | 811 | mov eax,esp |
812 | sub eax,100h | |
813 | jc stack_overflow | |
814 | cmp eax,[stack_limit] | |
812 | sub eax,[stack_limit] | |
813 | cmp eax,100h | |
815 | 814 | jb stack_overflow |
816 | 815 | push esi |
817 | 816 | or [prefix_flags],1 |
1303 | 1302 | push ebx |
1304 | 1303 | jmp stop_while |
1305 | 1304 | |
1305 | data_unicode: | |
1306 | or [base_code],-1 | |
1307 | jmp define_words | |
1308 | data_words: | |
1309 | mov [base_code],0 | |
1310 | define_words: | |
1311 | push define_data_word | |
1312 | jmp define_data | |
1313 | data_dwords: | |
1314 | push define_data_dword | |
1315 | jmp define_data | |
1316 | data_pwords: | |
1317 | push define_data_pword | |
1318 | jmp define_data | |
1319 | data_qwords: | |
1320 | push define_data_qword | |
1321 | jmp define_data | |
1322 | data_twords: | |
1323 | push define_data_tword | |
1324 | jmp define_data | |
1306 | 1325 | data_bytes: |
1307 | call define_data | |
1308 | lods byte [esi] | |
1309 | cmp al,'(' | |
1310 | je get_byte | |
1311 | cmp al,'?' | |
1312 | jne invalid_argument | |
1313 | mov eax,edi | |
1314 | mov byte [edi],0 | |
1315 | inc edi | |
1316 | jmp undefined_data | |
1317 | get_byte: | |
1318 | cmp byte [esi],0 | |
1319 | je get_string | |
1320 | call get_byte_value | |
1321 | stos byte [edi] | |
1322 | ret | |
1323 | get_string: | |
1324 | inc esi | |
1325 | lods dword [esi] | |
1326 | mov ecx,eax | |
1327 | lea eax,[edi+ecx] | |
1328 | cmp eax,[tagged_blocks] | |
1329 | ja out_of_memory | |
1330 | rep movs byte [edi],[esi] | |
1331 | inc esi | |
1332 | ret | |
1333 | undefined_data: | |
1334 | mov ebp,[addressing_space] | |
1335 | test byte [ds:ebp+0Ah],1 | |
1336 | jz mark_undefined_data | |
1337 | ret | |
1338 | mark_undefined_data: | |
1339 | cmp eax,[undefined_data_end] | |
1340 | je undefined_data_ok | |
1341 | mov [undefined_data_start],eax | |
1342 | undefined_data_ok: | |
1343 | mov [undefined_data_end],edi | |
1344 | ret | |
1345 | define_data: | |
1326 | push define_data_byte | |
1327 | define_data: | |
1346 | 1328 | cmp edi,[tagged_blocks] |
1347 | 1329 | jae out_of_memory |
1348 | 1330 | cmp byte [esi],'(' |
1412 | 1394 | dec esi |
1413 | 1395 | add esp,4 |
1414 | 1396 | jmp instruction_assembled |
1415 | data_unicode: | |
1416 | or [base_code],-1 | |
1417 | jmp define_words | |
1418 | data_words: | |
1419 | mov [base_code],0 | |
1420 | define_words: | |
1421 | call define_data | |
1397 | ||
1398 | ||
1399 | ||
1400 | ||
1401 | define_data_byte: | |
1402 | lods byte [esi] | |
1403 | cmp al,'(' | |
1404 | je get_byte | |
1405 | cmp al,'?' | |
1406 | jne invalid_argument | |
1407 | mov eax,edi | |
1408 | mov byte [edi],0 | |
1409 | inc edi | |
1410 | jmp undefined_data | |
1411 | get_byte: | |
1412 | cmp byte [esi],0 | |
1413 | je get_string | |
1414 | call get_byte_value | |
1415 | stos byte [edi] | |
1416 | ret | |
1417 | get_string: | |
1418 | inc esi | |
1419 | lods dword [esi] | |
1420 | mov ecx,eax | |
1421 | lea eax,[edi+ecx] | |
1422 | cmp eax,[tagged_blocks] | |
1423 | ja out_of_memory | |
1424 | rep movs byte [edi],[esi] | |
1425 | inc esi | |
1426 | ret | |
1427 | undefined_data: | |
1428 | mov ebp,[addressing_space] | |
1429 | test byte [ds:ebp+0Ah],1 | |
1430 | jz mark_undefined_data | |
1431 | ret | |
1432 | mark_undefined_data: | |
1433 | cmp eax,[undefined_data_end] | |
1434 | je undefined_data_ok | |
1435 | mov [undefined_data_start],eax | |
1436 | undefined_data_ok: | |
1437 | mov [undefined_data_end],edi | |
1438 | ret | |
1439 | define_data_word: | |
1422 | 1440 | lods byte [esi] |
1423 | 1441 | cmp al,'(' |
1424 | 1442 | je get_word |
1455 | 1473 | word_string_ok: |
1456 | 1474 | inc esi |
1457 | 1475 | ret |
1458 | data_dwords: | |
1459 | call define_data | |
1476 | define_data_dword: | |
1460 | 1477 | lods byte [esi] |
1461 | 1478 | cmp al,'(' |
1462 | 1479 | je get_dword |
1498 | 1515 | call mark_relocation |
1499 | 1516 | stos word [edi] |
1500 | 1517 | ret |
1501 | data_pwords: | |
1502 | call define_data | |
1518 | define_data_pword: | |
1503 | 1519 | lods byte [esi] |
1504 | 1520 | cmp al,'(' |
1505 | 1521 | je get_pword |
1545 | 1561 | call mark_relocation |
1546 | 1562 | stos word [edi] |
1547 | 1563 | ret |
1548 | data_qwords: | |
1549 | call define_data | |
1564 | define_data_qword: | |
1550 | 1565 | lods byte [esi] |
1551 | 1566 | cmp al,'(' |
1552 | 1567 | je get_qword |
1565 | 1580 | mov eax,edx |
1566 | 1581 | stos dword [edi] |
1567 | 1582 | ret |
1568 | data_twords: | |
1569 | call define_data | |
1583 | define_data_tword: | |
1570 | 1584 | lods byte [esi] |
1571 | 1585 | cmp al,'(' |
1572 | 1586 | je get_tword |
85 | 85 | cmp eax,edx |
86 | 86 | jae out_of_memory |
87 | 87 | mov eax,esp |
88 | sub eax,100h | |
89 | jc stack_overflow | |
90 | cmp eax,[stack_limit] | |
88 | sub eax,[stack_limit] | |
89 | cmp eax,100h | |
91 | 90 | jb stack_overflow |
92 | 91 | cmp byte [esi],'(' |
93 | 92 | je expression_value |
160 | 160 | ret |
161 | 161 | parse_block: |
162 | 162 | mov eax,esp |
163 | sub eax,100h | |
164 | jc stack_overflow | |
165 | cmp eax,[stack_limit] | |
163 | sub eax,[stack_limit] | |
164 | cmp eax,100h | |
166 | 165 | jb stack_overflow |
167 | 166 | push [current_line] |
168 | 167 | mov ax,bx |
366 | 365 | jmp skip_parsing_contents |
367 | 366 | skip_parsing_block: |
368 | 367 | mov eax,esp |
369 | sub eax,100h | |
370 | jc stack_overflow | |
371 | cmp eax,[stack_limit] | |
368 | sub eax,[stack_limit] | |
369 | cmp eax,100h | |
372 | 370 | jb stack_overflow |
373 | 371 | push [current_line] |
374 | 372 | mov ax,bx |
824 | 822 | cmp byte [esi],'(' |
825 | 823 | jne expression |
826 | 824 | mov eax,esp |
827 | sub eax,100h | |
828 | jc stack_overflow | |
829 | cmp eax,[stack_limit] | |
825 | sub eax,[stack_limit] | |
826 | cmp eax,100h | |
830 | 827 | jb stack_overflow |
831 | 828 | push esi edi |
832 | 829 | inc esi |
557 | 557 | jne next_directive |
558 | 558 | repe cmps byte [esi],[edi] |
559 | 559 | jb no_directive |
560 | je directive_ok | |
560 | je directive_handler | |
561 | 561 | next_directive: |
562 | 562 | mov edi,ebx |
563 | 563 | add edi,2 |
567 | 567 | mov ecx,ebp |
568 | 568 | stc |
569 | 569 | ret |
570 | directive_ok: | |
570 | directive_handler: | |
571 | 571 | lea esi,[edx+ebp] |
572 | call directive_handler | |
573 | directive_handler: | |
574 | pop ecx | |
575 | 572 | movzx eax,word [ebx] |
576 | add eax,ecx | |
573 | add eax,directive_handler | |
577 | 574 | clc |
578 | 575 | ret |
579 | 576 | |
580 | 577 | preprocess_line: |
581 | 578 | mov eax,esp |
582 | sub eax,100h | |
583 | jc stack_overflow | |
584 | cmp eax,[stack_limit] | |
579 | sub eax,[stack_limit] | |
580 | cmp eax,100h | |
585 | 581 | jb stack_overflow |
586 | 582 | push ecx esi |
587 | 583 | preprocess_current_line: |
32 | 32 | ; cannot simply be copied and put under another distribution licence |
33 | 33 | ; (including the GNU Public Licence). |
34 | 34 | |
35 | VERSION_STRING equ "1.71.57" | |
35 | VERSION_STRING equ "1.71.58" | |
36 | 36 | |
37 | 37 | VERSION_MAJOR = 1 |
38 | 38 | VERSION_MINOR = 71 |
0 | 0 | |
1 | 1 | Visit http://flatassembler.net/ for more information. |
2 | ||
3 | ||
4 | version 1.71.58 (Dec 08, 2016) | |
5 | ||
6 | [+] Added a 64-bit ELF executable version of flat assembler for Linux. It has | |
7 | no extended capabilities compared to regular versions, it just simulates | |
8 | the 32-bit environment to allow running the assembler on systems that | |
9 | support only 64-bit executables. | |
2 | 10 | |
3 | 11 | |
4 | 12 | version 1.71.57 (Sep 26, 2016) |