asm_dip/toolchain/fasm2/source/macos/fasmg.o.asm
2024-11-25 00:04:53 -05:00

490 lines
9.0 KiB
NASM

include 'macro/struct.inc'
include 'macro/proc32.inc'
format MachO
public main as '_main'
include '../version.inc'
extrn '_malloc' as libc.malloc
extrn '_realloc' as libc.realloc
extrn '_free' as libc.free
extrn '_fopen' as libc.fopen
extrn '_fclose' as libc.fclose
extrn '_fread' as libc.fread
extrn '_fwrite' as libc.fwrite
extrn '_fseek' as libc.fseek
extrn '_ftell' as libc.ftell
extrn '_time' as libc.time
extrn '_write' as libc.write
extrn '_getenv' as getenv
extrn '_gettimeofday' as gettimeofday
extrn '_exit' as exit
struct timeval
time_t dd ?
suseconds_t dd ?
ends
section '__TEXT':'__text' align 16
main:
mov ecx,[esp+4]
mov [argc],ecx
mov ebx,[esp+8]
mov [argv],ebx
call system_init
call get_arguments
mov bl,al
cmp [no_logo],0
jne logo_ok
mov esi,_logo
xor ecx,ecx
call display_string
logo_ok:
test bl,bl
jnz display_usage_information
xor al,al
mov ecx,[verbosity_level]
jecxz init
or al,TRACE_ERROR_STACK
dec ecx
jz init
or al,TRACE_DISPLAY
init:
call assembly_init
ccall gettimeofday,start_time,0
assemble:
mov esi,[initial_commands]
mov edx,[source_path]
call assembly_pass
jc assembly_done
mov eax,[current_pass]
cmp eax,[maximum_number_of_passes]
jb assemble
call show_display_data
mov esi,_error_prefix
xor ecx,ecx
call display_error_string
mov esi,_code_cannot_be_generated
xor ecx,ecx
call display_error_string
mov esi,_message_suffix
xor ecx,ecx
call display_error_string
jmp assembly_failed
assembly_done:
call show_display_data
cmp [first_error],0
jne assembly_failed
cmp [no_logo],0
jne summary_done
mov eax,[current_pass]
xor edx,edx
call itoa
call display_string
mov esi,_passes
cmp [current_pass],1
jne display_passes_suffix
mov esi,_pass
display_passes_suffix:
xor ecx,ecx
call display_string
ccall gettimeofday,end_time,0
mov eax,[end_time.time_t]
sub eax,[start_time.time_t]
mov ecx,1000000
mul ecx
add eax,[end_time.suseconds_t]
adc edx,0
sub eax,[start_time.suseconds_t]
sbb edx,0
add eax,50000
mov ecx,1000000
div ecx
mov ebx,eax
mov eax,edx
xor edx,edx
mov ecx,100000
div ecx
mov [tenths_of_second],eax
xchg eax,ebx
or ebx,eax
jz display_output_length
xor edx,edx
call itoa
call display_string
mov esi,_message_suffix
mov ecx,1
call display_string
mov eax,[tenths_of_second]
xor edx,edx
call itoa
call display_string
mov esi,_seconds
xor ecx,ecx
call display_string
display_output_length:
call get_output_length
push eax edx
call itoa
call display_string
pop edx eax
mov esi,_bytes
cmp eax,1
jne display_bytes_suffix
test edx,edx
jnz display_bytes_suffix
mov esi,_byte
display_bytes_suffix:
xor ecx,ecx
call display_string
mov esi,_new_line
xor ecx,ecx
call display_string
summary_done:
mov ebx,[source_path]
mov edi,[output_path]
call write_output_file
jc write_failed
call assembly_shutdown
call system_shutdown
ccall exit,0
assembly_failed:
call show_errors
call assembly_shutdown
call system_shutdown
ccall exit,2
write_failed:
mov ebx,_write_failed
jmp fatal_error
out_of_memory:
mov ebx,_out_of_memory
jmp fatal_error
fatal_error:
mov esi,_error_prefix
xor ecx,ecx
call display_error_string
mov esi,ebx
xor ecx,ecx
call display_error_string
mov esi,_message_suffix
xor ecx,ecx
call display_error_string
call assembly_shutdown
call system_shutdown
ccall exit,3
display_usage_information:
mov esi,_usage
xor ecx,ecx
call display_string
call system_shutdown
ccall exit,1
get_arguments:
xor eax,eax
mov [initial_commands],eax
mov [source_path],eax
mov [output_path],eax
mov [no_logo],al
mov [verbosity_level],eax
mov [maximum_number_of_passes],100
mov [maximum_number_of_errors],1
mov [maximum_depth_of_stack],10000
mov ecx,[argc]
mov ebx,[argv]
add ebx,4
dec ecx
jz error_in_arguments
get_argument:
mov esi,[ebx]
mov al,[esi]
cmp al,'-'
je get_option
cmp [source_path],0
jne get_output_file
mov [source_path],esi
jmp next_argument
get_output_file:
cmp [output_path],0
jne error_in_arguments
mov [output_path],esi
jmp next_argument
get_option:
inc esi
lodsb
cmp al,'e'
je set_errors_limit
cmp al,'E'
je set_errors_limit
cmp al,'i'
je insert_initial_command
cmp al,'I'
je insert_initial_command
cmp al,'p'
je set_passes_limit
cmp al,'P'
je set_passes_limit
cmp al,'r'
je set_recursion_limit
cmp al,'R'
je set_recursion_limit
cmp al,'v'
je set_verbose_mode
cmp al,'V'
je set_verbose_mode
cmp al,'n'
je set_no_logo
cmp al,'N'
jne error_in_arguments
set_no_logo:
or [no_logo],-1
cmp byte [esi],0
je next_argument
error_in_arguments:
or al,-1
ret
set_verbose_mode:
cmp byte [esi],0
jne get_verbose_setting
dec ecx
jz error_in_arguments
add ebx,4
mov esi,[ebx]
get_verbose_setting:
call get_option_value
cmp edx,2
ja error_in_arguments
mov [verbosity_level],edx
jmp next_argument
set_errors_limit:
cmp byte [esi],0
jne get_errors_setting
dec ecx
jz error_in_arguments
add ebx,4
mov esi,[ebx]
get_errors_setting:
call get_option_value
test edx,edx
jz error_in_arguments
mov [maximum_number_of_errors],edx
jmp next_argument
set_recursion_limit:
cmp byte [esi],0
jne get_recursion_setting
dec ecx
jz error_in_arguments
add ebx,4
mov esi,[ebx]
get_recursion_setting:
call get_option_value
test edx,edx
jz error_in_arguments
mov [maximum_depth_of_stack],edx
jmp next_argument
set_passes_limit:
cmp byte [esi],0
jne get_passes_setting
dec ecx
jz error_in_arguments
add ebx,4
mov esi,[ebx]
get_passes_setting:
call get_option_value
test edx,edx
jz error_in_arguments
mov [maximum_number_of_passes],edx
next_argument:
add ebx,4
dec ecx
jnz get_argument
cmp [source_path],0
je error_in_arguments
xor al,al
ret
get_option_value:
xor eax,eax
mov edx,eax
find_option_value:
cmp byte [esi],20h
jne get_option_digit
inc esi
jmp find_option_value
get_option_digit:
lodsb
test 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
insert_initial_command:
cmp byte [esi],0
jne measure_initial_command
dec ecx
jz error_in_arguments
add ebx,4
mov esi,[ebx]
measure_initial_command:
push ebx ecx edi
mov edi,esi
or ecx,-1
xor al,al
repne scasb
not ecx
dec ecx
mov edi,[initial_commands]
lea eax,[ecx+2]
test edi,edi
jz allocate_initial_commands_buffer
mov edx,[initial_commands_length]
add edi,edx
add eax,edx
cmp eax,[initial_commands_maximum_length]
ja grow_initial_commands_buffer
copy_initial_command:
rep movsb
mov ax,0Ah
stosw
dec edi
sub edi,[initial_commands]
mov [initial_commands_length],edi
pop edi ecx ebx
jmp next_argument
allocate_initial_commands_buffer:
push ecx
mov ecx,eax
call malloc
mov [initial_commands],eax
mov [initial_commands_maximum_length],ecx
mov edi,eax
pop ecx
jmp copy_initial_command
grow_initial_commands_buffer:
push ecx
mov ecx,eax
mov eax,[initial_commands]
call realloc
mov [initial_commands],eax
mov [initial_commands_maximum_length],ecx
mov edi,eax
add edi,[initial_commands_length]
pop ecx
jmp copy_initial_command
include 'system.inc'
include '../assembler.inc'
include '../symbols.inc'
include '../expressions.inc'
include '../conditions.inc'
include '../floats.inc'
include '../directives.inc'
include '../calm.inc'
include '../errors.inc'
include '../map.inc'
include '../reader.inc'
include '../output.inc'
include '../console.inc'
section '__TEXT':'__cstring' align 4
_logo db 'flat assembler version g.',VERSION,10,0
_usage db 'Usage: fasmg source [output]',10
db 'Optional settings:',10
db ' -p limit Set the maximum allowed number of passes (default 100)',10
db ' -e limit Set the maximum number of displayed errors (default 1)',10
db ' -r limit Set the maximum depth of the stack (default 10000)',10
db ' -v flag Enable or disable showing all lines from the stack (default 0)',10
db ' -i command Insert instruction at the beginning of source',13,10
db ' -n Do not show logo nor summary',13,10
db 0
_pass db ' pass, ',0
_passes db ' passes, ',0
_dot db '.'
_seconds db ' seconds, ',0
_byte db ' byte.',0
_bytes db ' bytes.',0
_write_failed db 'failed to write the output file',0
_out_of_memory db 'not enough memory to complete the assembly',0
_code_cannot_be_generated db 'could not generate code within the allowed number of passes',0
_open_mode db 'r',0
_create_mode db 'w',0
include '../tables.inc'
include '../messages.inc'
section '__DATA':'__data' align 4
include '../variables.inc'
source_path dd ?
output_path dd ?
maximum_number_of_passes dd ?
initial_commands dd ?
initial_commands_length dd ?
initial_commands_maximum_length dd ?
argc dd ?
argv dd ?
timestamp dq ?
start_time timeval
end_time timeval
tenths_of_second dd ?
verbosity_level dd ?
no_logo db ?
path_buffer rb 1000h