Initall commit
This commit is contained in:
690
fasmw172/TOOLS/LISTING.INC
Normal file
690
fasmw172/TOOLS/LISTING.INC
Normal file
@@ -0,0 +1,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,'?'
|
||||
Reference in New Issue
Block a user