add flat assembler toolchain
This commit is contained in:
229
toolchain/fasmw17332/TOOLS/DOS/LISTING.ASM
Normal file
229
toolchain/fasmw17332/TOOLS/DOS/LISTING.ASM
Normal file
@ -0,0 +1,229 @@
|
||||
|
||||
format MZ
|
||||
heap 0
|
||||
stack 8000h
|
||||
entry loader:init
|
||||
|
||||
include 'loader.inc'
|
||||
|
||||
segment main use32
|
||||
|
||||
start:
|
||||
|
||||
call get_params
|
||||
jnc make_listing
|
||||
|
||||
mov esi,_usage
|
||||
call display_string
|
||||
mov ax,4C02h
|
||||
int 21h
|
||||
|
||||
make_listing:
|
||||
call listing
|
||||
mov ax,4C00h
|
||||
int 21h
|
||||
|
||||
error:
|
||||
mov esi,_error_prefix
|
||||
call display_string
|
||||
pop esi
|
||||
call display_string
|
||||
mov esi,_error_suffix
|
||||
call display_string
|
||||
mov ax,4C00h
|
||||
int 21h
|
||||
|
||||
get_params:
|
||||
push ds
|
||||
mov ds,[psp_selector]
|
||||
mov esi,81h
|
||||
mov edi,params
|
||||
find_param:
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je find_param
|
||||
cmp al,'-'
|
||||
je option_param
|
||||
cmp al,0Dh
|
||||
je all_params
|
||||
or al,al
|
||||
jz all_params
|
||||
cmp [es:input_file],0
|
||||
jne get_output_file
|
||||
mov [es:input_file],edi
|
||||
jmp process_param
|
||||
get_output_file:
|
||||
cmp [es:output_file],0
|
||||
jne bad_params
|
||||
mov [es:output_file],edi
|
||||
process_param:
|
||||
cmp al,22h
|
||||
je string_param
|
||||
copy_param:
|
||||
stosb
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je param_end
|
||||
cmp al,0Dh
|
||||
je param_end
|
||||
or al,al
|
||||
jz param_end
|
||||
jmp copy_param
|
||||
string_param:
|
||||
lodsb
|
||||
cmp al,22h
|
||||
je string_param_end
|
||||
cmp al,0Dh
|
||||
je param_end
|
||||
or al,al
|
||||
jz param_end
|
||||
stosb
|
||||
jmp string_param
|
||||
option_param:
|
||||
lodsb
|
||||
cmp al,'a'
|
||||
je addresses_option
|
||||
cmp al,'A'
|
||||
je addresses_option
|
||||
cmp al,'b'
|
||||
je bytes_per_line_option
|
||||
cmp al,'B'
|
||||
je bytes_per_line_option
|
||||
invalid_option:
|
||||
pop ds
|
||||
stc
|
||||
ret
|
||||
get_option_value:
|
||||
xor eax,eax
|
||||
mov edx,eax
|
||||
get_option_digit:
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je option_value_ok
|
||||
cmp al,0Dh
|
||||
je option_value_ok
|
||||
or al,al
|
||||
jz option_value_ok
|
||||
sub al,30h
|
||||
jc bad_params_value
|
||||
cmp al,9
|
||||
ja bad_params_value
|
||||
imul edx,10
|
||||
jo bad_params_value
|
||||
add edx,eax
|
||||
jc bad_params_value
|
||||
jmp get_option_digit
|
||||
option_value_ok:
|
||||
dec esi
|
||||
clc
|
||||
ret
|
||||
bad_params_value:
|
||||
stc
|
||||
ret
|
||||
bytes_per_line_option:
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je bytes_per_line_option
|
||||
cmp al,0Dh
|
||||
je invalid_option
|
||||
or al,al
|
||||
jz invalid_option
|
||||
dec esi
|
||||
call get_option_value
|
||||
jc bad_params
|
||||
or edx,edx
|
||||
jz invalid_option
|
||||
cmp edx,1000
|
||||
ja invalid_option
|
||||
mov [es:code_bytes_per_line],edx
|
||||
jmp find_param
|
||||
addresses_option:
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je set_addresses_option
|
||||
cmp al,0Dh
|
||||
je set_addresses_option
|
||||
or al,al
|
||||
jnz bad_params
|
||||
set_addresses_option:
|
||||
dec esi
|
||||
mov [es:show_addresses],1
|
||||
jmp find_param
|
||||
param_end:
|
||||
dec esi
|
||||
string_param_end:
|
||||
xor al,al
|
||||
stosb
|
||||
jmp find_param
|
||||
all_params:
|
||||
xor al,al
|
||||
stosb
|
||||
pop ds
|
||||
cmp [input_file],0
|
||||
je bad_params
|
||||
cmp [output_file],0
|
||||
je bad_params
|
||||
clc
|
||||
ret
|
||||
bad_params:
|
||||
stc
|
||||
ret
|
||||
|
||||
include 'system.inc'
|
||||
|
||||
include '..\listing.inc'
|
||||
|
||||
_usage db 'listing generator for flat assembler',0Dh,0Ah
|
||||
db 'usage: listing <input> <output>',0Dh,0Ah
|
||||
db 'optional settings:',0Dh,0Ah
|
||||
db ' -a show target addresses for assembled code',0Dh,0Ah
|
||||
db ' -b <number> set the amount of bytes listed per line',0Dh,0Ah
|
||||
db 0
|
||||
_error_prefix db 'error: ',0
|
||||
_error_suffix db '.',0Dh,0Ah,0
|
||||
|
||||
input_file dd 0
|
||||
output_file dd 0
|
||||
code_bytes_per_line dd 16
|
||||
show_addresses db 0
|
||||
|
||||
line_break db 0Dh,0Ah
|
||||
|
||||
input dd ?
|
||||
assembled_code dd ?
|
||||
assembled_code_length dd ?
|
||||
code_end dd ?
|
||||
code_offset dd ?
|
||||
code_length dd ?
|
||||
output_handle dd ?
|
||||
output_buffer dd ?
|
||||
current_source_file dd ?
|
||||
current_source_line dd ?
|
||||
source dd ?
|
||||
source_length dd ?
|
||||
maximum_address_length dd ?
|
||||
address_start dd ?
|
||||
last_listed_address dd ?
|
||||
|
||||
psp_selector dw ?
|
||||
environment_selector dw ?
|
||||
|
||||
memory_handles_count dd ?
|
||||
memory_handles rd 400h
|
||||
|
||||
params rb 1000h
|
||||
characters rb 100h
|
||||
|
||||
segment buffer_segment
|
||||
|
||||
buffer = (buffer_segment-main) shl 4
|
||||
|
||||
db 1000h dup ?
|
||||
|
||||
segment stack_segment
|
||||
|
||||
stack_bottom = (stack_segment-main) shl 4
|
||||
|
||||
db 4000h dup ?
|
||||
|
||||
stack_top = stack_bottom + $
|
102
toolchain/fasmw17332/TOOLS/DOS/LOADER.INC
Normal file
102
toolchain/fasmw17332/TOOLS/DOS/LOADER.INC
Normal file
@ -0,0 +1,102 @@
|
||||
|
||||
segment loader use16
|
||||
|
||||
init:
|
||||
|
||||
mov ax,1687h
|
||||
int 2Fh
|
||||
or ax,ax ; DPMI installed?
|
||||
jnz short no_dpmi
|
||||
test bl,1 ; 32-bit programs supported?
|
||||
jz short no_dpmi
|
||||
mov word [cs:mode_switch],di
|
||||
mov word [cs:mode_switch+2],es
|
||||
mov bx,si ; allocate memory for DPMI data
|
||||
mov ah,48h
|
||||
int 21h
|
||||
jnc init_protected_mode
|
||||
init_failed:
|
||||
call init_error
|
||||
db 'error: DPMI initialization failed.',0Dh,0Ah,0
|
||||
no_dpmi:
|
||||
call init_error
|
||||
db 'error: 32-bit DPMI services are not available.',0Dh,0Ah,0
|
||||
init_error:
|
||||
pop si
|
||||
push cs
|
||||
pop ds
|
||||
display_error:
|
||||
lodsb
|
||||
test al,al
|
||||
jz short error_finish
|
||||
mov dl,al
|
||||
mov ah,2
|
||||
int 21h
|
||||
jmp short display_error
|
||||
error_finish:
|
||||
mov ax,4CFFh
|
||||
int 21h
|
||||
init_protected_mode:
|
||||
mov es,ax
|
||||
mov ds,[ds:2Ch]
|
||||
mov ax,1
|
||||
call far [cs:mode_switch] ; switch to protected mode
|
||||
jc init_failed
|
||||
mov cx,1
|
||||
xor ax,ax
|
||||
int 31h ; allocate descriptor for code
|
||||
jc init_failed
|
||||
mov si,ax
|
||||
xor ax,ax
|
||||
int 31h ; allocate descriptor for data
|
||||
jc init_failed
|
||||
mov di,ax
|
||||
mov dx,cs
|
||||
lar cx,dx
|
||||
shr cx,8
|
||||
or cx,0C000h
|
||||
mov bx,si
|
||||
mov ax,9
|
||||
int 31h ; set code descriptor access rights
|
||||
jc init_failed
|
||||
mov dx,ds
|
||||
lar cx,dx
|
||||
shr cx,8
|
||||
or cx,0C000h
|
||||
mov bx,di
|
||||
int 31h ; set data descriptor access rights
|
||||
jc init_failed
|
||||
mov ecx,main
|
||||
shl ecx,4
|
||||
mov dx,cx
|
||||
shr ecx,16
|
||||
mov ax,7
|
||||
int 31h ; set data descriptor base address
|
||||
jc init_failed
|
||||
mov bx,si
|
||||
int 31h ; set code descriptor base address
|
||||
jc init_failed
|
||||
mov cx,0FFFFh
|
||||
mov dx,0FFFFh
|
||||
mov ax,8 ; set segment limit to 4 GB
|
||||
int 31h
|
||||
jc init_failed
|
||||
mov bx,di
|
||||
int 31h
|
||||
jc init_failed
|
||||
mov ax,ds
|
||||
mov ds,di
|
||||
mov [psp_selector],es
|
||||
mov [environment_selector],ax
|
||||
cli
|
||||
mov ss,di
|
||||
mov esp,stack_top
|
||||
sti
|
||||
mov es,di
|
||||
xor eax,eax
|
||||
mov [memory_handles_count],eax
|
||||
push si
|
||||
push start
|
||||
retf
|
||||
|
||||
mode_switch dd ?
|
136
toolchain/fasmw17332/TOOLS/DOS/PREPSRC.ASM
Normal file
136
toolchain/fasmw17332/TOOLS/DOS/PREPSRC.ASM
Normal file
@ -0,0 +1,136 @@
|
||||
|
||||
format MZ
|
||||
heap 0
|
||||
stack 8000h
|
||||
entry loader:init
|
||||
|
||||
include 'loader.inc'
|
||||
|
||||
segment main use32
|
||||
|
||||
start:
|
||||
|
||||
call get_params
|
||||
jnc make_dump
|
||||
|
||||
mov esi,_usage
|
||||
call display_string
|
||||
mov ax,4C02h
|
||||
int 21h
|
||||
|
||||
make_dump:
|
||||
call preprocessed_source
|
||||
mov ax,4C00h
|
||||
int 21h
|
||||
|
||||
error:
|
||||
mov esi,_error_prefix
|
||||
call display_string
|
||||
pop esi
|
||||
call display_string
|
||||
mov esi,_error_suffix
|
||||
call display_string
|
||||
mov ax,4C00h
|
||||
int 21h
|
||||
|
||||
get_params:
|
||||
push ds
|
||||
mov ds,[psp_selector]
|
||||
mov esi,81h
|
||||
mov edi,params
|
||||
find_param:
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je find_param
|
||||
cmp al,0Dh
|
||||
je all_params
|
||||
or al,al
|
||||
jz all_params
|
||||
cmp [es:input_file],0
|
||||
jne get_output_file
|
||||
mov [es:input_file],edi
|
||||
jmp process_param
|
||||
get_output_file:
|
||||
cmp [es:output_file],0
|
||||
jne bad_params
|
||||
mov [es:output_file],edi
|
||||
process_param:
|
||||
cmp al,22h
|
||||
je string_param
|
||||
copy_param:
|
||||
stosb
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je param_end
|
||||
cmp al,0Dh
|
||||
je param_end
|
||||
or al,al
|
||||
jz param_end
|
||||
jmp copy_param
|
||||
string_param:
|
||||
lodsb
|
||||
cmp al,22h
|
||||
je string_param_end
|
||||
cmp al,0Dh
|
||||
je param_end
|
||||
or al,al
|
||||
jz param_end
|
||||
stosb
|
||||
jmp string_param
|
||||
bad_params_value:
|
||||
stc
|
||||
ret
|
||||
param_end:
|
||||
dec esi
|
||||
string_param_end:
|
||||
xor al,al
|
||||
stosb
|
||||
jmp find_param
|
||||
all_params:
|
||||
xor al,al
|
||||
stosb
|
||||
pop ds
|
||||
cmp [input_file],0
|
||||
je bad_params
|
||||
cmp [output_file],0
|
||||
je bad_params
|
||||
clc
|
||||
ret
|
||||
bad_params:
|
||||
stc
|
||||
ret
|
||||
|
||||
include 'system.inc'
|
||||
|
||||
include '..\prepsrc.inc'
|
||||
|
||||
_usage db 'preprocessed source dumper for flat assembler',0Dh,0Ah
|
||||
db 'usage: prepsrc <input> <output>',0Dh,0Ah
|
||||
db 0
|
||||
_error_prefix db 'error: ',0
|
||||
_error_suffix db '.',0Dh,0Ah,0
|
||||
|
||||
input_file dd 0
|
||||
output_file dd 0
|
||||
|
||||
psp_selector dw ?
|
||||
environment_selector dw ?
|
||||
|
||||
memory_handles_count dd ?
|
||||
memory_handles rd 400h
|
||||
|
||||
params rb 1000h
|
||||
|
||||
segment buffer_segment
|
||||
|
||||
buffer = (buffer_segment-main) shl 4
|
||||
|
||||
db 1000h dup ?
|
||||
|
||||
segment stack_segment
|
||||
|
||||
stack_bottom = (stack_segment-main) shl 4
|
||||
|
||||
db 4000h dup ?
|
||||
|
||||
stack_top = stack_bottom + $
|
140
toolchain/fasmw17332/TOOLS/DOS/SYMBOLS.ASM
Normal file
140
toolchain/fasmw17332/TOOLS/DOS/SYMBOLS.ASM
Normal file
@ -0,0 +1,140 @@
|
||||
|
||||
format MZ
|
||||
heap 0
|
||||
stack 8000h
|
||||
entry loader:init
|
||||
|
||||
include 'loader.inc'
|
||||
|
||||
segment main use32
|
||||
|
||||
start:
|
||||
|
||||
call get_params
|
||||
jnc make_dump
|
||||
|
||||
mov esi,_usage
|
||||
call display_string
|
||||
mov ax,4C02h
|
||||
int 21h
|
||||
|
||||
make_dump:
|
||||
call symbols
|
||||
mov ax,4C00h
|
||||
int 21h
|
||||
|
||||
error:
|
||||
mov esi,_error_prefix
|
||||
call display_string
|
||||
pop esi
|
||||
call display_string
|
||||
mov esi,_error_suffix
|
||||
call display_string
|
||||
mov ax,4C00h
|
||||
int 21h
|
||||
|
||||
get_params:
|
||||
push ds
|
||||
mov ds,[psp_selector]
|
||||
mov esi,81h
|
||||
mov edi,params
|
||||
find_param:
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je find_param
|
||||
cmp al,0Dh
|
||||
je all_params
|
||||
or al,al
|
||||
jz all_params
|
||||
cmp [es:input_file],0
|
||||
jne get_output_file
|
||||
mov [es:input_file],edi
|
||||
jmp process_param
|
||||
get_output_file:
|
||||
cmp [es:output_file],0
|
||||
jne bad_params
|
||||
mov [es:output_file],edi
|
||||
process_param:
|
||||
cmp al,22h
|
||||
je string_param
|
||||
copy_param:
|
||||
stosb
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je param_end
|
||||
cmp al,0Dh
|
||||
je param_end
|
||||
or al,al
|
||||
jz param_end
|
||||
jmp copy_param
|
||||
string_param:
|
||||
lodsb
|
||||
cmp al,22h
|
||||
je string_param_end
|
||||
cmp al,0Dh
|
||||
je param_end
|
||||
or al,al
|
||||
jz param_end
|
||||
stosb
|
||||
jmp string_param
|
||||
bad_params_value:
|
||||
stc
|
||||
ret
|
||||
param_end:
|
||||
dec esi
|
||||
string_param_end:
|
||||
xor al,al
|
||||
stosb
|
||||
jmp find_param
|
||||
all_params:
|
||||
xor al,al
|
||||
stosb
|
||||
pop ds
|
||||
cmp [input_file],0
|
||||
je bad_params
|
||||
cmp [output_file],0
|
||||
je bad_params
|
||||
clc
|
||||
ret
|
||||
bad_params:
|
||||
stc
|
||||
ret
|
||||
|
||||
include 'system.inc'
|
||||
|
||||
include '..\symbols.inc'
|
||||
|
||||
_usage db 'symbols dumper for flat assembler',0Dh,0Ah
|
||||
db 'usage: symbols <input> <output>',0Dh,0Ah
|
||||
db 0
|
||||
_error_prefix db 'error: ',0
|
||||
_error_suffix db '.',0Dh,0Ah,0
|
||||
|
||||
input_file dd 0
|
||||
output_file dd 0
|
||||
|
||||
input dd ?
|
||||
output_buffer dd ?
|
||||
output_handle dd ?
|
||||
|
||||
psp_selector dw ?
|
||||
environment_selector dw ?
|
||||
|
||||
memory_handles_count dd ?
|
||||
memory_handles rd 400h
|
||||
|
||||
params rb 1000h
|
||||
|
||||
segment buffer_segment
|
||||
|
||||
buffer = (buffer_segment-main) shl 4
|
||||
|
||||
db 1000h dup ?
|
||||
|
||||
segment stack_segment
|
||||
|
||||
stack_bottom = (stack_segment-main) shl 4
|
||||
|
||||
db 4000h dup ?
|
||||
|
||||
stack_top = stack_bottom + $
|
239
toolchain/fasmw17332/TOOLS/DOS/SYSTEM.INC
Normal file
239
toolchain/fasmw17332/TOOLS/DOS/SYSTEM.INC
Normal file
@ -0,0 +1,239 @@
|
||||
|
||||
display_string:
|
||||
lods byte [esi]
|
||||
or al,al
|
||||
jz string_end
|
||||
mov dl,al
|
||||
mov ah,2
|
||||
int 21h
|
||||
jmp display_string
|
||||
string_end:
|
||||
ret
|
||||
alloc:
|
||||
push ebx esi edi
|
||||
mov cx,ax
|
||||
shr eax,16
|
||||
mov bx,ax
|
||||
mov ax,501h
|
||||
int 31h
|
||||
jc dpmi_allocation_failed
|
||||
mov ax,bx
|
||||
shl eax,16
|
||||
mov ax,cx
|
||||
mov edx,main
|
||||
shl edx,4
|
||||
sub eax,edx
|
||||
mov bx,si
|
||||
shl ebx,16
|
||||
mov bx,di
|
||||
mov ecx,[memory_handles_count]
|
||||
inc [memory_handles_count]
|
||||
shl ecx,3
|
||||
add ecx,memory_handles
|
||||
mov [ecx],eax
|
||||
mov [ecx+4],ebx
|
||||
pop edi esi ebx
|
||||
clc
|
||||
ret
|
||||
dpmi_allocation_failed:
|
||||
pop edi esi ebx
|
||||
stc
|
||||
ret
|
||||
free:
|
||||
push ebx esi edi
|
||||
mov esi,memory_handles
|
||||
mov ecx,[memory_handles_count]
|
||||
find_memory_handle:
|
||||
cmp eax,[esi]
|
||||
je memory_handle_found
|
||||
add esi,8
|
||||
loop find_memory_handle
|
||||
pop edi esi
|
||||
ret
|
||||
memory_handle_found:
|
||||
mov ebx,[esi+4]
|
||||
dec [memory_handles_count]
|
||||
dec ecx
|
||||
jz free_memory
|
||||
remove_memory_handle:
|
||||
mov edx,[esi+8]
|
||||
mov edi,[esi+8+4]
|
||||
mov [esi],edx
|
||||
mov [esi+4],edi
|
||||
add esi,8
|
||||
loop remove_memory_handle
|
||||
free_memory:
|
||||
mov esi,ebx
|
||||
shr esi,16
|
||||
mov di,bx
|
||||
mov ax,502h
|
||||
int 31h
|
||||
pop edi esi ebx
|
||||
ret
|
||||
open:
|
||||
push esi edi ebp
|
||||
call adapt_path
|
||||
mov ax,716Ch
|
||||
mov bx,100000b
|
||||
mov dx,1
|
||||
xor cx,cx
|
||||
xor si,si
|
||||
call dos_int
|
||||
jnc open_done
|
||||
cmp ax,7100h
|
||||
je old_open
|
||||
stc
|
||||
jmp open_done
|
||||
old_open:
|
||||
mov ax,3D00h
|
||||
xor dx,dx
|
||||
call dos_int
|
||||
open_done:
|
||||
mov bx,ax
|
||||
pop ebp edi esi
|
||||
ret
|
||||
adapt_path:
|
||||
mov esi,edx
|
||||
mov edi,buffer
|
||||
copy_path:
|
||||
lodsb
|
||||
cmp al,'/'
|
||||
jne path_char_ok
|
||||
mov al,'\'
|
||||
path_char_ok:
|
||||
stosb
|
||||
or al,al
|
||||
jnz copy_path
|
||||
ret
|
||||
dos_int:
|
||||
push 0 0 0
|
||||
pushw buffer_segment buffer_segment
|
||||
stc
|
||||
pushfw
|
||||
push eax
|
||||
push ecx
|
||||
push edx
|
||||
push ebx
|
||||
push 0
|
||||
push ebp
|
||||
push esi
|
||||
push edi
|
||||
mov ax,300h
|
||||
mov bx,21h
|
||||
xor cx,cx
|
||||
mov edi,esp
|
||||
push es ss
|
||||
pop es
|
||||
int 31h
|
||||
pop es
|
||||
mov edi,[esp]
|
||||
mov esi,[esp+4]
|
||||
mov ebp,[esp+8]
|
||||
mov ebx,[esp+10h]
|
||||
mov edx,[esp+14h]
|
||||
mov ecx,[esp+18h]
|
||||
mov ah,[esp+20h]
|
||||
add esp,32h
|
||||
sahf
|
||||
mov eax,[esp-32h+1Ch]
|
||||
ret
|
||||
create:
|
||||
push esi edi ebp
|
||||
call adapt_path
|
||||
mov ax,716Ch
|
||||
mov bx,100001b
|
||||
mov dx,10010b
|
||||
xor cx,cx
|
||||
xor si,si
|
||||
xor di,di
|
||||
call dos_int
|
||||
jnc create_done
|
||||
cmp ax,7100h
|
||||
je old_create
|
||||
stc
|
||||
jmp create_done
|
||||
old_create:
|
||||
mov ah,3Ch
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
call dos_int
|
||||
create_done:
|
||||
mov bx,ax
|
||||
pop ebp edi esi
|
||||
ret
|
||||
write:
|
||||
push edx esi edi ebp
|
||||
mov ebp,ecx
|
||||
mov esi,edx
|
||||
write_loop:
|
||||
mov ecx,1000h
|
||||
sub ebp,1000h
|
||||
jnc do_write
|
||||
add ebp,1000h
|
||||
mov ecx,ebp
|
||||
xor ebp,ebp
|
||||
do_write:
|
||||
push ecx
|
||||
mov edi,buffer
|
||||
shr ecx,2
|
||||
rep movsd
|
||||
mov ecx,[esp]
|
||||
and ecx,11b
|
||||
rep movsb
|
||||
pop ecx
|
||||
mov ah,40h
|
||||
xor dx,dx
|
||||
call dos_int
|
||||
or ebp,ebp
|
||||
jnz write_loop
|
||||
pop ebp edi esi edx
|
||||
ret
|
||||
read:
|
||||
push edx esi edi ebp
|
||||
mov ebp,ecx
|
||||
mov edi,edx
|
||||
read_loop:
|
||||
mov ecx,1000h
|
||||
sub ebp,1000h
|
||||
jnc do_read
|
||||
add ebp,1000h
|
||||
mov ecx,ebp
|
||||
xor ebp,ebp
|
||||
do_read:
|
||||
push ecx
|
||||
mov ah,3Fh
|
||||
xor dx,dx
|
||||
call dos_int
|
||||
cmp ax,cx
|
||||
jne eof
|
||||
mov esi,buffer
|
||||
mov ecx,[esp]
|
||||
shr ecx,2
|
||||
rep movsd
|
||||
pop ecx
|
||||
and ecx,11b
|
||||
rep movsb
|
||||
or ebp,ebp
|
||||
jnz read_loop
|
||||
read_done:
|
||||
pop ebp edi esi edx
|
||||
ret
|
||||
eof:
|
||||
pop ecx
|
||||
stc
|
||||
jmp read_done
|
||||
close:
|
||||
mov ah,3Eh
|
||||
int 21h
|
||||
ret
|
||||
lseek:
|
||||
mov ah,42h
|
||||
mov ecx,edx
|
||||
shr ecx,16
|
||||
int 21h
|
||||
pushf
|
||||
shl edx,16
|
||||
popf
|
||||
mov dx,ax
|
||||
mov eax,edx
|
||||
ret
|
429
toolchain/fasmw17332/TOOLS/FAS.TXT
Normal file
429
toolchain/fasmw17332/TOOLS/FAS.TXT
Normal file
@ -0,0 +1,429 @@
|
||||
|
||||
flat assembler
|
||||
Symbolic information file format
|
||||
|
||||
|
||||
Table 1 Header
|
||||
/-------------------------------------------------------------------------\
|
||||
| Offset | Size | Description |
|
||||
|========|=========|======================================================|
|
||||
| +0 | dword | Signature 1A736166h (little-endian). |
|
||||
|--------|---------|------------------------------------------------------|
|
||||
| +4 | byte | Major version of flat assembler. |
|
||||
|--------|---------|------------------------------------------------------|
|
||||
| +5 | byte | Minor version of flat assembler. |
|
||||
|--------|---------|------------------------------------------------------|
|
||||
| +6 | word | Length of header. |
|
||||
|--------|---------|------------------------------------------------------|
|
||||
| +8 | dword | Offset of input file name in the strings table. |
|
||||
|--------|---------|------------------------------------------------------|
|
||||
| +12 | dword | Offset of output file name in the strings table. |
|
||||
|--------|---------|------------------------------------------------------|
|
||||
| +16 | dword | Offset of strings table. |
|
||||
|--------|---------|------------------------------------------------------|
|
||||
| +20 | dword | Length of strings table. |
|
||||
|--------|---------|------------------------------------------------------|
|
||||
| +24 | dword | Offset of symbols table. |
|
||||
|--------|---------|------------------------------------------------------|
|
||||
| +28 | dword | Length of symbols table. |
|
||||
|--------|---------|------------------------------------------------------|
|
||||
| +32 | dword | Offset of preprocessed source. |
|
||||
|--------|---------|------------------------------------------------------|
|
||||
| +36 | dword | Length of preprocessed source. |
|
||||
|--------|---------|------------------------------------------------------|
|
||||
| +40 | dword | Offset of assembly dump. |
|
||||
|--------|---------|------------------------------------------------------|
|
||||
| +44 | dword | Length of assembly dump. |
|
||||
|--------|---------|------------------------------------------------------|
|
||||
| +48 | dword | Offset of section names table. |
|
||||
|--------|---------|------------------------------------------------------|
|
||||
| +52 | dword | Length of section names table. |
|
||||
|--------|---------|------------------------------------------------------|
|
||||
| +56 | dword | Offset of symbol references dump. |
|
||||
|--------|---------|------------------------------------------------------|
|
||||
| +60 | dword | Length of symbol references dump. |
|
||||
\-------------------------------------------------------------------------/
|
||||
|
||||
Notes:
|
||||
|
||||
If header is shorter than 64 bytes, it comes from a version that does not
|
||||
support dumping some of the structures. It should then be interpreted
|
||||
that the data for missing structures could not be provided, not that the
|
||||
size of that data is zero.
|
||||
|
||||
Offsets given in header generally mean positions in the file, however
|
||||
input and output file names are specified by offsets in the strings table,
|
||||
so you have to add their offset to the offset of strings table to obtain
|
||||
the positions of those strings in the file.
|
||||
|
||||
The strings table contains just a sequence of ASCIIZ strings, which may
|
||||
be referred to by other parts of the file. It contains the names of
|
||||
main input file, the output file, and the names of the sections and
|
||||
external symbols if there were any.
|
||||
|
||||
The symbols table is an array of 32-byte structures, each one in format
|
||||
specified by table 2.
|
||||
|
||||
The preprocessed source is a sequence of preprocessed lines, each one
|
||||
in format as defined in table 3.
|
||||
|
||||
The assembly dump contains an array of 28-byte structures, each one in
|
||||
format specified by table 4, and at the end of this array an additional
|
||||
double word containing the offset in output file at which the assembly
|
||||
was ended.
|
||||
|
||||
It is possible that file does not contain assembly dump at all - this
|
||||
happens when some error occured and only the preprocessed source was
|
||||
dumped. If error occured during the preprocessing, only the source up to
|
||||
the point of error is provided. In such case (and only then) the field
|
||||
at offset 44 contains zero.
|
||||
|
||||
The section names table exists only when the output format was an object
|
||||
file (ELF or COFF), and it is an array of 4-byte entries, each being an
|
||||
offset of the name of the section in the strings table.
|
||||
The index of section in this table is the same, as the index of section
|
||||
in the generated object file.
|
||||
|
||||
The symbol references dump contains an array of 8-byte structures, each
|
||||
one describes an event of some symbol being used. The first double word
|
||||
of such structure contains an offset of symbol in the symbols table,
|
||||
and the second double word is an offset of structure in assembly dump,
|
||||
which specifies at what moment the symbol was referenced.
|
||||
|
||||
|
||||
Table 2 Symbol structure
|
||||
/-------------------------------------------------------------------------\
|
||||
| Offset | Size | Description |
|
||||
|========|=======|========================================================|
|
||||
| +0 | qword | Value of symbol. |
|
||||
|--------|-------|--------------------------------------------------------|
|
||||
| +8 | word | Flags (table 2.1). |
|
||||
|--------|-------|--------------------------------------------------------|
|
||||
| +10 | byte | Size of data labelled by this symbol (zero means plain |
|
||||
| | | label without size attached). |
|
||||
|--------|-------|--------------------------------------------------------|
|
||||
| +11 | byte | Type of value (table 2.2). Any value other than zero |
|
||||
| | | means some kind of relocatable symbol. |
|
||||
|--------|-------|--------------------------------------------------------|
|
||||
| +12 | dword | Extended SIB, the first two bytes are register codes |
|
||||
| | | and the second two bytes are corresponding scales. |
|
||||
|--------|-------|--------------------------------------------------------|
|
||||
| +16 | word | Number of pass in which symbol was defined last time. |
|
||||
|--------|-------|--------------------------------------------------------|
|
||||
| +18 | word | Number of pass in which symbol was used last time. |
|
||||
|--------|-------|--------------------------------------------------------|
|
||||
| +20 | dword | If the symbol is relocatable, this field contains |
|
||||
| | | information about section or external symbol, to which |
|
||||
| | | it is relative - otherwise this field has no meaning. |
|
||||
| | | When the highest bit is cleared, the symbol is |
|
||||
| | | relative to a section, and the bits 0-30 contain |
|
||||
| | | the index (starting from 1) in the table of sections. |
|
||||
| | | When the highest bit is set, the symbol is relative to |
|
||||
| | | an external symbol, and the bits 0-30 contain the |
|
||||
| | | the offset of the name of this symbol in the strings |
|
||||
| | | table. |
|
||||
|--------|-------|--------------------------------------------------------|
|
||||
| +24 | dword | If the highest bit is cleared, the bits 0-30 contain |
|
||||
| | | the offset of symbol name in the preprocessed source. |
|
||||
| | | This name is a pascal-style string (byte length |
|
||||
| | | followed by string data). |
|
||||
| | | Zero in this field means an anonymous symbol. |
|
||||
| | | If the highest bit is set, the bits 0-30 contain the |
|
||||
| | | offset of the symbol name in the strings table, and |
|
||||
| | | this name is a zero-ended string in this case (as are |
|
||||
| | | all the strings there). |
|
||||
|--------|-------|--------------------------------------------------------|
|
||||
| +28 | dword | Offset in the preprocessed source of line that defined |
|
||||
| | | this symbol (see table 3). |
|
||||
\-------------------------------------------------------------------------/
|
||||
|
||||
|
||||
Table 2.1 Symbol flags
|
||||
/-----------------------------------------------------------------\
|
||||
| Bit | Value | Description |
|
||||
|=====|=======|===================================================|
|
||||
| 0 | 1 | Symbol was defined. |
|
||||
|-----|-------|---------------------------------------------------|
|
||||
| 1 | 2 | Symbol is an assembly-time variable. |
|
||||
|-----|-------|---------------------------------------------------|
|
||||
| 2 | 4 | Symbol cannot be forward-referenced. |
|
||||
|-----|-------|---------------------------------------------------|
|
||||
| 3 | 8 | Symbol was used. |
|
||||
|-----|-------|---------------------------------------------------|
|
||||
| 4 | 10h | The prediction was needed when checking |
|
||||
| | | whether the symbol was used. |
|
||||
|-----|-------|---------------------------------------------------|
|
||||
| 5 | 20h | Result of last predicted check for being used. |
|
||||
|-----|-------|---------------------------------------------------|
|
||||
| 6 | 40h | The prediction was needed when checking |
|
||||
| | | whether the symbol was defined. |
|
||||
|-----|-------|---------------------------------------------------|
|
||||
| 7 | 80h | Result of last predicted check for being defined. |
|
||||
|-----|-------|---------------------------------------------------|
|
||||
| 8 | 100h | The optimization adjustment is applied to |
|
||||
| | | the value of this symbol. |
|
||||
|-----|-------|---------------------------------------------------|
|
||||
| 9 | 200h | The value of symbol is negative number encoded |
|
||||
| | | as two's complement. |
|
||||
|-----|-------|---------------------------------------------------|
|
||||
| 10 | 400h | Symbol is a special marker and has no value. |
|
||||
\-----------------------------------------------------------------/
|
||||
|
||||
Notes:
|
||||
|
||||
Some of those flags are listed here just for completness, as they
|
||||
have little use outside of the flat assembler. However the bit 0
|
||||
is important, because the symbols table contains all the labels
|
||||
that occured in source, even if some of them were in the
|
||||
conditional blocks that did not get assembled.
|
||||
|
||||
|
||||
Table 2.2 Symbol value types
|
||||
/-------------------------------------------------------------------\
|
||||
| Value | Description |
|
||||
|=======|===========================================================|
|
||||
| 0 | Absolute value. |
|
||||
|-------|-----------------------------------------------------------|
|
||||
| 1 | Relocatable segment address (only with MZ output). |
|
||||
|-------|-----------------------------------------------------------|
|
||||
| 2 | Relocatable 32-bit address. |
|
||||
|-------|-----------------------------------------------------------|
|
||||
| 3 | Relocatable relative 32-bit address (value valid only for |
|
||||
| | symbol used in the same place where it was calculated, |
|
||||
| | it should not occur in the symbol structure). |
|
||||
|-------|-----------------------------------------------------------|
|
||||
| 4 | Relocatable 64-bit address. |
|
||||
|-------|-----------------------------------------------------------|
|
||||
| 5 | [ELF only] GOT-relative 32-bit address. |
|
||||
|-------|-----------------------------------------------------------|
|
||||
| 6 | [ELF only] 32-bit address of PLT entry. |
|
||||
|-------|-----------------------------------------------------------|
|
||||
| 7 | [ELF only] Relative 32-bit address of PLT entry (value |
|
||||
| | valid only for symbol used in the same place where it |
|
||||
| | was calculated, it should not occur in the symbol |
|
||||
| | structure). |
|
||||
\-------------------------------------------------------------------/
|
||||
|
||||
Notes:
|
||||
|
||||
The types 3 and 7 should never be encountered in the symbols dump,
|
||||
they are only used internally by the flat assembler.
|
||||
|
||||
If type value is a negative number, it is an opposite of a value
|
||||
from this table and it means that the symbol of a given type has
|
||||
been negated.
|
||||
|
||||
|
||||
Table 2.3 Register codes for extended SIB
|
||||
/------------------\
|
||||
| Value | Register |
|
||||
|=======|==========|
|
||||
| 23h | BX |
|
||||
|-------|----------|
|
||||
| 25h | BP |
|
||||
|-------|----------|
|
||||
| 26h | SI |
|
||||
|-------|----------|
|
||||
| 27h | DI |
|
||||
|-------|----------|
|
||||
| 40h | EAX |
|
||||
|-------|----------|
|
||||
| 41h | ECX |
|
||||
|-------|----------|
|
||||
| 42h | EDX |
|
||||
|-------|----------|
|
||||
| 43h | EBX |
|
||||
|-------|----------|
|
||||
| 44h | ESP |
|
||||
|-------|----------|
|
||||
| 45h | EBP |
|
||||
|-------|----------|
|
||||
| 46h | ESI |
|
||||
|-------|----------|
|
||||
| 47h | EDI |
|
||||
|-------|----------|
|
||||
| 48h | R8D |
|
||||
|-------|----------|
|
||||
| 49h | R9D |
|
||||
|-------|----------|
|
||||
| 4Ah | R10D |
|
||||
|-------|----------|
|
||||
| 4Bh | R11D |
|
||||
|-------|----------|
|
||||
| 4Ch | R12D |
|
||||
|-------|----------|
|
||||
| 4Dh | R13D |
|
||||
|-------|----------|
|
||||
| 4Eh | R14D |
|
||||
|-------|----------|
|
||||
| 4Fh | R15D |
|
||||
|-------|----------|
|
||||
| 80h | RAX |
|
||||
|-------|----------|
|
||||
| 81h | RCX |
|
||||
|-------|----------|
|
||||
| 82h | RDX |
|
||||
|-------|----------|
|
||||
| 83h | RBX |
|
||||
|-------|----------|
|
||||
| 84h | RSP |
|
||||
|-------|----------|
|
||||
| 85h | RBP |
|
||||
|-------|----------|
|
||||
| 86h | RSI |
|
||||
|-------|----------|
|
||||
| 87h | RDI |
|
||||
|-------|----------|
|
||||
| 88h | R8 |
|
||||
|-------|----------|
|
||||
| 89h | R9 |
|
||||
|-------|----------|
|
||||
| 8Ah | R10 |
|
||||
|-------|----------|
|
||||
| 8Bh | R11 |
|
||||
|-------|----------|
|
||||
| 8Ch | R12 |
|
||||
|-------|----------|
|
||||
| 8Dh | R13 |
|
||||
|-------|----------|
|
||||
| 8Eh | R14 |
|
||||
|-------|----------|
|
||||
| 8Fh | R15 |
|
||||
|-------|----------|
|
||||
| 94h | EIP |
|
||||
|-------|----------|
|
||||
| 98h | RIP |
|
||||
\------------------/
|
||||
|
||||
|
||||
Table 3 Preprocessed line
|
||||
/--------------------------------------------------------------------------\
|
||||
| Offset | Size | Value |
|
||||
|========|=================================================================|
|
||||
| +0 | dword | When the line was loaded from source, this field |
|
||||
| | | contains either zero (if it is the line from the main |
|
||||
| | | input file), or an offset inside the preprocessed |
|
||||
| | | source to the name of file, from which this line was |
|
||||
| | | loaded (the name of file is zero-ended string). |
|
||||
| | | When the line was generated by macroinstruction, this |
|
||||
| | | field contains offset inside the preprocessed source to |
|
||||
| | | the pascal-style string specifying the name of |
|
||||
| | | macroinstruction, which generated this line. |
|
||||
|--------|-------|---------------------------------------------------------|
|
||||
| +4 | dword | Bits 0-30 contain the number of this line. |
|
||||
| | | If the highest bit is zeroed, this line was loaded from |
|
||||
| | | source. |
|
||||
| | | If the highest bit is set, this line was generated by |
|
||||
| | | macroinstruction. |
|
||||
|--------|-------|---------------------------------------------------------|
|
||||
| +8 | dword | If the line was loaded from source, this field contains |
|
||||
| | | the position of the line inside the source file, from |
|
||||
| | | which it was loaded. |
|
||||
| | | If line was generated by macroinstruction, this field |
|
||||
| | | contains the offset of preprocessed line, which invoked |
|
||||
| | | the macroinstruction. |
|
||||
| | | If line was generated by instantaneous macro, this |
|
||||
| | | field is equal to the next one. |
|
||||
|--------|-------|---------------------------------------------------------|
|
||||
| +12 | dword | If the line was generated by macroinstruction, this |
|
||||
| | | field contains offset of the preprocessed line inside |
|
||||
| | | the definition of macro, from which this one was |
|
||||
| | | generated. |
|
||||
|--------|-------|---------------------------------------------------------|
|
||||
| +16 | ? | The tokenized contents of line. |
|
||||
\--------------------------------------------------------------------------/
|
||||
|
||||
Notes:
|
||||
|
||||
To determine, whether this is the line loaded from source, or generated by
|
||||
macroinstruction, you need to check the highest bit of the second double
|
||||
word.
|
||||
|
||||
The contents of line is no longer a text, which it was in source file,
|
||||
but a sequence of tokens, ended with a zero byte.
|
||||
Any chain of characters that aren't special ones, separated from other
|
||||
similar chains with spaces or some other special characters, is converted
|
||||
into symbol token. The first byte of this element has the value of 1Ah,
|
||||
the second byte is the count of characters, followed by this amount of
|
||||
bytes, which build the symbol.
|
||||
Some characters have a special meaning, and cannot occur inside the
|
||||
symbol, they split the symbols and are converted into separate tokens.
|
||||
For example, if source contains this line of text:
|
||||
|
||||
mov ax,4
|
||||
|
||||
preprocessor converts it into the chain of bytes, shown here with their
|
||||
hexadecimal values (characters corresponding to some of those values are
|
||||
placed below the hexadecimal codes):
|
||||
|
||||
1A 03 6D 6F 76 1A 02 61 78 2C 1A 01 34 00
|
||||
m o v a x , 4
|
||||
|
||||
The third type of token that can be found in preprocessed line is the
|
||||
quoted text. This element is created from chain of any bytes other than
|
||||
line breaks that are placed between the single or double quotes in the
|
||||
original text. First byte of such element is always 22h, it is followed
|
||||
by double word which specifies the number of bytes that follow, and the
|
||||
value of quoted text comes next. For example, this line from source:
|
||||
|
||||
mov eax,'ABCD'
|
||||
|
||||
is converted into (the notation used is the same as in previous sample):
|
||||
|
||||
1A 03 6D 6F 76 1A 03 65 61 78 2C 22 04 00 00 00 41 42 43 44 00
|
||||
m o v e a x , A B C D
|
||||
|
||||
This data defines two symbols followed by symbol character, quoted text
|
||||
and zero byte that marks end of line.
|
||||
There is also a special case of symbol token with first byte having the
|
||||
value 3Bh instead of 1Ah, such symbol means that all the line elements
|
||||
that follow, including this one, have already been interpreted by
|
||||
preprocessor and are ignored by assembler.
|
||||
|
||||
|
||||
Table 4 Row of the assembly dump
|
||||
/-------------------------------------------------------------------------\
|
||||
| Offset | Size | Description |
|
||||
|========|=======|========================================================|
|
||||
| +0 | dword | Offset in output file. |
|
||||
|--------|-------|--------------------------------------------------------|
|
||||
| +4 | dword | Offset of line in preprocessed source. |
|
||||
|--------|-------|--------------------------------------------------------|
|
||||
| +8 | qword | Value of $ address. |
|
||||
|--------|-------|--------------------------------------------------------|
|
||||
| +16 | dword | Extended SIB for the $ address, the first two bytes |
|
||||
| | | are register codes and the second two bytes are |
|
||||
| | | corresponding scales. |
|
||||
|--------|-------|--------------------------------------------------------|
|
||||
| +20 | dword | If the $ address is relocatable, this field contains |
|
||||
| | | information about section or external symbol, to which |
|
||||
| | | it is relative - otherwise this field is zero. |
|
||||
| | | When the highest bit is cleared, the address is |
|
||||
| | | relative to a section, and the bits 0-30 contain |
|
||||
| | | the index (starting from 1) in the table of sections. |
|
||||
| | | When the highest bit is set, the address is relative |
|
||||
| | | to an external symbol, and the bits 0-30 contain the |
|
||||
| | | the offset of the name of this symbol in the strings |
|
||||
| | | table. |
|
||||
|--------|-------|--------------------------------------------------------|
|
||||
| +24 | byte | Type of $ address value (as in table 2.2). |
|
||||
|--------|-------|--------------------------------------------------------|
|
||||
| +25 | byte | Type of code - possible values are 16, 32, and 64. |
|
||||
|--------|-------|--------------------------------------------------------|
|
||||
| +26 | byte | If the bit 0 is set, then at this point the assembly |
|
||||
| | | was taking place inside the virtual block, and the |
|
||||
| | | offset in output file has no meaning here. |
|
||||
| | | If the bit 1 is set, the line was assembled at the |
|
||||
| | | point, which was not included in the output file for |
|
||||
| | | some other reasons (like inside the reserved data at |
|
||||
| | | the end of section). |
|
||||
|--------|-------|--------------------------------------------------------|
|
||||
| +27 | byte | The higher bits of value of $ address. |
|
||||
\-------------------------------------------------------------------------/
|
||||
|
||||
|
||||
Notes:
|
||||
|
||||
Each row of the assembly dump informs, that the given line of preprocessed
|
||||
source was assembled at the specified address (defined by its type, value
|
||||
and the extended SIB) and at the specified position in output file.
|
23
toolchain/fasmw17332/TOOLS/LIBC/CCALL.INC
Normal file
23
toolchain/fasmw17332/TOOLS/LIBC/CCALL.INC
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
macro ccall proc,[arg]
|
||||
{ common
|
||||
push ebp
|
||||
mov ebp,esp
|
||||
local size
|
||||
size = 0
|
||||
if ~ arg eq
|
||||
forward
|
||||
size = size + 4
|
||||
common
|
||||
sub esp,size
|
||||
end if
|
||||
and esp,-16
|
||||
if ~ arg eq
|
||||
add esp,size
|
||||
reverse
|
||||
pushd arg
|
||||
common
|
||||
end if
|
||||
call proc
|
||||
leave }
|
||||
|
177
toolchain/fasmw17332/TOOLS/LIBC/LISTING.ASM
Normal file
177
toolchain/fasmw17332/TOOLS/LIBC/LISTING.ASM
Normal file
@ -0,0 +1,177 @@
|
||||
|
||||
format ELF
|
||||
public main
|
||||
|
||||
include 'ccall.inc'
|
||||
|
||||
section '.text' executable align 16
|
||||
|
||||
main:
|
||||
mov ecx,[esp+4]
|
||||
mov [argc],ecx
|
||||
mov ebx,[esp+8]
|
||||
mov [argv],ebx
|
||||
|
||||
mov [display_handle],1
|
||||
|
||||
call get_params
|
||||
jnc make_listing
|
||||
|
||||
mov esi,_usage
|
||||
call display_string
|
||||
ccall exit,2
|
||||
|
||||
make_listing:
|
||||
call listing
|
||||
ccall exit,0
|
||||
|
||||
error:
|
||||
mov [display_handle],2
|
||||
mov esi,_error_prefix
|
||||
call display_string
|
||||
pop esi
|
||||
call display_string
|
||||
mov esi,_error_suffix
|
||||
call display_string
|
||||
ccall exit,0
|
||||
|
||||
get_params:
|
||||
mov ecx,[argc]
|
||||
mov ebx,[argv]
|
||||
add ebx,4
|
||||
dec ecx
|
||||
jz bad_params
|
||||
get_param:
|
||||
mov esi,[ebx]
|
||||
mov al,[esi]
|
||||
cmp al,'-'
|
||||
je option_param
|
||||
cmp [input_file],0
|
||||
jne get_output_file
|
||||
mov [input_file],esi
|
||||
jmp next_param
|
||||
get_output_file:
|
||||
cmp [output_file],0
|
||||
jne bad_params
|
||||
mov [output_file],esi
|
||||
jmp next_param
|
||||
option_param:
|
||||
inc esi
|
||||
lodsb
|
||||
cmp al,'a'
|
||||
je addresses_option
|
||||
cmp al,'A'
|
||||
je addresses_option
|
||||
cmp al,'b'
|
||||
je bytes_per_line_option
|
||||
cmp al,'B'
|
||||
je bytes_per_line_option
|
||||
bad_params:
|
||||
stc
|
||||
ret
|
||||
addresses_option:
|
||||
cmp byte [esi],0
|
||||
jne bad_params
|
||||
mov [show_addresses],1
|
||||
jmp next_param
|
||||
bytes_per_line_option:
|
||||
cmp byte [esi],0
|
||||
jne get_bytes_per_line_setting
|
||||
dec ecx
|
||||
jz bad_params
|
||||
add ebx,4
|
||||
mov esi,[ebx]
|
||||
get_bytes_per_line_setting:
|
||||
call get_option_value
|
||||
or edx,edx
|
||||
jz bad_params
|
||||
cmp edx,1000
|
||||
ja bad_params
|
||||
mov [code_bytes_per_line],edx
|
||||
next_param:
|
||||
add ebx,4
|
||||
dec ecx
|
||||
jnz get_param
|
||||
cmp [input_file],0
|
||||
je bad_params
|
||||
cmp [output_file],0
|
||||
je bad_params
|
||||
clc
|
||||
ret
|
||||
get_option_value:
|
||||
xor eax,eax
|
||||
mov edx,eax
|
||||
get_option_digit:
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je option_value_ok
|
||||
cmp al,0Dh
|
||||
je option_value_ok
|
||||
or al,al
|
||||
jz option_value_ok
|
||||
sub al,30h
|
||||
jc invalid_option_value
|
||||
cmp al,9
|
||||
ja invalid_option_value
|
||||
imul edx,10
|
||||
jo invalid_option_value
|
||||
add edx,eax
|
||||
jc invalid_option_value
|
||||
jmp get_option_digit
|
||||
option_value_ok:
|
||||
dec esi
|
||||
clc
|
||||
ret
|
||||
invalid_option_value:
|
||||
stc
|
||||
ret
|
||||
|
||||
include 'system.inc'
|
||||
|
||||
include '..\listing.inc'
|
||||
|
||||
section '.data' writeable align 4
|
||||
|
||||
input_file dd 0
|
||||
output_file dd 0
|
||||
code_bytes_per_line dd 16
|
||||
show_addresses db 0
|
||||
|
||||
line_break db 0Dh,0Ah
|
||||
|
||||
_usage db 'listing generator for flat assembler',0Dh,0Ah
|
||||
db 'usage: listing <input> <output>',0Dh,0Ah
|
||||
db 'optional settings:',0Dh,0Ah
|
||||
db ' -a show target addresses for assembled code',0Dh,0Ah
|
||||
db ' -b <number> set the amount of bytes listed per line',0Dh,0Ah
|
||||
db 0
|
||||
_error_prefix db 'error: ',0
|
||||
_error_suffix db '.',0Dh,0Ah,0
|
||||
|
||||
section '.bss' writeable align 4
|
||||
|
||||
argc dd ?
|
||||
argv dd ?
|
||||
|
||||
input dd ?
|
||||
assembled_code dd ?
|
||||
assembled_code_length dd ?
|
||||
code_end dd ?
|
||||
code_offset dd ?
|
||||
code_length dd ?
|
||||
output_handle dd ?
|
||||
output_buffer dd ?
|
||||
current_source_file dd ?
|
||||
current_source_line dd ?
|
||||
source dd ?
|
||||
source_length dd ?
|
||||
maximum_address_length dd ?
|
||||
address_start dd ?
|
||||
last_listed_address dd ?
|
||||
|
||||
display_handle dd ?
|
||||
character db ?
|
||||
|
||||
params rb 1000h
|
||||
characters rb 100h
|
||||
buffer rb 1000h
|
94
toolchain/fasmw17332/TOOLS/LIBC/PREPSRC.ASM
Normal file
94
toolchain/fasmw17332/TOOLS/LIBC/PREPSRC.ASM
Normal file
@ -0,0 +1,94 @@
|
||||
|
||||
format ELF
|
||||
public main
|
||||
|
||||
include 'ccall.inc'
|
||||
|
||||
section '.text' executable align 16
|
||||
|
||||
main:
|
||||
mov ecx,[esp+4]
|
||||
mov [argc],ecx
|
||||
mov ebx,[esp+8]
|
||||
mov [argv],ebx
|
||||
|
||||
mov [display_handle],1
|
||||
|
||||
call get_params
|
||||
jnc make_dump
|
||||
|
||||
mov esi,_usage
|
||||
call display_string
|
||||
ccall exit,2
|
||||
|
||||
make_dump:
|
||||
call preprocessed_source
|
||||
ccall exit,0
|
||||
|
||||
error:
|
||||
mov [display_handle],2
|
||||
mov esi,_error_prefix
|
||||
call display_string
|
||||
pop esi
|
||||
call display_string
|
||||
mov esi,_error_suffix
|
||||
call display_string
|
||||
ccall exit,0
|
||||
|
||||
get_params:
|
||||
mov ecx,[argc]
|
||||
mov ebx,[argv]
|
||||
add ebx,4
|
||||
dec ecx
|
||||
jz bad_params
|
||||
get_param:
|
||||
mov esi,[ebx]
|
||||
mov al,[esi]
|
||||
cmp [input_file],0
|
||||
jne get_output_file
|
||||
mov [input_file],esi
|
||||
jmp next_param
|
||||
get_output_file:
|
||||
cmp [output_file],0
|
||||
jne bad_params
|
||||
mov [output_file],esi
|
||||
jmp next_param
|
||||
bad_params:
|
||||
stc
|
||||
ret
|
||||
next_param:
|
||||
add ebx,4
|
||||
dec ecx
|
||||
jnz get_param
|
||||
cmp [input_file],0
|
||||
je bad_params
|
||||
cmp [output_file],0
|
||||
je bad_params
|
||||
clc
|
||||
ret
|
||||
|
||||
include 'system.inc'
|
||||
|
||||
include '..\prepsrc.inc'
|
||||
|
||||
section '.data' writeable align 4
|
||||
|
||||
input_file dd 0
|
||||
output_file dd 0
|
||||
|
||||
_usage db 'preprocessed source dumper for flat assembler',0Dh,0Ah
|
||||
db 'usage: prepsrc <input> <output>',0Dh,0Ah
|
||||
db 0
|
||||
_error_prefix db 'error: ',0
|
||||
_error_suffix db '.',0Dh,0Ah,0
|
||||
|
||||
section '.bss' writeable align 4
|
||||
|
||||
argc dd ?
|
||||
argv dd ?
|
||||
|
||||
display_handle dd ?
|
||||
character db ?
|
||||
|
||||
params rb 1000h
|
||||
buffer rb 1000h
|
98
toolchain/fasmw17332/TOOLS/LIBC/SYMBOLS.ASM
Normal file
98
toolchain/fasmw17332/TOOLS/LIBC/SYMBOLS.ASM
Normal file
@ -0,0 +1,98 @@
|
||||
|
||||
format ELF
|
||||
public main
|
||||
|
||||
include 'ccall.inc'
|
||||
|
||||
section '.text' executable align 16
|
||||
|
||||
main:
|
||||
mov ecx,[esp+4]
|
||||
mov [argc],ecx
|
||||
mov ebx,[esp+8]
|
||||
mov [argv],ebx
|
||||
|
||||
mov [display_handle],1
|
||||
|
||||
call get_params
|
||||
jnc make_dump
|
||||
|
||||
mov esi,_usage
|
||||
call display_string
|
||||
ccall exit,2
|
||||
|
||||
make_dump:
|
||||
call symbols
|
||||
ccall exit,0
|
||||
|
||||
error:
|
||||
mov [display_handle],2
|
||||
mov esi,_error_prefix
|
||||
call display_string
|
||||
pop esi
|
||||
call display_string
|
||||
mov esi,_error_suffix
|
||||
call display_string
|
||||
ccall exit,0
|
||||
|
||||
get_params:
|
||||
mov ecx,[argc]
|
||||
mov ebx,[argv]
|
||||
add ebx,4
|
||||
dec ecx
|
||||
jz bad_params
|
||||
get_param:
|
||||
mov esi,[ebx]
|
||||
mov al,[esi]
|
||||
cmp [input_file],0
|
||||
jne get_output_file
|
||||
mov [input_file],esi
|
||||
jmp next_param
|
||||
get_output_file:
|
||||
cmp [output_file],0
|
||||
jne bad_params
|
||||
mov [output_file],esi
|
||||
jmp next_param
|
||||
bad_params:
|
||||
stc
|
||||
ret
|
||||
next_param:
|
||||
add ebx,4
|
||||
dec ecx
|
||||
jnz get_param
|
||||
cmp [input_file],0
|
||||
je bad_params
|
||||
cmp [output_file],0
|
||||
je bad_params
|
||||
clc
|
||||
ret
|
||||
|
||||
include 'system.inc'
|
||||
|
||||
include '..\symbols.inc'
|
||||
|
||||
section '.data' writeable align 4
|
||||
|
||||
input_file dd 0
|
||||
output_file dd 0
|
||||
|
||||
_usage db 'symbols dumper for flat assembler',0Dh,0Ah
|
||||
db 'usage: symbols <input> <output>',0Dh,0Ah
|
||||
db 0
|
||||
_error_prefix db 'error: ',0
|
||||
_error_suffix db '.',0Dh,0Ah,0
|
||||
|
||||
section '.bss' writeable align 4
|
||||
|
||||
input dd ?
|
||||
output_buffer dd ?
|
||||
output_handle dd ?
|
||||
|
||||
argc dd ?
|
||||
argv dd ?
|
||||
|
||||
display_handle dd ?
|
||||
character db ?
|
||||
|
||||
params rb 1000h
|
||||
buffer rb 1000h
|
107
toolchain/fasmw17332/TOOLS/LIBC/SYSTEM.INC
Normal file
107
toolchain/fasmw17332/TOOLS/LIBC/SYSTEM.INC
Normal file
@ -0,0 +1,107 @@
|
||||
|
||||
extrn malloc
|
||||
extrn getenv
|
||||
extrn fopen
|
||||
extrn fclose
|
||||
extrn fread
|
||||
extrn fwrite
|
||||
extrn fseek
|
||||
extrn ftell
|
||||
extrn time
|
||||
extrn exit
|
||||
extrn 'free' as libc_free
|
||||
extrn 'write' as libc_write
|
||||
|
||||
alloc:
|
||||
ccall malloc,eax
|
||||
test eax,eax
|
||||
jz allocation_failed
|
||||
clc
|
||||
ret
|
||||
allocation_failed:
|
||||
stc
|
||||
ret
|
||||
free:
|
||||
ccall libc_free,eax
|
||||
ret
|
||||
display_string:
|
||||
lodsb
|
||||
or al,al
|
||||
jz string_displayed
|
||||
mov dl,al
|
||||
call display_character
|
||||
jmp display_string
|
||||
string_displayed:
|
||||
ret
|
||||
display_character:
|
||||
mov [character],dl
|
||||
ccall libc_write,[display_handle],character,1
|
||||
ret
|
||||
open:
|
||||
push esi edi ebp
|
||||
call adapt_path
|
||||
ccall fopen,buffer,open_mode
|
||||
pop ebp edi esi
|
||||
or eax,eax
|
||||
jz file_error
|
||||
mov ebx,eax
|
||||
clc
|
||||
ret
|
||||
adapt_path:
|
||||
mov esi,edx
|
||||
mov edi,buffer
|
||||
copy_path:
|
||||
lods byte [esi]
|
||||
cmp al,'\'
|
||||
jne path_char_ok
|
||||
mov al,'/'
|
||||
path_char_ok:
|
||||
stos byte [edi]
|
||||
or al,al
|
||||
jnz copy_path
|
||||
cmp edi,buffer+1000h
|
||||
ja not_enough_memory
|
||||
ret
|
||||
create:
|
||||
push esi edi ebp
|
||||
call adapt_path
|
||||
ccall fopen,buffer,create_mode
|
||||
pop ebp edi esi
|
||||
or eax,eax
|
||||
jz file_error
|
||||
mov ebx,eax
|
||||
clc
|
||||
ret
|
||||
close:
|
||||
ccall fclose,ebx
|
||||
ret
|
||||
read:
|
||||
push ebx ecx edx esi edi
|
||||
ccall fread,edx,1,ecx,ebx
|
||||
pop edi esi edx ecx ebx
|
||||
cmp eax,ecx
|
||||
jne file_error
|
||||
clc
|
||||
ret
|
||||
file_error:
|
||||
stc
|
||||
ret
|
||||
write:
|
||||
push ebx ecx edx esi edi
|
||||
ccall fwrite,edx,1,ecx,ebx
|
||||
pop edi esi edx ecx ebx
|
||||
cmp eax,ecx
|
||||
jne file_error
|
||||
clc
|
||||
ret
|
||||
lseek:
|
||||
push ebx
|
||||
movzx eax,al
|
||||
ccall fseek,ebx,edx,eax
|
||||
mov ebx,[esp]
|
||||
ccall ftell,ebx
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
open_mode db 'r',0
|
||||
create_mode db 'w',0
|
690
toolchain/fasmw17332/TOOLS/LISTING.INC
Normal file
690
toolchain/fasmw17332/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,'?'
|
115
toolchain/fasmw17332/TOOLS/PREPSRC.INC
Normal file
115
toolchain/fasmw17332/TOOLS/PREPSRC.INC
Normal file
@ -0,0 +1,115 @@
|
||||
|
||||
preprocessed_source:
|
||||
mov edx,[input_file]
|
||||
call open
|
||||
jc input_not_found
|
||||
mov al,2
|
||||
xor edx,edx
|
||||
call lseek
|
||||
cmp eax,30h
|
||||
jb invalid_input
|
||||
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
|
||||
cmp dword [eax],1A736166h
|
||||
jne invalid_input
|
||||
mov esi,[eax+32]
|
||||
add esi,eax
|
||||
mov ebp,[eax+36]
|
||||
add ebp,esi
|
||||
mov edi,eax
|
||||
push eax
|
||||
preprocessed_to_text:
|
||||
cmp esi,ebp
|
||||
jae conversion_done
|
||||
add esi,16
|
||||
xor dl,dl
|
||||
convert_preprocessed_line:
|
||||
lodsb
|
||||
cmp al,1Ah
|
||||
je copy_symbol
|
||||
cmp al,22h
|
||||
je copy_symbol
|
||||
cmp al,3Bh
|
||||
je preprocessor_symbols
|
||||
or al,al
|
||||
jz line_converted
|
||||
stosb
|
||||
xor dl,dl
|
||||
jmp convert_preprocessed_line
|
||||
copy_symbol:
|
||||
or dl,dl
|
||||
jz space_ok
|
||||
mov byte [edi],20h
|
||||
inc edi
|
||||
space_ok:
|
||||
cmp al,22h
|
||||
je quoted
|
||||
lodsb
|
||||
movzx ecx,al
|
||||
rep movsb
|
||||
or dl,-1
|
||||
jmp convert_preprocessed_line
|
||||
quoted:
|
||||
mov al,27h
|
||||
stosb
|
||||
lodsd
|
||||
mov ecx,eax
|
||||
jecxz quoted_copied
|
||||
copy_quoted:
|
||||
lodsb
|
||||
stosb
|
||||
cmp al,27h
|
||||
jne quote_ok
|
||||
stosb
|
||||
quote_ok:
|
||||
loop copy_quoted
|
||||
quoted_copied:
|
||||
mov al,27h
|
||||
stosb
|
||||
or dl,-1
|
||||
jmp convert_preprocessed_line
|
||||
preprocessor_symbols:
|
||||
mov al,3Bh
|
||||
stosb
|
||||
jmp copy_symbol
|
||||
line_converted:
|
||||
mov ax,0A0Dh
|
||||
stosw
|
||||
jmp preprocessed_to_text
|
||||
conversion_done:
|
||||
mov edx,[output_file]
|
||||
call create
|
||||
jc writing_error
|
||||
pop edx
|
||||
mov ecx,edi
|
||||
sub ecx,edx
|
||||
call write
|
||||
jc writing_error
|
||||
call close
|
||||
ret
|
||||
|
||||
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
|
||||
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
|
26
toolchain/fasmw17332/TOOLS/README.TXT
Normal file
26
toolchain/fasmw17332/TOOLS/README.TXT
Normal file
@ -0,0 +1,26 @@
|
||||
|
||||
This directory contains some tools, which extract various types of information
|
||||
from the symbolic information file generated by flat assembler, and present
|
||||
them in a human-readable form.
|
||||
|
||||
The listing tool creates a listing of assembled code - this tool needs to be
|
||||
executed in the exact configuration, in which the assembly was taking place.
|
||||
All the source files and the output file aswell must not have been moved or
|
||||
modified - if any of them was altered before generating the listing, it is
|
||||
going to contain garbage instead of useful information. For example, if you
|
||||
assembled the file with the command like:
|
||||
|
||||
fasm example.asm example.exe -s example.fas
|
||||
|
||||
you should generate listing by immediately running this command from the same
|
||||
directory:
|
||||
|
||||
listing example.fas example.lst
|
||||
|
||||
In addition, the "-a" switch is recommended to use in the case of executable
|
||||
formats, as it allows to get the run-time addresses for all the assembled code
|
||||
and data.
|
||||
|
||||
The preprocessed source and symbols dump tools are simpler ones - they only
|
||||
need the symbolic information file as input and generate proper output text
|
||||
regardless of the availability of other files.
|
444
toolchain/fasmw17332/TOOLS/SYMBOLS.INC
Normal file
444
toolchain/fasmw17332/TOOLS/SYMBOLS.INC
Normal file
@ -0,0 +1,444 @@
|
||||
|
||||
symbols:
|
||||
mov edx,[input_file]
|
||||
call open
|
||||
jc input_not_found
|
||||
mov al,2
|
||||
xor edx,edx
|
||||
call lseek
|
||||
cmp eax,30h
|
||||
jb invalid_input
|
||||
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
|
||||
cmp dword [eax],1A736166h
|
||||
jne invalid_input
|
||||
mov [input],eax
|
||||
add [eax+16],eax
|
||||
add [eax+24],eax
|
||||
add [eax+32],eax
|
||||
add [eax+48],eax
|
||||
mov edx,[eax+16]
|
||||
add [eax+8],edx
|
||||
|
||||
mov ebx,eax
|
||||
mov eax,[ebx+20]
|
||||
add eax,[ebx+36]
|
||||
cmp eax,1000h
|
||||
ja allocate_output_buffer
|
||||
mov eax,1000h
|
||||
allocate_output_buffer:
|
||||
call alloc
|
||||
jc not_enough_memory
|
||||
mov [output_buffer],eax
|
||||
|
||||
mov edx,[output_file]
|
||||
call create
|
||||
jc writing_error
|
||||
mov [output_handle],ebx
|
||||
|
||||
mov ebx,[input]
|
||||
mov edx,[ebx+24]
|
||||
mov ebp,[ebx+28]
|
||||
add ebp,edx
|
||||
dump_symbols:
|
||||
cmp edx,ebp
|
||||
je dump_done
|
||||
test byte [edx+8],1
|
||||
jz next_symbol
|
||||
test byte [edx+9],4
|
||||
jnz next_symbol
|
||||
mov edi,[output_buffer]
|
||||
mov esi,[edx+24]
|
||||
test esi,esi
|
||||
jz anonymous_symbol
|
||||
mov ebx,[input]
|
||||
btr esi,31
|
||||
jc symbol_name_in_strings_table
|
||||
add esi,[ebx+32]
|
||||
lodsb
|
||||
movzx ecx,al
|
||||
rep movsb
|
||||
jmp symbol_name_ok
|
||||
symbol_name_in_strings_table:
|
||||
add esi,[ebx+16]
|
||||
call write_string
|
||||
jmp symbol_name_ok
|
||||
anonymous_symbol:
|
||||
mov al,'@'
|
||||
stosb
|
||||
stosb
|
||||
symbol_name_ok:
|
||||
test byte [edx+9],2
|
||||
jnz negative_value
|
||||
mov eax,': 0x'
|
||||
stosd
|
||||
mov eax,[edx+4]
|
||||
call write_hex_dword
|
||||
mov eax,[edx]
|
||||
call write_hex_dword
|
||||
jmp write_address_registers
|
||||
negative_value:
|
||||
mov eax,': -0'
|
||||
stosd
|
||||
mov al,'x'
|
||||
stosb
|
||||
mov ecx,[edx]
|
||||
mov eax,[edx+4]
|
||||
not ecx
|
||||
not eax
|
||||
add ecx,1
|
||||
adc eax,0
|
||||
push ecx
|
||||
or ecx,eax
|
||||
jnz negative_value_ok
|
||||
mov byte [edi],'1'
|
||||
inc edi
|
||||
negative_value_ok:
|
||||
call write_hex_dword
|
||||
pop eax
|
||||
call write_hex_dword
|
||||
write_address_registers:
|
||||
mov bl,[edx+12]
|
||||
mov bh,[edx+14]
|
||||
call write_address_register
|
||||
mov bl,[edx+13]
|
||||
mov bh,[edx+15]
|
||||
call write_address_register
|
||||
mov bl,[edx+11]
|
||||
cmp bl,0
|
||||
je symbol_type_ok
|
||||
jl negated_symbol
|
||||
mov ax,', '
|
||||
stosw
|
||||
jmp write_symbol_type
|
||||
negated_symbol:
|
||||
mov ax,', '
|
||||
stosw
|
||||
mov esi,_negated
|
||||
call write_string
|
||||
neg bl
|
||||
write_symbol_type:
|
||||
cmp bl,1
|
||||
je segment_type
|
||||
cmp bl,5
|
||||
je rva_type
|
||||
cmp bl,6
|
||||
je plt_type
|
||||
test byte [edx+20+3],80h
|
||||
jnz external
|
||||
mov esi,_relocatable
|
||||
call write_string
|
||||
cmp dword [edx+20],0
|
||||
je symbol_type_ok
|
||||
mov esi,_in_section
|
||||
call write_string
|
||||
jmp write_symbol_base
|
||||
simple_relocatable:
|
||||
mov esi,_relocatable
|
||||
call write_string
|
||||
jmp symbol_type_ok
|
||||
external:
|
||||
mov esi,_relative_to_external
|
||||
call write_string
|
||||
jmp write_symbol_base
|
||||
segment_type:
|
||||
mov esi,_relocatable_segment
|
||||
call write_string
|
||||
jmp symbol_type_ok
|
||||
rva_type:
|
||||
mov esi,_rva
|
||||
call write_string
|
||||
jmp write_symbol_base
|
||||
plt_type:
|
||||
mov esi,_plt
|
||||
call write_string
|
||||
write_symbol_base:
|
||||
mov esi,[edx+20]
|
||||
btr esi,31
|
||||
jc write_external_name
|
||||
dec esi
|
||||
shl esi,2
|
||||
mov ebx,[input]
|
||||
add esi,[ebx+48]
|
||||
mov esi,[esi]
|
||||
add esi,[ebx+16]
|
||||
call write_string
|
||||
mov al,'('
|
||||
stosb
|
||||
mov eax,[edx+20]
|
||||
call write_dec_number
|
||||
mov al,')'
|
||||
stosb
|
||||
jmp symbol_type_ok
|
||||
write_external_name:
|
||||
mov ebx,[input]
|
||||
add esi,[ebx+16]
|
||||
call write_string
|
||||
jmp symbol_type_ok
|
||||
symbol_type_ok:
|
||||
mov esi,_defined
|
||||
call write_string
|
||||
mov ebx,[edx+28]
|
||||
mov eax,[input]
|
||||
add ebx,[eax+32]
|
||||
call write_line_identifier
|
||||
mov ax,0A0Dh
|
||||
stosw
|
||||
push edx
|
||||
mov ebx,[output_handle]
|
||||
mov ecx,edi
|
||||
mov edx,[output_buffer]
|
||||
sub ecx,edx
|
||||
call write
|
||||
pop edx
|
||||
next_symbol:
|
||||
add edx,32
|
||||
jmp dump_symbols
|
||||
dump_done:
|
||||
mov ebx,[output_handle]
|
||||
call close
|
||||
ret
|
||||
|
||||
write_string:
|
||||
lodsb
|
||||
test al,al
|
||||
jz string_ok
|
||||
stosb
|
||||
jmp write_string
|
||||
string_ok:
|
||||
ret
|
||||
write_hex_dword:
|
||||
mov ebx,eax
|
||||
mov ecx,8
|
||||
write_hex_digits:
|
||||
xor al,al
|
||||
shld eax,ebx,4
|
||||
cmp al,10
|
||||
sbb al,69h
|
||||
das
|
||||
stosb
|
||||
shl ebx,4
|
||||
loop write_hex_digits
|
||||
ret
|
||||
write_dec_number:
|
||||
push ebx edx
|
||||
mov ecx,1000000000
|
||||
xor edx,edx
|
||||
xor bl,bl
|
||||
dec_number_loop:
|
||||
div ecx
|
||||
push edx
|
||||
cmp ecx,1
|
||||
je write_dec_digit
|
||||
or bl,bl
|
||||
jnz write_dec_digit
|
||||
or al,al
|
||||
jz dec_digit_ok
|
||||
not bl
|
||||
write_dec_digit:
|
||||
add al,30h
|
||||
stosb
|
||||
dec_digit_ok:
|
||||
mov eax,ecx
|
||||
xor edx,edx
|
||||
mov ecx,10
|
||||
div ecx
|
||||
mov ecx,eax
|
||||
pop eax
|
||||
or ecx,ecx
|
||||
jnz dec_number_loop
|
||||
pop edx ebx
|
||||
ret
|
||||
write_address_register:
|
||||
cmp bh,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_not_found
|
||||
cmp al,bl
|
||||
je register_found
|
||||
cmp bl,[esi]
|
||||
je register_found
|
||||
lodsb
|
||||
movzx eax,al
|
||||
add esi,eax
|
||||
jmp find_register
|
||||
register_not_found:
|
||||
mov al,bl
|
||||
shr al,5
|
||||
cmp al,0Ch shr 1
|
||||
je xmm_register
|
||||
cmp al,0Eh shr 1
|
||||
je ymm_register
|
||||
cmp al,6 shr 1
|
||||
je zmm_register
|
||||
register_found:
|
||||
lodsb
|
||||
movzx ecx,al
|
||||
rep movsb
|
||||
write_register_scale:
|
||||
pop esi
|
||||
cmp bh,1
|
||||
je register_ok
|
||||
mov al,'*'
|
||||
stosb
|
||||
movzx eax,bh
|
||||
call write_dec_number
|
||||
register_ok:
|
||||
ret
|
||||
zmm_register:
|
||||
mov al,'z'
|
||||
jmp vector_address_register
|
||||
ymm_register:
|
||||
mov al,'y'
|
||||
jmp vector_address_register
|
||||
xmm_register:
|
||||
mov al,'x'
|
||||
vector_address_register:
|
||||
stosb
|
||||
mov ax,'mm'
|
||||
stosw
|
||||
mov al,bl
|
||||
and eax,11111b
|
||||
call write_dec_number
|
||||
jmp write_register_scale
|
||||
|
||||
write_line_identifier:
|
||||
test dword [ebx+4],80000000h
|
||||
jnz identify_macro_generated_line
|
||||
mov esi,[ebx]
|
||||
mov eax,[input]
|
||||
test esi,esi
|
||||
jz main_file
|
||||
add esi,[eax+32]
|
||||
jmp file_name_ok
|
||||
main_file:
|
||||
mov esi,[eax+8]
|
||||
file_name_ok:
|
||||
call write_string
|
||||
mov al,'['
|
||||
stosb
|
||||
mov eax,[ebx+4]
|
||||
call write_dec_number
|
||||
mov al,']'
|
||||
stosb
|
||||
ret
|
||||
identify_macro_generated_line:
|
||||
mov al,'{'
|
||||
stosb
|
||||
mov esi,_generated_by
|
||||
call write_string
|
||||
push ebx
|
||||
mov ebx,[ebx+8]
|
||||
mov eax,[input]
|
||||
add ebx,[eax+32]
|
||||
call write_line_identifier
|
||||
pop ebx
|
||||
mov eax,[ebx+8]
|
||||
cmp eax,[ebx+12]
|
||||
je macro_generated_line_identifier_ok
|
||||
mov esi,_from
|
||||
call write_string
|
||||
push ebx
|
||||
mov ebx,[ebx+12]
|
||||
mov eax,[input]
|
||||
add ebx,[eax+32]
|
||||
call write_line_identifier
|
||||
pop ebx
|
||||
macro_generated_line_identifier_ok:
|
||||
mov al,'}'
|
||||
stosb
|
||||
ret
|
||||
|
||||
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
|
||||
|
||||
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 94h,3,'eip'
|
||||
db 98h,3,'rip'
|
||||
db 0,1,'?'
|
||||
|
||||
_negated db 'negated ',0
|
||||
_relocatable_segment db 'relocatable segment',0
|
||||
_relocatable db 'relocatable',0
|
||||
_in_section db ' in section ',0
|
||||
_relative_to_external db 'relative to external ',0
|
||||
_rva db 'relative to RVA or GOT-based offset of ',0
|
||||
_plt db 'relative to address of PLT entry for ',0
|
||||
_defined db ', defined in ',0
|
||||
_generated_by db 'line generated by ',0
|
||||
_from db ' from ',0
|
229
toolchain/fasmw17332/TOOLS/WIN32/LISTING.ASM
Normal file
229
toolchain/fasmw17332/TOOLS/WIN32/LISTING.ASM
Normal file
@ -0,0 +1,229 @@
|
||||
|
||||
format PE console 4.0
|
||||
entry start
|
||||
|
||||
include 'win32a.inc'
|
||||
|
||||
section '.data' data readable writeable
|
||||
|
||||
_usage db 'listing generator for flat assembler',0Dh,0Ah
|
||||
db 'usage: listing <input> <output>',0Dh,0Ah
|
||||
db 'optional settings:',0Dh,0Ah
|
||||
db ' -a show target addresses for assembled code',0Dh,0Ah
|
||||
db ' -b <number> set the amount of bytes listed per line',0Dh,0Ah
|
||||
db 0
|
||||
_error_prefix db 'error: ',0
|
||||
_error_suffix db '.',0Dh,0Ah,0
|
||||
|
||||
line_break db 0Dh,0Ah
|
||||
|
||||
input_file dd 0
|
||||
output_file dd 0
|
||||
code_bytes_per_line dd 16
|
||||
show_addresses db 0
|
||||
|
||||
input dd ?
|
||||
assembled_code dd ?
|
||||
assembled_code_length dd ?
|
||||
code_end dd ?
|
||||
code_offset dd ?
|
||||
code_length dd ?
|
||||
output_handle dd ?
|
||||
output_buffer dd ?
|
||||
current_source_file dd ?
|
||||
current_source_line dd ?
|
||||
source dd ?
|
||||
source_length dd ?
|
||||
maximum_address_length dd ?
|
||||
address_start dd ?
|
||||
last_listed_address dd ?
|
||||
|
||||
display_handle dd ?
|
||||
bytes_count dd ?
|
||||
|
||||
params rb 1000h
|
||||
characters rb 100h
|
||||
|
||||
section '.text' code readable executable
|
||||
|
||||
start:
|
||||
|
||||
mov [display_handle],STD_OUTPUT_HANDLE
|
||||
|
||||
call get_params
|
||||
jnc make_listing
|
||||
|
||||
mov esi,_usage
|
||||
call display_string
|
||||
invoke ExitProcess,2
|
||||
|
||||
make_listing:
|
||||
call listing
|
||||
invoke ExitProcess,0
|
||||
|
||||
error:
|
||||
mov [display_handle],STD_ERROR_HANDLE
|
||||
mov esi,_error_prefix
|
||||
call display_string
|
||||
pop esi
|
||||
call display_string
|
||||
mov esi,_error_suffix
|
||||
call display_string
|
||||
invoke ExitProcess,1
|
||||
|
||||
get_params:
|
||||
invoke GetCommandLine
|
||||
mov esi,eax
|
||||
mov edi,params
|
||||
find_command_start:
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je find_command_start
|
||||
cmp al,22h
|
||||
je skip_quoted_name
|
||||
skip_name:
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je find_param
|
||||
or al,al
|
||||
jz all_params
|
||||
jmp skip_name
|
||||
skip_quoted_name:
|
||||
lodsb
|
||||
cmp al,22h
|
||||
je find_param
|
||||
or al,al
|
||||
jz all_params
|
||||
jmp skip_quoted_name
|
||||
find_param:
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je find_param
|
||||
cmp al,'-'
|
||||
je option_param
|
||||
cmp al,0Dh
|
||||
je all_params
|
||||
or al,al
|
||||
jz all_params
|
||||
cmp [input_file],0
|
||||
jne get_output_file
|
||||
mov [input_file],edi
|
||||
jmp process_param
|
||||
get_output_file:
|
||||
cmp [output_file],0
|
||||
jne bad_params
|
||||
mov [output_file],edi
|
||||
process_param:
|
||||
cmp al,22h
|
||||
je string_param
|
||||
copy_param:
|
||||
stosb
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je param_end
|
||||
cmp al,0Dh
|
||||
je param_end
|
||||
or al,al
|
||||
jz param_end
|
||||
jmp copy_param
|
||||
string_param:
|
||||
lodsb
|
||||
cmp al,22h
|
||||
je string_param_end
|
||||
cmp al,0Dh
|
||||
je param_end
|
||||
or al,al
|
||||
jz param_end
|
||||
stosb
|
||||
jmp string_param
|
||||
option_param:
|
||||
lodsb
|
||||
cmp al,'a'
|
||||
je addresses_option
|
||||
cmp al,'A'
|
||||
je addresses_option
|
||||
cmp al,'b'
|
||||
je bytes_per_line_option
|
||||
cmp al,'B'
|
||||
je bytes_per_line_option
|
||||
bad_params:
|
||||
stc
|
||||
ret
|
||||
get_option_value:
|
||||
xor eax,eax
|
||||
mov edx,eax
|
||||
get_option_digit:
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je option_value_ok
|
||||
cmp al,0Dh
|
||||
je option_value_ok
|
||||
or al,al
|
||||
jz option_value_ok
|
||||
sub al,30h
|
||||
jc invalid_option_value
|
||||
cmp al,9
|
||||
ja invalid_option_value
|
||||
imul edx,10
|
||||
jo invalid_option_value
|
||||
add edx,eax
|
||||
jc invalid_option_value
|
||||
jmp get_option_digit
|
||||
option_value_ok:
|
||||
dec esi
|
||||
clc
|
||||
ret
|
||||
invalid_option_value:
|
||||
stc
|
||||
ret
|
||||
bytes_per_line_option:
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je bytes_per_line_option
|
||||
cmp al,0Dh
|
||||
je bad_params
|
||||
or al,al
|
||||
jz bad_params
|
||||
dec esi
|
||||
call get_option_value
|
||||
or edx,edx
|
||||
jz bad_params
|
||||
cmp edx,1000
|
||||
ja bad_params
|
||||
mov [code_bytes_per_line],edx
|
||||
jmp find_param
|
||||
addresses_option:
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je set_addresses_option
|
||||
cmp al,0Dh
|
||||
je set_addresses_option
|
||||
or al,al
|
||||
jnz bad_params
|
||||
set_addresses_option:
|
||||
dec esi
|
||||
mov [show_addresses],1
|
||||
jmp find_param
|
||||
param_end:
|
||||
dec esi
|
||||
string_param_end:
|
||||
xor al,al
|
||||
stosb
|
||||
jmp find_param
|
||||
all_params:
|
||||
cmp [input_file],0
|
||||
je bad_params
|
||||
cmp [output_file],0
|
||||
je bad_params
|
||||
clc
|
||||
ret
|
||||
|
||||
include 'system.inc'
|
||||
|
||||
include '..\listing.inc'
|
||||
|
||||
section '.idata' import data readable writeable
|
||||
|
||||
library kernel32,'KERNEL32.DLL'
|
||||
|
||||
include 'api\kernel32.inc'
|
138
toolchain/fasmw17332/TOOLS/WIN32/PREPSRC.ASM
Normal file
138
toolchain/fasmw17332/TOOLS/WIN32/PREPSRC.ASM
Normal file
@ -0,0 +1,138 @@
|
||||
|
||||
format PE console 4.0
|
||||
entry start
|
||||
|
||||
include 'win32a.inc'
|
||||
|
||||
section '.data' data readable writeable
|
||||
|
||||
_usage db 'preprocessed source dumper for flat assembler',0Dh,0Ah
|
||||
db 'usage: prepsrc <input> <output>',0Dh,0Ah
|
||||
db 0
|
||||
_error_prefix db 'error: ',0
|
||||
_error_suffix db '.',0Dh,0Ah,0
|
||||
|
||||
input_file dd 0
|
||||
output_file dd 0
|
||||
|
||||
display_handle dd ?
|
||||
bytes_count dd ?
|
||||
|
||||
params rb 1000h
|
||||
|
||||
section '.text' code readable executable
|
||||
|
||||
start:
|
||||
|
||||
mov [display_handle],STD_OUTPUT_HANDLE
|
||||
|
||||
call get_params
|
||||
jnc make_dump
|
||||
|
||||
mov esi,_usage
|
||||
call display_string
|
||||
invoke ExitProcess,2
|
||||
|
||||
make_dump:
|
||||
call preprocessed_source
|
||||
invoke ExitProcess,0
|
||||
|
||||
error:
|
||||
mov [display_handle],STD_ERROR_HANDLE
|
||||
mov esi,_error_prefix
|
||||
call display_string
|
||||
pop esi
|
||||
call display_string
|
||||
mov esi,_error_suffix
|
||||
call display_string
|
||||
invoke ExitProcess,1
|
||||
|
||||
get_params:
|
||||
invoke GetCommandLine
|
||||
mov esi,eax
|
||||
mov edi,params
|
||||
find_command_start:
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je find_command_start
|
||||
cmp al,22h
|
||||
je skip_quoted_name
|
||||
skip_name:
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je find_param
|
||||
or al,al
|
||||
jz all_params
|
||||
jmp skip_name
|
||||
skip_quoted_name:
|
||||
lodsb
|
||||
cmp al,22h
|
||||
je find_param
|
||||
or al,al
|
||||
jz all_params
|
||||
jmp skip_quoted_name
|
||||
find_param:
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je find_param
|
||||
cmp al,0Dh
|
||||
je all_params
|
||||
or al,al
|
||||
jz all_params
|
||||
cmp [input_file],0
|
||||
jne get_output_file
|
||||
mov [input_file],edi
|
||||
jmp process_param
|
||||
get_output_file:
|
||||
cmp [output_file],0
|
||||
jne bad_params
|
||||
mov [output_file],edi
|
||||
process_param:
|
||||
cmp al,22h
|
||||
je string_param
|
||||
copy_param:
|
||||
stosb
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je param_end
|
||||
cmp al,0Dh
|
||||
je param_end
|
||||
or al,al
|
||||
jz param_end
|
||||
jmp copy_param
|
||||
string_param:
|
||||
lodsb
|
||||
cmp al,22h
|
||||
je string_param_end
|
||||
cmp al,0Dh
|
||||
je param_end
|
||||
or al,al
|
||||
jz param_end
|
||||
stosb
|
||||
jmp string_param
|
||||
bad_params:
|
||||
stc
|
||||
ret
|
||||
param_end:
|
||||
dec esi
|
||||
string_param_end:
|
||||
xor al,al
|
||||
stosb
|
||||
jmp find_param
|
||||
all_params:
|
||||
cmp [input_file],0
|
||||
je bad_params
|
||||
cmp [output_file],0
|
||||
je bad_params
|
||||
clc
|
||||
ret
|
||||
|
||||
include 'system.inc'
|
||||
|
||||
include '..\prepsrc.inc'
|
||||
|
||||
section '.idata' import data readable writeable
|
||||
|
||||
library kernel32,'KERNEL32.DLL'
|
||||
|
||||
include 'api\kernel32.inc'
|
142
toolchain/fasmw17332/TOOLS/WIN32/SYMBOLS.ASM
Normal file
142
toolchain/fasmw17332/TOOLS/WIN32/SYMBOLS.ASM
Normal file
@ -0,0 +1,142 @@
|
||||
|
||||
format PE console 4.0
|
||||
entry start
|
||||
|
||||
include 'win32a.inc'
|
||||
|
||||
section '.data' data readable writeable
|
||||
|
||||
_usage db 'symbols dumper for flat assembler',0Dh,0Ah
|
||||
db 'usage: symbols <input> <output>',0Dh,0Ah
|
||||
db 0
|
||||
_error_prefix db 'error: ',0
|
||||
_error_suffix db '.',0Dh,0Ah,0
|
||||
|
||||
input_file dd 0
|
||||
output_file dd 0
|
||||
|
||||
input dd ?
|
||||
output_buffer dd ?
|
||||
output_handle dd ?
|
||||
|
||||
display_handle dd ?
|
||||
bytes_count dd ?
|
||||
|
||||
params rb 1000h
|
||||
|
||||
section '.text' code readable executable
|
||||
|
||||
start:
|
||||
|
||||
mov [display_handle],STD_OUTPUT_HANDLE
|
||||
|
||||
call get_params
|
||||
jnc make_dump
|
||||
|
||||
mov esi,_usage
|
||||
call display_string
|
||||
invoke ExitProcess,2
|
||||
|
||||
make_dump:
|
||||
call symbols
|
||||
invoke ExitProcess,0
|
||||
|
||||
error:
|
||||
mov [display_handle],STD_ERROR_HANDLE
|
||||
mov esi,_error_prefix
|
||||
call display_string
|
||||
pop esi
|
||||
call display_string
|
||||
mov esi,_error_suffix
|
||||
call display_string
|
||||
invoke ExitProcess,1
|
||||
|
||||
get_params:
|
||||
invoke GetCommandLine
|
||||
mov esi,eax
|
||||
mov edi,params
|
||||
find_command_start:
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je find_command_start
|
||||
cmp al,22h
|
||||
je skip_quoted_name
|
||||
skip_name:
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je find_param
|
||||
or al,al
|
||||
jz all_params
|
||||
jmp skip_name
|
||||
skip_quoted_name:
|
||||
lodsb
|
||||
cmp al,22h
|
||||
je find_param
|
||||
or al,al
|
||||
jz all_params
|
||||
jmp skip_quoted_name
|
||||
find_param:
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je find_param
|
||||
cmp al,0Dh
|
||||
je all_params
|
||||
or al,al
|
||||
jz all_params
|
||||
cmp [input_file],0
|
||||
jne get_output_file
|
||||
mov [input_file],edi
|
||||
jmp process_param
|
||||
get_output_file:
|
||||
cmp [output_file],0
|
||||
jne bad_params
|
||||
mov [output_file],edi
|
||||
process_param:
|
||||
cmp al,22h
|
||||
je string_param
|
||||
copy_param:
|
||||
stosb
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je param_end
|
||||
cmp al,0Dh
|
||||
je param_end
|
||||
or al,al
|
||||
jz param_end
|
||||
jmp copy_param
|
||||
string_param:
|
||||
lodsb
|
||||
cmp al,22h
|
||||
je string_param_end
|
||||
cmp al,0Dh
|
||||
je param_end
|
||||
or al,al
|
||||
jz param_end
|
||||
stosb
|
||||
jmp string_param
|
||||
bad_params:
|
||||
stc
|
||||
ret
|
||||
param_end:
|
||||
dec esi
|
||||
string_param_end:
|
||||
xor al,al
|
||||
stosb
|
||||
jmp find_param
|
||||
all_params:
|
||||
cmp [input_file],0
|
||||
je bad_params
|
||||
cmp [output_file],0
|
||||
je bad_params
|
||||
clc
|
||||
ret
|
||||
|
||||
include 'system.inc'
|
||||
|
||||
include '..\symbols.inc'
|
||||
|
||||
section '.idata' import data readable writeable
|
||||
|
||||
library kernel32,'KERNEL32.DLL'
|
||||
|
||||
include 'api\kernel32.inc'
|
66
toolchain/fasmw17332/TOOLS/WIN32/SYSTEM.INC
Normal file
66
toolchain/fasmw17332/TOOLS/WIN32/SYSTEM.INC
Normal file
@ -0,0 +1,66 @@
|
||||
|
||||
display_string:
|
||||
invoke GetStdHandle,[display_handle]
|
||||
mov edx,eax
|
||||
mov edi,esi
|
||||
or ecx,-1
|
||||
xor al,al
|
||||
repne scasb
|
||||
neg ecx
|
||||
sub ecx,2
|
||||
invoke WriteFile,edx,esi,ecx,bytes_count,0
|
||||
retn
|
||||
alloc:
|
||||
invoke VirtualAlloc,0,eax,MEM_COMMIT,PAGE_READWRITE
|
||||
or eax,eax
|
||||
jz allocation_error
|
||||
clc
|
||||
retn
|
||||
allocation_error:
|
||||
stc
|
||||
retn
|
||||
free:
|
||||
invoke VirtualFree,eax,0,MEM_RELEASE
|
||||
retn
|
||||
open:
|
||||
invoke CreateFile,edx,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0
|
||||
cmp eax,-1
|
||||
je file_error
|
||||
mov ebx,eax
|
||||
clc
|
||||
retn
|
||||
file_error:
|
||||
stc
|
||||
retn
|
||||
create:
|
||||
invoke CreateFile,edx,GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0
|
||||
cmp eax,-1
|
||||
je file_error
|
||||
mov ebx,eax
|
||||
clc
|
||||
retn
|
||||
write:
|
||||
invoke WriteFile,ebx,edx,ecx,bytes_count,0
|
||||
or eax,eax
|
||||
jz file_error
|
||||
clc
|
||||
retn
|
||||
read:
|
||||
push ecx
|
||||
invoke ReadFile,ebx,edx,ecx,bytes_count,0
|
||||
pop edx
|
||||
or eax,eax
|
||||
jz file_error
|
||||
cmp edx,[bytes_count]
|
||||
jne file_error
|
||||
clc
|
||||
retn
|
||||
close:
|
||||
invoke CloseHandle,ebx
|
||||
retn
|
||||
lseek:
|
||||
movzx eax,al
|
||||
invoke SetFilePointer,ebx,edx,0,eax
|
||||
cmp eax,-1
|
||||
je file_error
|
||||
retn
|
Reference in New Issue
Block a user