Line 0
Link Here
|
|
|
1 |
|
2 |
; flat assembler interface for libc |
3 |
; Copyright (c) 1999-2004, Tomasz Grysztar. |
4 |
; All rights reserved. |
5 |
|
6 |
extrn malloc |
7 |
extrn free |
8 |
extrn getenv |
9 |
extrn fopen |
10 |
extrn fclose |
11 |
extrn fread |
12 |
extrn fwrite |
13 |
extrn fseek |
14 |
extrn ftell |
15 |
extrn chmod |
16 |
extrn putchar |
17 |
extrn time |
18 |
extrn exit |
19 |
|
20 |
S_ISUID = 4000o |
21 |
S_ISGID = 2000o |
22 |
S_ISVTX = 1000o |
23 |
S_IRUSR = 0400o |
24 |
S_IWUSR = 0200o |
25 |
S_IXUSR = 0100o |
26 |
S_IRGRP = 0040o |
27 |
S_IWGRP = 0020o |
28 |
S_IXGRP = 0010o |
29 |
S_IROTH = 0004o |
30 |
S_IWOTH = 0002o |
31 |
S_IXOTH = 0001o |
32 |
|
33 |
init_memory: |
34 |
mov ecx,[memory_setting] |
35 |
or ecx,ecx |
36 |
jnz allocate_memory |
37 |
mov ecx,4000h |
38 |
allocate_memory: |
39 |
shl ecx,10 |
40 |
mov [memory_setting],ecx |
41 |
ccall malloc,ecx |
42 |
or eax,eax |
43 |
jz out_of_memory |
44 |
mov [additional_memory],eax |
45 |
add eax,[memory_setting] |
46 |
mov [memory_end],eax |
47 |
mov eax,[memory_setting] |
48 |
shr eax,3 |
49 |
imul eax,3 |
50 |
add eax,[additional_memory] |
51 |
mov [additional_memory_end],eax |
52 |
mov [memory_start],eax |
53 |
ret |
54 |
|
55 |
exit_program: |
56 |
movzx eax,al |
57 |
push eax |
58 |
ccall free,[additional_memory] |
59 |
call exit |
60 |
mov esp,[stack_frame] |
61 |
pop ebp |
62 |
ret |
63 |
|
64 |
get_params: |
65 |
mov [input_file],0 |
66 |
mov [output_file],0 |
67 |
mov [memory_setting],0 |
68 |
mov [passes_limit],100 |
69 |
mov ecx,[argc] |
70 |
mov ebx,[argv] |
71 |
add ebx,4 |
72 |
dec ecx |
73 |
jz bad_params |
74 |
get_param: |
75 |
mov esi,[ebx] |
76 |
mov al,[esi] |
77 |
cmp al,'-' |
78 |
je option_param |
79 |
cmp [input_file],0 |
80 |
jne get_output_file |
81 |
mov [input_file],esi |
82 |
jmp next_param |
83 |
get_output_file: |
84 |
cmp [output_file],0 |
85 |
jne bad_params |
86 |
mov [output_file],esi |
87 |
jmp next_param |
88 |
option_param: |
89 |
inc esi |
90 |
lodsb |
91 |
cmp al,'m' |
92 |
je memory_option |
93 |
cmp al,'M' |
94 |
je memory_option |
95 |
cmp al,'p' |
96 |
je passes_option |
97 |
cmp al,'P' |
98 |
je passes_option |
99 |
bad_params: |
100 |
stc |
101 |
ret |
102 |
memory_option: |
103 |
cmp byte [esi],0 |
104 |
jne get_memory_setting |
105 |
dec ecx |
106 |
jz bad_params |
107 |
add ebx,4 |
108 |
mov esi,[ebx] |
109 |
get_memory_setting: |
110 |
call get_option_value |
111 |
or edx,edx |
112 |
jz bad_params |
113 |
cmp edx,1 shl (32-10) |
114 |
jae bad_params |
115 |
mov [memory_setting],edx |
116 |
jmp next_param |
117 |
passes_option: |
118 |
cmp byte [esi],0 |
119 |
jne get_passes_setting |
120 |
dec ecx |
121 |
jz bad_params |
122 |
add ebx,4 |
123 |
mov esi,[ebx] |
124 |
get_passes_setting: |
125 |
call get_option_value |
126 |
or edx,edx |
127 |
jz bad_params |
128 |
cmp edx,10000h |
129 |
ja bad_params |
130 |
mov [passes_limit],dx |
131 |
next_param: |
132 |
add ebx,4 |
133 |
dec ecx |
134 |
jnz get_param |
135 |
cmp [input_file],0 |
136 |
je bad_params |
137 |
clc |
138 |
ret |
139 |
get_option_value: |
140 |
xor eax,eax |
141 |
mov edx,eax |
142 |
get_option_digit: |
143 |
lodsb |
144 |
cmp al,20h |
145 |
je option_value_ok |
146 |
cmp al,0Dh |
147 |
je option_value_ok |
148 |
or al,al |
149 |
jz option_value_ok |
150 |
sub al,30h |
151 |
jc invalid_option_value |
152 |
cmp al,9 |
153 |
ja invalid_option_value |
154 |
imul edx,10 |
155 |
jo invalid_option_value |
156 |
add edx,eax |
157 |
jc invalid_option_value |
158 |
jmp get_option_digit |
159 |
option_value_ok: |
160 |
dec esi |
161 |
clc |
162 |
ret |
163 |
invalid_option_value: |
164 |
stc |
165 |
ret |
166 |
|
167 |
get_environment_variable: |
168 |
ccall getenv,esi |
169 |
mov esi,eax |
170 |
or eax,eax |
171 |
jz no_environment_variable |
172 |
copy_variable_value: |
173 |
lodsb |
174 |
cmp edi,[memory_end] |
175 |
jae out_of_memory |
176 |
stosb |
177 |
or al,al |
178 |
jnz copy_variable_value |
179 |
dec edi |
180 |
ret |
181 |
no_environment_variable: |
182 |
stosb |
183 |
dec edi |
184 |
ret |
185 |
|
186 |
open: |
187 |
push esi edi ebp |
188 |
call adapt_path |
189 |
ccall fopen,buffer,open_mode |
190 |
pop ebp edi esi |
191 |
or eax,eax |
192 |
jz file_error |
193 |
mov ebx,eax |
194 |
clc |
195 |
ret |
196 |
adapt_path: |
197 |
mov esi,edx |
198 |
mov edi,buffer |
199 |
copy_path: |
200 |
lods byte [esi] |
201 |
cmp al,'\' |
202 |
jne path_char_ok |
203 |
mov al,'/' |
204 |
path_char_ok: |
205 |
stos byte [edi] |
206 |
or al,al |
207 |
jnz copy_path |
208 |
cmp edi,buffer+1000h |
209 |
ja out_of_memory |
210 |
ret |
211 |
create: |
212 |
push esi edi ebp |
213 |
call adapt_path |
214 |
ccall fopen,buffer,create_mode |
215 |
cmp [output_format],5 |
216 |
jne created_ok |
217 |
bt [format_flags],0 |
218 |
jnc created_ok |
219 |
push eax |
220 |
ccall chmod,buffer,S_IRUSR+S_IWUSR+S_IRGRP+S_IROTH+S_IXUSR+S_IXGRP+S_IXOTH |
221 |
pop eax |
222 |
created_ok: |
223 |
pop ebp edi esi |
224 |
or eax,eax |
225 |
jz file_error |
226 |
mov ebx,eax |
227 |
clc |
228 |
ret |
229 |
close: |
230 |
ccall fclose,ebx |
231 |
ret |
232 |
read: |
233 |
push ebx ecx edx esi edi |
234 |
ccall fread,edx,1,ecx,ebx |
235 |
pop edi esi edx ecx ebx |
236 |
cmp eax,ecx |
237 |
jne file_error |
238 |
clc |
239 |
ret |
240 |
file_error: |
241 |
stc |
242 |
ret |
243 |
write: |
244 |
push ebx ecx edx esi edi |
245 |
ccall fwrite,edx,1,ecx,ebx |
246 |
pop edi esi edx ecx ebx |
247 |
cmp eax,ecx |
248 |
jne file_error |
249 |
clc |
250 |
ret |
251 |
lseek: |
252 |
push ebx |
253 |
movzx eax,al |
254 |
ccall fseek,ebx,edx,eax |
255 |
mov ebx,[esp] |
256 |
ccall ftell,ebx |
257 |
pop ebx |
258 |
ret |
259 |
|
260 |
display_string: |
261 |
lodsb |
262 |
or al,al |
263 |
jz string_displayed |
264 |
mov dl,al |
265 |
call display_character |
266 |
jmp display_string |
267 |
string_displayed: |
268 |
ret |
269 |
display_character: |
270 |
movzx edx,dl |
271 |
ccall putchar,edx |
272 |
ret |
273 |
display_number: |
274 |
push ebx |
275 |
mov ecx,1000000000 |
276 |
xor edx,edx |
277 |
xor bl,bl |
278 |
display_loop: |
279 |
div ecx |
280 |
push edx |
281 |
cmp ecx,1 |
282 |
je display_digit |
283 |
or bl,bl |
284 |
jnz display_digit |
285 |
or al,al |
286 |
jz digit_ok |
287 |
not bl |
288 |
display_digit: |
289 |
mov dl,al |
290 |
add dl,30h |
291 |
push ebx ecx |
292 |
call display_character |
293 |
pop ecx ebx |
294 |
digit_ok: |
295 |
mov eax,ecx |
296 |
xor edx,edx |
297 |
mov ecx,10 |
298 |
div ecx |
299 |
mov ecx,eax |
300 |
pop eax |
301 |
or ecx,ecx |
302 |
jnz display_loop |
303 |
pop ebx |
304 |
ret |
305 |
|
306 |
display_user_messages: |
307 |
mov [displayed_count],0 |
308 |
call flush_display_buffer |
309 |
cmp [displayed_count],0 |
310 |
je line_break_ok |
311 |
cmp [last_displayed],0Ah |
312 |
je line_break_ok |
313 |
mov dl,0Ah |
314 |
call display_character |
315 |
line_break_ok: |
316 |
ret |
317 |
display_block: |
318 |
jecxz block_displayed |
319 |
add [displayed_count],ecx |
320 |
mov al,[esi+ecx-1] |
321 |
mov [last_displayed],al |
322 |
display_characters: |
323 |
lodsb |
324 |
mov dl,al |
325 |
push ecx esi |
326 |
call display_character |
327 |
pop esi ecx |
328 |
loop display_characters |
329 |
block_displayed: |
330 |
ret |
331 |
|
332 |
fatal_error: |
333 |
mov esi,error_prefix |
334 |
call display_string |
335 |
pop esi |
336 |
call display_string |
337 |
mov esi,error_suffix |
338 |
call display_string |
339 |
mov al,0FFh |
340 |
jmp exit_program |
341 |
assembler_error: |
342 |
call display_user_messages |
343 |
push dword 0 |
344 |
mov ebx,[current_line] |
345 |
get_error_lines: |
346 |
push ebx |
347 |
test byte [ebx+7],80h |
348 |
jz display_error_line |
349 |
mov edx,ebx |
350 |
find_definition_origin: |
351 |
mov edx,[edx+12] |
352 |
test byte [edx+7],80h |
353 |
jnz find_definition_origin |
354 |
push edx |
355 |
mov ebx,[ebx+8] |
356 |
jmp get_error_lines |
357 |
display_error_line: |
358 |
mov esi,[ebx] |
359 |
call display_string |
360 |
mov esi,line_number_start |
361 |
call display_string |
362 |
mov eax,[ebx+4] |
363 |
and eax,7FFFFFFFh |
364 |
call display_number |
365 |
mov dl,']' |
366 |
call display_character |
367 |
pop esi |
368 |
cmp ebx,esi |
369 |
je line_number_ok |
370 |
mov dl,20h |
371 |
call display_character |
372 |
push esi |
373 |
mov esi,[esi] |
374 |
movzx ecx,byte [esi] |
375 |
inc esi |
376 |
call display_block |
377 |
mov esi,line_number_start |
378 |
call display_string |
379 |
pop esi |
380 |
mov eax,[esi+4] |
381 |
and eax,7FFFFFFFh |
382 |
call display_number |
383 |
mov dl,']' |
384 |
call display_character |
385 |
line_number_ok: |
386 |
mov esi,line_data_start |
387 |
call display_string |
388 |
mov esi,ebx |
389 |
mov edx,[esi] |
390 |
call open |
391 |
mov al,2 |
392 |
xor edx,edx |
393 |
call lseek |
394 |
mov edx,[esi+8] |
395 |
sub eax,edx |
396 |
push eax |
397 |
xor al,al |
398 |
call lseek |
399 |
mov ecx,[esp] |
400 |
mov edx,[additional_memory] |
401 |
lea eax,[edx+ecx] |
402 |
cmp eax,[additional_memory_end] |
403 |
ja out_of_memory |
404 |
call read |
405 |
call close |
406 |
pop ecx |
407 |
mov esi,[additional_memory] |
408 |
get_line_data: |
409 |
mov al,[esi] |
410 |
cmp al,0Ah |
411 |
je display_line_data |
412 |
cmp al,0Dh |
413 |
je display_line_data |
414 |
cmp al,1Ah |
415 |
je display_line_data |
416 |
or al,al |
417 |
jz display_line_data |
418 |
inc esi |
419 |
loop get_line_data |
420 |
display_line_data: |
421 |
mov ecx,esi |
422 |
mov esi,[additional_memory] |
423 |
sub ecx,esi |
424 |
call display_block |
425 |
mov esi,lf |
426 |
call display_string |
427 |
pop ebx |
428 |
or ebx,ebx |
429 |
jnz display_error_line |
430 |
mov esi,error_prefix |
431 |
call display_string |
432 |
pop esi |
433 |
call display_string |
434 |
mov esi,error_suffix |
435 |
call display_string |
436 |
mov al,2 |
437 |
jmp exit_program |
438 |
|
439 |
make_timestamp: |
440 |
ccall time,timestamp |
441 |
mov eax,[timestamp] |
442 |
ret |
443 |
|
444 |
open_mode db 'r',0 |
445 |
create_mode db 'w',0 |
446 |
|
447 |
error_prefix db 'error: ',0 |
448 |
error_suffix db '.' |
449 |
lf db 0xA,0 |
450 |
line_number_start db ' [',0 |
451 |
line_data_start db ':',0xA,0 |
452 |
|
453 |
macro dm string { db string,0 } |