File: listing.inc

package info (click to toggle)
fasm 1.73.34-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,540 kB
  • sloc: pascal: 4,300; asm: 3,056; makefile: 12
file content (690 lines) | stat: -rw-r--r-- 12,405 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690

listing:
	mov	edx,[input_file]
	call	open
	jc	input_not_found
	call	load_file
	mov	[input],eax
	cmp	ecx,38h
	jb	invalid_input
	cmp	dword [eax],1A736166h
	jne	invalid_input
	cmp	dword [eax+44],0
	je	incomplete_input
	add	[eax+16],eax
	add	[eax+24],eax
	add	[eax+32],eax
	add	[eax+40],eax
	add	[eax+48],eax
	mov	edx,[eax+16]
	add	[eax+8],edx
	add	[eax+12],edx
	mov	edx,[eax+12]
	call	open
	jc	code_not_found
	call	load_file
	mov	[assembled_code],eax
	mov	[assembled_code_length],ecx
	call	close
	mov	[maximum_address_length],0
	mov	ebx,[input]
	mov	esi,[ebx+40]
	lea	ebp,[esi-4]
	add	ebp,[ebx+44]
    get_offsets_for_lines:
	cmp	esi,ebp
	je	offsets_prepared
	mov	edx,[esi+4]
	add	edx,[ebx+32]
      find_line_loaded_from_source:
	test	byte [edx+7],1 shl 7
	jz	store_offset_in_line
	mov	edx,[edx+8]
	add	edx,[ebx+32]
	jmp	find_line_loaded_from_source
      store_offset_in_line:
	cmp	dword [edx+12],0
	jne	get_next_offset
	mov	[edx+12],esi
	movzx	ecx,byte [esi+27]
	and	cl,1
	mov	edi,[esi+20]
	test	edi,edi
	jz	base_name_length_ok
	xor	ecx,ecx
	btr	edi,31
	jc	count_base_name_characters
	dec	edi
	shl	edi,2
	add	edi,[ebx+48]
	mov	edi,[edi]
      count_base_name_characters:
	mov	ecx,[ebx+20]
	sub	ecx,edi
	add	edi,[ebx+16]
	mov	edx,edi
	xor	al,al
	repne	scasb
	mov	ecx,edi
	sub	ecx,edx
      base_name_length_ok:
	cmp	byte [esi+18],1
	jb	first_register_length_ok
	ja	first_register_with_scale
	add	ecx,5
	jmp	first_register_length_ok
      first_register_with_scale:
	add	ecx,5+3
      first_register_length_ok:
	cmp	byte [esi+19],1
	jb	second_register_length_ok
	ja	second_register_with_scale
	add	ecx,5
	jmp	second_register_length_ok
      second_register_with_scale:
	add	ecx,5+3
      second_register_length_ok:
	cmp	ecx,[maximum_address_length]
	jb	get_next_offset
	mov	[maximum_address_length],ecx
      get_next_offset:
	add	esi,28
	jmp	get_offsets_for_lines
    offsets_prepared:
	mov	eax,[esi]
	mov	[code_end],eax
	add	[maximum_address_length],19
	mov	edi,characters
	xor	al,al
      make_characters_table:
	stosb
	inc	al
	jnz	make_characters_table
	mov	edi,characters
	mov	esi,symbol_characters+1
	movzx	ecx,byte [esi-1]
	xor	eax,eax
      mark_symbol_characters:
	lodsb
	mov	byte [edi+eax],0
	loop	mark_symbol_characters
	mov	eax,[code_bytes_per_line]
	imul	eax,3
	add	eax,[maximum_address_length]
	add	eax,18
	call	alloc
	jc	not_enough_memory
	mov	[output_buffer],eax
	mov	esi,[ebx+32]
	mov	ebp,esi
	add	ebp,[ebx+36]
	mov	edx,[output_file]
	call	create
	jc	writing_error
	mov	[output_handle],ebx
	xor	eax,eax
	mov	[current_source_file],eax
	mov	[last_listed_address],eax
	mov	[code_length],eax
    generate_listing:
	cmp	esi,ebp
	jae	listing_done
	mov	edi,[output_buffer]
	test	byte [esi+7],1 shl 7
	jnz	next_line
	mov	ebx,[esi+12]
	test	ebx,ebx
	jz	no_code_listing
	test	byte [ebx+26],11b
	jnz	no_code_listing
	push	esi
	mov	edx,[esi]
	mov	ecx,[esi+4]
     find_next_code_point:
	add	esi,16
	call	skip_preprocessed_line
	cmp	esi,ebp
	je	last_code_point
	cmp	edx,[esi]
	jne	next_line_ok
	cmp	ecx,[esi+4]
	je	find_next_code_point
     next_line_ok:
	test	byte [esi+7],1 shl 7
	jnz	find_next_code_point
	mov	eax,[esi+12]
	test	eax,eax
	jz	find_next_code_point
	test	byte [eax+26],11b
	jnz	find_next_code_point
	mov	eax,[eax]
	jmp	calculate_code_length
     last_code_point:
	mov	eax,[code_end]
     calculate_code_length:
	pop	esi
	mov	edx,[ebx]
	sub	eax,edx
	jz	no_code_listing
	mov	[code_length],eax
	mov	[code_offset],edx
	add	eax,edx
	cmp	eax,[assembled_code_length]
	jbe	write_file_offset
	mov	[code_length],0
      write_file_offset:
	call	write_hex_dword
	mov	ax,': '
	stosw
	call	list_address
	call	list_code
	jmp	code_listing_ok
      no_code_listing:
	mov	al,20h
	mov	ecx,8+2
	rep	stosb
	call	list_address
	mov	ecx,[code_bytes_per_line]
	imul	ecx,3
	mov	al,20h
	rep	stosb
      code_listing_ok:
	call	write_listing_data
	mov	eax,[input]
	mov	edx,[esi]
	test	edx,edx
	jz	main_source_file
	add	edx,[eax+32]
	jmp	source_name_ok
      main_source_file:
	mov	edx,[eax+8]
      source_name_ok:
	cmp	edx,[current_source_file]
	je	source_loaded
	push	ebx
	push	edx
	call	open
	jc	source_not_found
	pop	eax
	xchg	eax,[current_source_file]
	test	eax,eax
	jz	load_source
	mov	eax,[source]
	call	free
      load_source:
	call	load_file
	mov	[source],eax
	mov	[source_length],ecx
	call	close
	pop	ebx
      source_loaded:
	mov	eax,[source]
	add	eax,[esi+8]
	mov	[current_source_line],eax
	push	esi ebp
	call	write_source_line
	pop	ebp esi
      write_supplemental_rows:
	mov	eax,[code_length]
	or	eax,[current_source_line]
	jz	next_line
	mov	edi,[output_buffer]
	mov	ecx,8+2
	movzx	eax,[show_addresses]
	imul	eax,[maximum_address_length]
	add	ecx,eax
	mov	al,20h
	rep	stosb
	call	list_code
	call	write_listing_data
	push	esi ebp
	call	write_source_line
	pop	ebp esi
	jmp	write_supplemental_rows
      next_line:
	mov	edx,[esi]
	mov	ecx,[esi+4]
      find_next_line:
	add	esi,16
	call	skip_preprocessed_line
	cmp	edx,[esi]
	jne	generate_listing
	cmp	ecx,[esi+4]
	jne	generate_listing
	jmp	find_next_line
    list_address:
	cmp	[show_addresses],0
	je	address_ok
	mov	[address_start],edi
	mov	eax,[esi+12]
	test	eax,eax
	jz	address_finished
	cmp	[last_listed_address],0
	je	make_address
	push	esi edi
	lea	esi,[eax+8]
	mov	edi,[last_listed_address]
	mov	ecx,17
	repe	cmpsb
	pop	edi esi
	je	address_finished
      make_address:
	mov	ebx,[esi+12]
	lea	eax,[ebx+8]
	mov	[last_listed_address],eax
	mov	al,'['
	stosb
	mov	edx,[ebx+20]
	test	edx,edx
	jz	write_main_address
	push	esi
	mov	esi,edx
	mov	eax,[input]
	btr	esi,31
	jc	base_name_ready
	dec	esi
	shl	esi,2
	add	esi,[eax+48]
	mov	esi,[esi]
      base_name_ready:
	add	esi,[eax+16]
      copy_section_name:
	lodsb
	test	al,al
	jz	section_name_ok
	stosb
	jmp	copy_section_name
      section_name_ok:
	pop	esi
	mov	al,':'
	test	edx,80000000h
	jz	address_separator_ok
	cmp	byte [ebx+27],0
	jne	address_separator_ok
	mov	al,'+'
      address_separator_ok:
	stosb
      write_main_address:
	cmp	byte [ebx+27],0
	jne	write_negative_address
	mov	edx,[ebx+8+4]
	call	write_hex_dword
	mov	edx,[ebx+8]
	call	write_hex_dword
	jmp	write_address_registers
      write_negative_address:
	mov	al,'-'
	stosb
	mov	eax,[ebx+8]
	mov	edx,[ebx+8+4]
	not	eax
	not	edx
	add	eax,1
	adc	edx,0
	push	eax
	call	write_hex_dword
	pop	edx
	call	write_hex_dword
      write_address_registers:
	mov	dl,[ebx+16]
	mov	dh,[ebx+18]
	call	address_register
	mov	dl,[ebx+17]
	mov	dh,[ebx+19]
	call	address_register
	mov	ax,']'
	stosb
      address_finished:
	mov	ecx,[maximum_address_length]
	sub	ecx,edi
	add	ecx,[address_start]
	mov	al,20h
	rep	stosb
      address_ok:
	ret
      address_register:
	cmp	dh,0
	je	register_ok
	jl	negative_register
	mov	al,'+'
	jmp	register_sign_ok
      negative_register:
	mov	al,'-'
      register_sign_ok:
	stosb
	push	esi
	mov	esi,address_registers
      find_register:
	lodsb
	test	al,al
	jz	register_found
	cmp	al,dl
	je	register_found
	cmp	dl,[esi]
	je	register_found
	lodsb
	movzx	eax,al
	add	esi,eax
	jmp	find_register
      register_found:
	lodsb
	movzx	ecx,al
	rep	movsb
	pop	esi
	cmp	dh,1
	je	register_ok
	mov	al,'*'
	stosb
	test	dh,0F0h
	jz	first_scale_digit_ok
	mov	al,dh
	shr	al,4
	cmp	al,10
	sbb	al,69h
	das
	stosb
      first_scale_digit_ok:
	mov	al,dh
	and	al,1111b
	cmp	al,10
	sbb	al,69h
	das
	stosb
      register_ok:
	ret
    list_code:
	mov	ecx,[code_length]
	cmp	ecx,[code_bytes_per_line]
	jb	code_bytes_count_ready
	mov	ecx,[code_bytes_per_line]
      code_bytes_count_ready:
	sub	[code_length],ecx
	mov	edx,[code_offset]
	add	[code_offset],ecx
	jecxz	code_bytes_ok
	push	ecx
	add	edx,[assembled_code]
      list_code_bytes:
	mov	al,[edx]
	and	al,1111b
	cmp	al,10
	sbb	al,69h
	das
	mov	ah,al
	mov	al,[edx]
	shr	al,4
	cmp	al,10
	sbb	al,69h
	das
	stosw
	mov	al,20h
	stosb
	inc	edx
	loop	list_code_bytes
	pop	ecx
      code_bytes_ok:
	neg	ecx
	add	ecx,[code_bytes_per_line]
	imul	ecx,3
	mov	al,20h
	rep	stosb
	ret
    write_listing_data:
	mov	ecx,[output_buffer]
	sub	ecx,edi
	and	ecx,111b
	mov	al,20h
	rep	stosb
	mov	edx,[output_buffer]
	mov	ecx,edi
	sub	ecx,edx
	mov	ebx,[output_handle]
	call	write
	jc	writing_error
	ret
    write_source_line:
	mov	esi,[current_source_line]
	test	esi,esi
	je	write_line_break
	mov	ebp,[source_length]
	add	ebp,[source]
	mov	ebx,characters
	xor	cl,cl
      start_cutting:
	xor	dl,dl
      cut_source_line:
	cmp	esi,ebp
	je	end_of_file
	lodsb
	cmp	al,0Dh
	je	cr_character
	cmp	al,0Ah
	je	lf_character
	cmp	al,1Ah
	je	end_of_line
	or	al,al
	jz	end_of_line
	cmp	dl,3Bh
	je	cut_source_line
	cmp	al,3Bh
	je	start_special_block
	cmp	dl,22h
	je	inside_string
	cmp	dl,27h
	je	inside_string
	cmp	al,'\'
	je	check_for_line_continuation
	xlatb
	test	al,al
	jz	start_cutting
	cmp	dl,0FFh
	je	cut_source_line
	cmp	al,22h
	je	start_special_block
	cmp	al,27h
	je	start_special_block
	mov	dl,0FFh
	jmp	cut_source_line
      start_special_block:
	mov	dl,al
	jmp	cut_source_line
      inside_string:
	cmp	al,dl
	jne	cut_source_line
	jmp	start_cutting
      check_for_line_continuation:
	or	cl,0FFh
	cmp	esi,ebp
	je	end_of_file
	mov	al,[esi]
	cmp	al,20h
	je	start_cutting
	cmp	al,0Dh
	je	start_cutting
	cmp	al,0Ah
	je	start_cutting
	cmp	al,3Bh
	je	start_cutting
	xor	cl,cl
	jmp	start_cutting
      cr_character:
	mov	edx,esi
	mov	word [line_break],0Dh
	cmp	esi,ebp
	je	line_with_break
	mov	al,[esi]
	cmp	al,0Ah
	jne	line_with_break
	inc	edx
	mov	[line_break+1],al
	jmp	line_with_break
      lf_character:
	mov	edx,esi
	mov	word [line_break],0Ah
	cmp	esi,ebp
	je	line_with_break
	mov	al,[esi]
	cmp	al,0Dh
	jne	line_with_break
	inc	edx
	mov	[line_break+1],al
      line_with_break:
	dec	esi
	jmp	write_line
      end_of_line:
	dec	esi
      end_of_file:
	mov	edx,esi
      write_line:
	cmp	cl,0FFh
	je	continued_line
	xor	edx,edx
      continued_line:
	xchg	edx,[current_source_line]
	mov	ecx,esi
	sub	ecx,edx
	mov	ebx,[output_handle]
	call	write
	jc	writing_error
      write_line_break:
	mov	edx,line_break
	mov	ecx,2
	cmp	[line_break+1],0
	jne	line_break_size_ok
	dec	ecx
      line_break_size_ok:
	call	write
	jc	writing_error
	ret
    listing_done:
	mov	ebx,[output_handle]
	call	close
	ret

load_file:
	push	ebx
	mov	al,2
	xor	edx,edx
	call	lseek
	test	eax,eax
	jz	empty_file
	push	eax
	call	alloc
	jc	not_enough_memory
	push	eax
	xor	al,al
	xor	edx,edx
	call	lseek
	mov	ecx,[esp+4]
	mov	edx,[esp]
	call	read
	jc	reading_error
	pop	eax ecx
	pop	ebx
	ret
      empty_file:
	pop	ebx
	mov	ecx,eax
	ret

write_hex_dword:
	mov	ecx,8
      write_hex_digits:
	xor	al,al
	shld	eax,edx,4
	cmp	al,10
	sbb	al,69h
	das
	stosb
	shl	edx,4
	loop	write_hex_digits
	ret

skip_preprocessed_line:
	lods	byte [esi]
	cmp	al,1Ah
	je	skip_preprocessed_symbol
	cmp	al,3Bh
	je	skip_preprocessed_symbol
	cmp	al,22h
	je	skip_preprocessed_string
	or	al,al
	jnz	skip_preprocessed_line
	ret
      skip_preprocessed_symbol:
	lods	byte [esi]
	movzx	eax,al
	add	esi,eax
	jmp	skip_preprocessed_line
      skip_preprocessed_string:
	lods	dword [esi]
	add	esi,eax
	jmp	skip_preprocessed_line


not_enough_memory:
	call	error
	db	'not enough memory to load the required data',0
input_not_found:
	call	error
	db	'the input file was not found',0
code_not_found:
	call	error
	db	'the assembled file was not found',0
source_not_found:
	call	error
	db	'could not find some of the source files',0
reading_error:
	call	error
	db	'some error occured while trying to read file',0
writing_error:
	call	error
	db	'some error occured while trying to write file',0
invalid_input:
	call	error
	db	'input file is not a recognized assembly information format',0
incomplete_input:
	call	error
	db	'input file does not contain an assembly dump',0

symbol_characters db 27, 9,0Ah,0Dh,1Ah,20h,'+-/*=<>()[]{}:,|&~#`;\'

address_registers db 23h,2,'bx'
		  db 25h,2,'bp'
		  db 26h,2,'si'
		  db 27h,2,'di'
		  db 40h,3,'eax'
		  db 41h,3,'ecx'
		  db 42h,3,'edx'
		  db 43h,3,'ebx'
		  db 44h,3,'esp'
		  db 45h,3,'ebp'
		  db 46h,3,'esi'
		  db 47h,3,'edi'
		  db 48h,3,'r8d'
		  db 49h,3,'r9d'
		  db 4Ah,4,'r10d'
		  db 4Bh,4,'r11d'
		  db 4Ch,4,'r12d'
		  db 4Dh,4,'r13d'
		  db 4Eh,4,'r14d'
		  db 4Fh,4,'r15d'
		  db 80h,3,'rax'
		  db 81h,3,'rcx'
		  db 82h,3,'rdx'
		  db 83h,3,'rbx'
		  db 84h,3,'rsp'
		  db 85h,3,'rbp'
		  db 86h,3,'rsi'
		  db 87h,3,'rdi'
		  db 88h,2,'r8'
		  db 89h,2,'r9'
		  db 8Ah,3,'r10'
		  db 8Bh,3,'r11'
		  db 8Ch,3,'r12'
		  db 8Dh,3,'r13'
		  db 8Eh,3,'r14'
		  db 8Fh,3,'r15'
		  db 0F4h,3,'eip'
		  db 0F8h,3,'rip'
		  db 0,1,'?'