asm_dip/toolchain/fasmw17332/TOOLS/LISTING.INC
2024-11-24 23:13:28 -05:00

691 lines
12 KiB
Plaintext

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,'?'