add flat assembler toolchain
This commit is contained in:
341
toolchain/fasmw17332/SOURCE/LINUX/FASM.ASM
Normal file
341
toolchain/fasmw17332/SOURCE/LINUX/FASM.ASM
Normal file
@ -0,0 +1,341 @@
|
||||
|
||||
; flat assembler interface for Linux
|
||||
; Copyright (c) 1999-2022, Tomasz Grysztar.
|
||||
; All rights reserved.
|
||||
|
||||
format ELF executable 3
|
||||
entry start
|
||||
|
||||
segment readable executable
|
||||
|
||||
start:
|
||||
|
||||
mov [con_handle],1
|
||||
mov esi,_logo
|
||||
call display_string
|
||||
|
||||
mov [command_line],esp
|
||||
mov ecx,[esp]
|
||||
lea ebx,[esp+4+ecx*4+4]
|
||||
mov [environment],ebx
|
||||
call get_params
|
||||
jc information
|
||||
|
||||
call init_memory
|
||||
|
||||
mov esi,_memory_prefix
|
||||
call display_string
|
||||
mov eax,[memory_end]
|
||||
sub eax,[memory_start]
|
||||
add eax,[additional_memory_end]
|
||||
sub eax,[additional_memory]
|
||||
shr eax,10
|
||||
call display_number
|
||||
mov esi,_memory_suffix
|
||||
call display_string
|
||||
|
||||
mov eax,78
|
||||
mov ebx,buffer
|
||||
xor ecx,ecx
|
||||
int 0x80
|
||||
mov eax,dword [buffer]
|
||||
mov ecx,1000
|
||||
mul ecx
|
||||
mov ebx,eax
|
||||
mov eax,dword [buffer+4]
|
||||
div ecx
|
||||
add eax,ebx
|
||||
mov [start_time],eax
|
||||
|
||||
and [preprocessing_done],0
|
||||
call preprocessor
|
||||
or [preprocessing_done],-1
|
||||
call parser
|
||||
call assembler
|
||||
call formatter
|
||||
|
||||
call display_user_messages
|
||||
movzx eax,[current_pass]
|
||||
inc eax
|
||||
call display_number
|
||||
mov esi,_passes_suffix
|
||||
call display_string
|
||||
mov eax,78
|
||||
mov ebx,buffer
|
||||
xor ecx,ecx
|
||||
int 0x80
|
||||
mov eax,dword [buffer]
|
||||
mov ecx,1000
|
||||
mul ecx
|
||||
mov ebx,eax
|
||||
mov eax,dword [buffer+4]
|
||||
div ecx
|
||||
add eax,ebx
|
||||
sub eax,[start_time]
|
||||
jnc time_ok
|
||||
add eax,3600000
|
||||
time_ok:
|
||||
xor edx,edx
|
||||
mov ebx,100
|
||||
div ebx
|
||||
or eax,eax
|
||||
jz display_bytes_count
|
||||
xor edx,edx
|
||||
mov ebx,10
|
||||
div ebx
|
||||
push edx
|
||||
call display_number
|
||||
mov dl,'.'
|
||||
call display_character
|
||||
pop eax
|
||||
call display_number
|
||||
mov esi,_seconds_suffix
|
||||
call display_string
|
||||
display_bytes_count:
|
||||
mov eax,[written_size]
|
||||
call display_number
|
||||
mov esi,_bytes_suffix
|
||||
call display_string
|
||||
xor al,al
|
||||
jmp exit_program
|
||||
|
||||
information:
|
||||
mov esi,_usage
|
||||
call display_string
|
||||
mov al,1
|
||||
jmp exit_program
|
||||
|
||||
get_params:
|
||||
mov ebx,[command_line]
|
||||
mov [input_file],0
|
||||
mov [output_file],0
|
||||
mov [symbols_file],0
|
||||
mov [memory_setting],0
|
||||
mov [passes_limit],100
|
||||
mov ecx,[ebx]
|
||||
add ebx,8
|
||||
dec ecx
|
||||
jz bad_params
|
||||
mov [definitions_pointer],predefinitions
|
||||
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,'m'
|
||||
je memory_option
|
||||
cmp al,'M'
|
||||
je memory_option
|
||||
cmp al,'p'
|
||||
je passes_option
|
||||
cmp al,'P'
|
||||
je passes_option
|
||||
cmp al,'d'
|
||||
je definition_option
|
||||
cmp al,'D'
|
||||
je definition_option
|
||||
cmp al,'s'
|
||||
je symbols_option
|
||||
cmp al,'S'
|
||||
je symbols_option
|
||||
bad_params:
|
||||
stc
|
||||
ret
|
||||
memory_option:
|
||||
cmp byte [esi],0
|
||||
jne get_memory_setting
|
||||
dec ecx
|
||||
jz bad_params
|
||||
add ebx,4
|
||||
mov esi,[ebx]
|
||||
get_memory_setting:
|
||||
call get_option_value
|
||||
or edx,edx
|
||||
jz bad_params
|
||||
cmp edx,1 shl (32-10)
|
||||
jae bad_params
|
||||
mov [memory_setting],edx
|
||||
jmp next_param
|
||||
passes_option:
|
||||
cmp byte [esi],0
|
||||
jne get_passes_setting
|
||||
dec ecx
|
||||
jz bad_params
|
||||
add ebx,4
|
||||
mov esi,[ebx]
|
||||
get_passes_setting:
|
||||
call get_option_value
|
||||
or edx,edx
|
||||
jz bad_params
|
||||
cmp edx,10000h
|
||||
ja bad_params
|
||||
mov [passes_limit],dx
|
||||
next_param:
|
||||
add ebx,4
|
||||
dec ecx
|
||||
jnz get_param
|
||||
cmp [input_file],0
|
||||
je bad_params
|
||||
mov eax,[definitions_pointer]
|
||||
mov byte [eax],0
|
||||
mov [initial_definitions],predefinitions
|
||||
clc
|
||||
ret
|
||||
definition_option:
|
||||
cmp byte [esi],0
|
||||
jne get_definition
|
||||
dec ecx
|
||||
jz bad_params
|
||||
add ebx,4
|
||||
mov esi,[ebx]
|
||||
get_definition:
|
||||
push edi
|
||||
mov edi,[definitions_pointer]
|
||||
call convert_definition_option
|
||||
mov [definitions_pointer],edi
|
||||
pop edi
|
||||
jc bad_params
|
||||
jmp next_param
|
||||
symbols_option:
|
||||
cmp byte [esi],0
|
||||
jne get_symbols_setting
|
||||
dec ecx
|
||||
jz bad_params
|
||||
add ebx,4
|
||||
mov esi,[ebx]
|
||||
get_symbols_setting:
|
||||
mov [symbols_file],esi
|
||||
jmp next_param
|
||||
get_option_value:
|
||||
xor eax,eax
|
||||
mov edx,eax
|
||||
get_option_digit:
|
||||
lodsb
|
||||
cmp al,20h
|
||||
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
|
||||
convert_definition_option:
|
||||
mov edx,edi
|
||||
cmp edi,predefinitions+1000h
|
||||
jae bad_definition_option
|
||||
xor al,al
|
||||
stosb
|
||||
copy_definition_name:
|
||||
lodsb
|
||||
cmp al,'='
|
||||
je copy_definition_value
|
||||
cmp al,20h
|
||||
je bad_definition_option
|
||||
or al,al
|
||||
jz bad_definition_option
|
||||
cmp edi,predefinitions+1000h
|
||||
jae bad_definition_option
|
||||
stosb
|
||||
inc byte [edx]
|
||||
jnz copy_definition_name
|
||||
bad_definition_option:
|
||||
stc
|
||||
ret
|
||||
copy_definition_value:
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je definition_value_end
|
||||
or al,al
|
||||
jz definition_value_end
|
||||
cmp edi,predefinitions+1000h
|
||||
jae bad_definition_option
|
||||
stosb
|
||||
jmp copy_definition_value
|
||||
definition_value_end:
|
||||
dec esi
|
||||
cmp edi,predefinitions+1000h
|
||||
jae bad_definition_option
|
||||
xor al,al
|
||||
stosb
|
||||
clc
|
||||
ret
|
||||
|
||||
include 'system.inc'
|
||||
|
||||
include '..\version.inc'
|
||||
|
||||
_copyright db 'Copyright (c) 1999-2022, Tomasz Grysztar',0xA,0
|
||||
|
||||
_logo db 'flat assembler version ',VERSION_STRING,0
|
||||
_usage db 0xA
|
||||
db 'usage: fasm <source> [output]',0xA
|
||||
db 'optional settings:',0xA
|
||||
db ' -m <limit> set the limit in kilobytes for the available memory',0xA
|
||||
db ' -p <limit> set the maximum allowed number of passes',0xA
|
||||
db ' -d <name>=<value> define symbolic variable',0xA
|
||||
db ' -s <file> dump symbolic information for debugging',0xA
|
||||
db 0
|
||||
_memory_prefix db ' (',0
|
||||
_memory_suffix db ' kilobytes memory)',0xA,0
|
||||
_passes_suffix db ' passes, ',0
|
||||
_seconds_suffix db ' seconds, ',0
|
||||
_bytes_suffix db ' bytes.',0xA,0
|
||||
|
||||
include '..\errors.inc'
|
||||
include '..\symbdump.inc'
|
||||
include '..\preproce.inc'
|
||||
include '..\parser.inc'
|
||||
include '..\exprpars.inc'
|
||||
include '..\assemble.inc'
|
||||
include '..\exprcalc.inc'
|
||||
include '..\formats.inc'
|
||||
include '..\x86_64.inc'
|
||||
include '..\avx.inc'
|
||||
|
||||
include '..\tables.inc'
|
||||
include '..\messages.inc'
|
||||
|
||||
segment readable writeable
|
||||
|
||||
align 4
|
||||
|
||||
include '..\variable.inc'
|
||||
|
||||
command_line dd ?
|
||||
memory_setting dd ?
|
||||
definitions_pointer dd ?
|
||||
environment dd ?
|
||||
timestamp dq ?
|
||||
start_time dd ?
|
||||
con_handle dd ?
|
||||
displayed_count dd ?
|
||||
last_displayed db ?
|
||||
character db ?
|
||||
preprocessing_done db ?
|
||||
|
||||
predefinitions rb 1000h
|
||||
buffer rb 1000h
|
470
toolchain/fasmw17332/SOURCE/LINUX/SYSTEM.INC
Normal file
470
toolchain/fasmw17332/SOURCE/LINUX/SYSTEM.INC
Normal file
@ -0,0 +1,470 @@
|
||||
|
||||
; flat assembler interface for Linux
|
||||
; Copyright (c) 1999-2022, Tomasz Grysztar.
|
||||
; All rights reserved.
|
||||
|
||||
O_ACCMODE = 0003o
|
||||
O_RDONLY = 0000o
|
||||
O_WRONLY = 0001o
|
||||
O_RDWR = 0002o
|
||||
O_CREAT = 0100o
|
||||
O_EXCL = 0200o
|
||||
O_NOCTTY = 0400o
|
||||
O_TRUNC = 1000o
|
||||
O_APPEND = 2000o
|
||||
O_NONBLOCK = 4000o
|
||||
|
||||
S_ISUID = 4000o
|
||||
S_ISGID = 2000o
|
||||
S_ISVTX = 1000o
|
||||
S_IRUSR = 0400o
|
||||
S_IWUSR = 0200o
|
||||
S_IXUSR = 0100o
|
||||
S_IRGRP = 0040o
|
||||
S_IWGRP = 0020o
|
||||
S_IXGRP = 0010o
|
||||
S_IROTH = 0004o
|
||||
S_IWOTH = 0002o
|
||||
S_IXOTH = 0001o
|
||||
|
||||
init_memory:
|
||||
mov eax,esp
|
||||
and eax,not 0FFFh
|
||||
add eax,1000h-10000h
|
||||
mov [stack_limit],eax
|
||||
xor ebx,ebx
|
||||
mov eax,45
|
||||
int 0x80
|
||||
mov [additional_memory],eax
|
||||
mov ecx,[memory_setting]
|
||||
shl ecx,10
|
||||
jnz allocate_memory
|
||||
mov ecx,1000000h
|
||||
allocate_memory:
|
||||
mov ebx,[additional_memory]
|
||||
add ebx,ecx
|
||||
mov eax,45
|
||||
int 0x80
|
||||
mov [memory_end],eax
|
||||
sub eax,[additional_memory]
|
||||
shr eax,2
|
||||
add eax,[additional_memory]
|
||||
mov [additional_memory_end],eax
|
||||
mov [memory_start],eax
|
||||
ret
|
||||
|
||||
exit_program:
|
||||
movzx ebx,al
|
||||
mov eax,1
|
||||
int 0x80
|
||||
|
||||
get_environment_variable:
|
||||
mov ecx,esi
|
||||
mov ebx,[environment]
|
||||
next_variable:
|
||||
mov esi,[ebx]
|
||||
test esi,esi
|
||||
jz no_environment_variable
|
||||
add ebx,4
|
||||
compare_variable_names:
|
||||
mov edx,ecx
|
||||
compare_character:
|
||||
lodsb
|
||||
mov ah,[edx]
|
||||
inc edx
|
||||
cmp al,'='
|
||||
je end_of_variable_name
|
||||
or ah,ah
|
||||
jz next_variable
|
||||
sub ah,al
|
||||
jz compare_character
|
||||
cmp ah,20h
|
||||
jne next_variable
|
||||
cmp al,41h
|
||||
jb next_variable
|
||||
cmp al,5Ah
|
||||
jna compare_character
|
||||
jmp next_variable
|
||||
no_environment_variable:
|
||||
ret
|
||||
end_of_variable_name:
|
||||
or ah,ah
|
||||
jnz next_variable
|
||||
copy_variable_value:
|
||||
lodsb
|
||||
cmp edi,[memory_end]
|
||||
jae out_of_memory
|
||||
stosb
|
||||
or al,al
|
||||
jnz copy_variable_value
|
||||
dec edi
|
||||
ret
|
||||
|
||||
open:
|
||||
push esi edi ebp
|
||||
call adapt_path
|
||||
mov eax,5
|
||||
mov ebx,buffer
|
||||
mov ecx,O_RDONLY
|
||||
xor edx,edx
|
||||
int 0x80
|
||||
pop ebp edi esi
|
||||
test eax,eax
|
||||
js 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 out_of_memory
|
||||
ret
|
||||
create:
|
||||
push esi edi ebp edx
|
||||
call adapt_path
|
||||
mov ebx,buffer
|
||||
mov ecx,O_CREAT+O_TRUNC+O_WRONLY
|
||||
mov edx,S_IRUSR+S_IWUSR+S_IRGRP+S_IROTH
|
||||
pop eax
|
||||
cmp eax,[output_file]
|
||||
jne do_create
|
||||
cmp [output_format],5
|
||||
jne do_create
|
||||
bt [format_flags],0
|
||||
jnc do_create
|
||||
or edx,S_IXUSR+S_IXGRP+S_IXOTH
|
||||
do_create:
|
||||
mov eax,5
|
||||
int 0x80
|
||||
pop ebp edi esi
|
||||
test eax,eax
|
||||
js file_error
|
||||
mov ebx,eax
|
||||
clc
|
||||
ret
|
||||
close:
|
||||
mov eax,6
|
||||
int 0x80
|
||||
ret
|
||||
read:
|
||||
push ecx edx esi edi ebp
|
||||
mov eax,3
|
||||
xchg ecx,edx
|
||||
int 0x80
|
||||
pop ebp edi esi edx ecx
|
||||
test eax,eax
|
||||
js file_error
|
||||
cmp eax,ecx
|
||||
jne file_error
|
||||
clc
|
||||
ret
|
||||
file_error:
|
||||
stc
|
||||
ret
|
||||
write:
|
||||
push edx esi edi ebp
|
||||
mov eax,4
|
||||
xchg ecx,edx
|
||||
int 0x80
|
||||
pop ebp edi esi edx
|
||||
test eax,eax
|
||||
js file_error
|
||||
clc
|
||||
ret
|
||||
lseek:
|
||||
mov ecx,edx
|
||||
xor edx,edx
|
||||
mov dl,al
|
||||
mov eax,19
|
||||
int 0x80
|
||||
cmp eax,-1
|
||||
je file_error
|
||||
clc
|
||||
ret
|
||||
|
||||
display_string:
|
||||
push ebx
|
||||
mov edi,esi
|
||||
mov edx,esi
|
||||
or ecx,-1
|
||||
xor al,al
|
||||
repne scasb
|
||||
neg ecx
|
||||
sub ecx,2
|
||||
mov eax,4
|
||||
mov ebx,[con_handle]
|
||||
xchg ecx,edx
|
||||
int 0x80
|
||||
pop ebx
|
||||
ret
|
||||
display_character:
|
||||
push ebx
|
||||
mov [character],dl
|
||||
mov eax,4
|
||||
mov ebx,[con_handle]
|
||||
mov ecx,character
|
||||
mov edx,1
|
||||
int 0x80
|
||||
pop ebx
|
||||
ret
|
||||
display_number:
|
||||
push ebx
|
||||
mov ecx,1000000000
|
||||
xor edx,edx
|
||||
xor bl,bl
|
||||
display_loop:
|
||||
div ecx
|
||||
push edx
|
||||
cmp ecx,1
|
||||
je display_digit
|
||||
or bl,bl
|
||||
jnz display_digit
|
||||
or al,al
|
||||
jz digit_ok
|
||||
not bl
|
||||
display_digit:
|
||||
mov dl,al
|
||||
add dl,30h
|
||||
push ebx ecx
|
||||
call display_character
|
||||
pop ecx ebx
|
||||
digit_ok:
|
||||
mov eax,ecx
|
||||
xor edx,edx
|
||||
mov ecx,10
|
||||
div ecx
|
||||
mov ecx,eax
|
||||
pop eax
|
||||
or ecx,ecx
|
||||
jnz display_loop
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
display_user_messages:
|
||||
mov [displayed_count],0
|
||||
call show_display_buffer
|
||||
cmp [displayed_count],0
|
||||
je line_break_ok
|
||||
cmp [last_displayed],0Ah
|
||||
je line_break_ok
|
||||
mov dl,0Ah
|
||||
call display_character
|
||||
line_break_ok:
|
||||
ret
|
||||
display_block:
|
||||
jecxz block_displayed
|
||||
add [displayed_count],ecx
|
||||
mov al,[esi+ecx-1]
|
||||
mov [last_displayed],al
|
||||
push ebx
|
||||
mov eax,4
|
||||
mov ebx,[con_handle]
|
||||
mov edx,ecx
|
||||
mov ecx,esi
|
||||
int 0x80
|
||||
pop ebx
|
||||
block_displayed:
|
||||
ret
|
||||
|
||||
fatal_error:
|
||||
mov [con_handle],2
|
||||
mov esi,error_prefix
|
||||
call display_string
|
||||
pop esi
|
||||
call display_string
|
||||
mov esi,error_suffix
|
||||
call display_string
|
||||
mov al,0FFh
|
||||
jmp exit_program
|
||||
assembler_error:
|
||||
mov [con_handle],2
|
||||
call display_user_messages
|
||||
mov ebx,[current_line]
|
||||
test ebx,ebx
|
||||
jz display_error_message
|
||||
pushd 0
|
||||
get_error_lines:
|
||||
mov eax,[ebx]
|
||||
cmp byte [eax],0
|
||||
je get_next_error_line
|
||||
push ebx
|
||||
test byte [ebx+7],80h
|
||||
jz display_error_line
|
||||
mov edx,ebx
|
||||
find_definition_origin:
|
||||
mov edx,[edx+12]
|
||||
test byte [edx+7],80h
|
||||
jnz find_definition_origin
|
||||
push edx
|
||||
get_next_error_line:
|
||||
mov ebx,[ebx+8]
|
||||
jmp get_error_lines
|
||||
display_error_line:
|
||||
mov esi,[ebx]
|
||||
call display_string
|
||||
mov esi,line_number_start
|
||||
call display_string
|
||||
mov eax,[ebx+4]
|
||||
and eax,7FFFFFFFh
|
||||
call display_number
|
||||
mov dl,']'
|
||||
call display_character
|
||||
pop esi
|
||||
cmp ebx,esi
|
||||
je line_number_ok
|
||||
mov dl,20h
|
||||
call display_character
|
||||
push esi
|
||||
mov esi,[esi]
|
||||
movzx ecx,byte [esi]
|
||||
inc esi
|
||||
call display_block
|
||||
mov esi,line_number_start
|
||||
call display_string
|
||||
pop esi
|
||||
mov eax,[esi+4]
|
||||
and eax,7FFFFFFFh
|
||||
call display_number
|
||||
mov dl,']'
|
||||
call display_character
|
||||
line_number_ok:
|
||||
mov esi,line_data_start
|
||||
call display_string
|
||||
mov esi,ebx
|
||||
mov edx,[esi]
|
||||
call open
|
||||
mov al,2
|
||||
xor edx,edx
|
||||
call lseek
|
||||
mov edx,[esi+8]
|
||||
sub eax,edx
|
||||
jz line_data_displayed
|
||||
push eax
|
||||
xor al,al
|
||||
call lseek
|
||||
mov ecx,[esp]
|
||||
mov edx,[additional_memory]
|
||||
lea eax,[edx+ecx]
|
||||
cmp eax,[additional_memory_end]
|
||||
ja out_of_memory
|
||||
call read
|
||||
call close
|
||||
pop ecx
|
||||
mov esi,[additional_memory]
|
||||
get_line_data:
|
||||
mov al,[esi]
|
||||
cmp al,0Ah
|
||||
je display_line_data
|
||||
cmp al,0Dh
|
||||
je display_line_data
|
||||
cmp al,1Ah
|
||||
je display_line_data
|
||||
or al,al
|
||||
jz display_line_data
|
||||
inc esi
|
||||
loop get_line_data
|
||||
display_line_data:
|
||||
mov ecx,esi
|
||||
mov esi,[additional_memory]
|
||||
sub ecx,esi
|
||||
call display_block
|
||||
line_data_displayed:
|
||||
mov esi,lf
|
||||
call display_string
|
||||
pop ebx
|
||||
or ebx,ebx
|
||||
jnz display_error_line
|
||||
cmp [preprocessing_done],0
|
||||
je display_error_message
|
||||
mov esi,preprocessed_instruction_prefix
|
||||
call display_string
|
||||
mov esi,[current_line]
|
||||
add esi,16
|
||||
mov edi,[additional_memory]
|
||||
xor dl,dl
|
||||
convert_instruction:
|
||||
lodsb
|
||||
cmp al,1Ah
|
||||
je copy_symbol
|
||||
cmp al,22h
|
||||
je copy_symbol
|
||||
cmp al,3Bh
|
||||
je instruction_converted
|
||||
stosb
|
||||
or al,al
|
||||
jz instruction_converted
|
||||
xor dl,dl
|
||||
jmp convert_instruction
|
||||
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_instruction
|
||||
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_instruction
|
||||
instruction_converted:
|
||||
xor al,al
|
||||
stosb
|
||||
mov esi,[additional_memory]
|
||||
call display_string
|
||||
mov esi,lf
|
||||
call display_string
|
||||
display_error_message:
|
||||
mov esi,error_prefix
|
||||
call display_string
|
||||
pop esi
|
||||
call display_string
|
||||
mov esi,error_suffix
|
||||
call display_string
|
||||
mov al,2
|
||||
jmp exit_program
|
||||
|
||||
make_timestamp:
|
||||
mov eax,13
|
||||
mov ebx,timestamp
|
||||
int 0x80
|
||||
mov eax,dword [timestamp]
|
||||
mov edx,dword [timestamp+4]
|
||||
ret
|
||||
|
||||
error_prefix db 'error: ',0
|
||||
error_suffix db '.'
|
||||
lf db 0xA,0
|
||||
line_number_start db ' [',0
|
||||
line_data_start db ':',0xA,0
|
||||
preprocessed_instruction_prefix db 'processed: ',0
|
360
toolchain/fasmw17332/SOURCE/LINUX/X64/FASM.ASM
Normal file
360
toolchain/fasmw17332/SOURCE/LINUX/X64/FASM.ASM
Normal file
@ -0,0 +1,360 @@
|
||||
|
||||
; flat assembler interface for Linux x64
|
||||
; Copyright (c) 1999-2022, Tomasz Grysztar.
|
||||
; All rights reserved.
|
||||
|
||||
format ELF64 executable 3 at 400000h
|
||||
entry start
|
||||
|
||||
include 'modes.inc'
|
||||
|
||||
segment readable executable
|
||||
|
||||
start:
|
||||
|
||||
mov [con_handle],1
|
||||
mov esi,_logo
|
||||
call display_string
|
||||
|
||||
mov [command_line],rsp
|
||||
mov rcx,[rsp]
|
||||
lea rbx,[rsp+8+rcx*8+8]
|
||||
mov [environment],rbx
|
||||
call get_params
|
||||
jc information
|
||||
|
||||
call init_memory
|
||||
|
||||
mov esi,_memory_prefix
|
||||
call display_string
|
||||
mov eax,[memory_end]
|
||||
sub eax,[memory_start]
|
||||
add eax,[additional_memory_end]
|
||||
sub eax,[additional_memory]
|
||||
shr eax,10
|
||||
call display_number
|
||||
mov esi,_memory_suffix
|
||||
call display_string
|
||||
|
||||
mov eax,96
|
||||
mov edi,buffer
|
||||
xor esi,esi
|
||||
syscall
|
||||
mov eax,dword [buffer]
|
||||
mov ecx,1000
|
||||
mul ecx
|
||||
mov ebx,eax
|
||||
mov eax,dword [buffer+4]
|
||||
div ecx
|
||||
add eax,ebx
|
||||
mov [start_time],eax
|
||||
|
||||
and [preprocessing_done],0
|
||||
call preprocessor
|
||||
or [preprocessing_done],-1
|
||||
call parser
|
||||
call assembler
|
||||
call formatter
|
||||
|
||||
call display_user_messages
|
||||
movzx eax,[current_pass]
|
||||
inc eax
|
||||
call display_number
|
||||
mov esi,_passes_suffix
|
||||
call display_string
|
||||
mov eax,96
|
||||
mov edi,buffer
|
||||
xor esi,esi
|
||||
syscall
|
||||
mov eax,dword [buffer]
|
||||
mov ecx,1000
|
||||
mul ecx
|
||||
mov ebx,eax
|
||||
mov eax,dword [buffer+4]
|
||||
div ecx
|
||||
add eax,ebx
|
||||
sub eax,[start_time]
|
||||
jnc time_ok
|
||||
add eax,3600000
|
||||
time_ok:
|
||||
xor edx,edx
|
||||
mov ebx,100
|
||||
div ebx
|
||||
or eax,eax
|
||||
jz display_bytes_count
|
||||
xor edx,edx
|
||||
mov ebx,10
|
||||
div ebx
|
||||
push edx
|
||||
call display_number
|
||||
mov dl,'.'
|
||||
call display_character
|
||||
pop eax
|
||||
call display_number
|
||||
mov esi,_seconds_suffix
|
||||
call display_string
|
||||
display_bytes_count:
|
||||
mov eax,[written_size]
|
||||
call display_number
|
||||
mov esi,_bytes_suffix
|
||||
call display_string
|
||||
xor al,al
|
||||
jmp exit_program
|
||||
|
||||
information:
|
||||
mov esi,_usage
|
||||
call display_string
|
||||
mov al,1
|
||||
jmp exit_program
|
||||
|
||||
get_params:
|
||||
mov rbx,[command_line]
|
||||
mov [input_file],0
|
||||
mov [output_file],0
|
||||
mov [symbols_file],0
|
||||
mov [memory_setting],0
|
||||
mov [passes_limit],100
|
||||
mov rcx,[rbx]
|
||||
add rbx,8*2
|
||||
dec rcx
|
||||
jz bad_params
|
||||
mov [definitions_pointer],predefinitions
|
||||
mov [path_pointer],paths
|
||||
get_param:
|
||||
mov rsi,[rbx]
|
||||
mov al,[rsi]
|
||||
cmp al,'-'
|
||||
je option_param
|
||||
cmp [input_file],0
|
||||
jne get_output_file
|
||||
call collect_path
|
||||
mov [input_file],edx
|
||||
jmp next_param
|
||||
get_output_file:
|
||||
cmp [output_file],0
|
||||
jne bad_params
|
||||
call collect_path
|
||||
mov [output_file],edx
|
||||
jmp next_param
|
||||
option_param:
|
||||
inc rsi
|
||||
lodsb
|
||||
cmp al,'m'
|
||||
je memory_option
|
||||
cmp al,'M'
|
||||
je memory_option
|
||||
cmp al,'p'
|
||||
je passes_option
|
||||
cmp al,'P'
|
||||
je passes_option
|
||||
cmp al,'d'
|
||||
je definition_option
|
||||
cmp al,'D'
|
||||
je definition_option
|
||||
cmp al,'s'
|
||||
je symbols_option
|
||||
cmp al,'S'
|
||||
je symbols_option
|
||||
bad_params:
|
||||
stc
|
||||
ret
|
||||
memory_option:
|
||||
cmp byte [rsi],0
|
||||
jne get_memory_setting
|
||||
dec rcx
|
||||
jz bad_params
|
||||
add rbx,8
|
||||
mov rsi,[rbx]
|
||||
get_memory_setting:
|
||||
call get_option_value
|
||||
or edx,edx
|
||||
jz bad_params
|
||||
cmp edx,1 shl (32-10)
|
||||
jae bad_params
|
||||
mov [memory_setting],edx
|
||||
jmp next_param
|
||||
passes_option:
|
||||
cmp byte [rsi],0
|
||||
jne get_passes_setting
|
||||
dec rcx
|
||||
jz bad_params
|
||||
add rbx,8
|
||||
mov rsi,[rbx]
|
||||
get_passes_setting:
|
||||
call get_option_value
|
||||
or edx,edx
|
||||
jz bad_params
|
||||
cmp edx,10000h
|
||||
ja bad_params
|
||||
mov [passes_limit],dx
|
||||
next_param:
|
||||
add rbx,8
|
||||
dec rcx
|
||||
jnz get_param
|
||||
cmp [input_file],0
|
||||
je bad_params
|
||||
mov eax,[definitions_pointer]
|
||||
mov byte [eax],0
|
||||
mov [initial_definitions],predefinitions
|
||||
clc
|
||||
ret
|
||||
definition_option:
|
||||
cmp byte [rsi],0
|
||||
jne get_definition
|
||||
dec rcx
|
||||
jz bad_params
|
||||
add rbx,8
|
||||
mov rsi,[rbx]
|
||||
get_definition:
|
||||
mov r12d,edi
|
||||
mov edi,[definitions_pointer]
|
||||
call convert_definition_option
|
||||
mov [definitions_pointer],edi
|
||||
mov edi,r12d
|
||||
jc bad_params
|
||||
jmp next_param
|
||||
symbols_option:
|
||||
cmp byte [rsi],0
|
||||
jne get_symbols_setting
|
||||
dec rcx
|
||||
jz bad_params
|
||||
add rbx,8
|
||||
mov rsi,[rbx]
|
||||
get_symbols_setting:
|
||||
call collect_path
|
||||
mov [symbols_file],edx
|
||||
jmp next_param
|
||||
get_option_value:
|
||||
xor eax,eax
|
||||
mov edx,eax
|
||||
get_option_digit:
|
||||
lodsb
|
||||
cmp al,20h
|
||||
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 rsi
|
||||
clc
|
||||
ret
|
||||
invalid_option_value:
|
||||
stc
|
||||
ret
|
||||
convert_definition_option:
|
||||
mov edx,edi
|
||||
cmp edi,predefinitions+1000h
|
||||
jae bad_definition_option
|
||||
xor al,al
|
||||
stosb
|
||||
copy_definition_name:
|
||||
lodsb
|
||||
cmp al,'='
|
||||
je copy_definition_value
|
||||
cmp al,20h
|
||||
je bad_definition_option
|
||||
or al,al
|
||||
jz bad_definition_option
|
||||
cmp edi,predefinitions+1000h
|
||||
jae bad_definition_option
|
||||
stosb
|
||||
inc byte [edx]
|
||||
jnz copy_definition_name
|
||||
bad_definition_option:
|
||||
stc
|
||||
ret
|
||||
copy_definition_value:
|
||||
lodsb
|
||||
cmp al,20h
|
||||
je definition_value_end
|
||||
or al,al
|
||||
jz definition_value_end
|
||||
cmp edi,predefinitions+1000h
|
||||
jae bad_definition_option
|
||||
stosb
|
||||
jmp copy_definition_value
|
||||
definition_value_end:
|
||||
dec rsi
|
||||
cmp edi,predefinitions+1000h
|
||||
jae bad_definition_option
|
||||
xor al,al
|
||||
stosb
|
||||
clc
|
||||
ret
|
||||
collect_path:
|
||||
mov edi,[path_pointer]
|
||||
mov edx,edi
|
||||
copy_path_to_low_memory:
|
||||
lodsb
|
||||
stosb
|
||||
test al,al
|
||||
jnz copy_path_to_low_memory
|
||||
mov [path_pointer],edi
|
||||
retn
|
||||
|
||||
include 'system.inc'
|
||||
|
||||
include '..\..\version.inc'
|
||||
|
||||
_copyright db 'Copyright (c) 1999-2022, Tomasz Grysztar',0xA,0
|
||||
|
||||
_logo db 'flat assembler version ',VERSION_STRING,0
|
||||
_usage db 0xA
|
||||
db 'usage: fasm <source> [output]',0xA
|
||||
db 'optional settings:',0xA
|
||||
db ' -m <limit> set the limit in kilobytes for the available memory',0xA
|
||||
db ' -p <limit> set the maximum allowed number of passes',0xA
|
||||
db ' -d <name>=<value> define symbolic variable',0xA
|
||||
db ' -s <file> dump symbolic information for debugging',0xA
|
||||
db 0
|
||||
_memory_prefix db ' (',0
|
||||
_memory_suffix db ' kilobytes memory, x64)',0xA,0
|
||||
_passes_suffix db ' passes, ',0
|
||||
_seconds_suffix db ' seconds, ',0
|
||||
_bytes_suffix db ' bytes.',0xA,0
|
||||
_no_low_memory db 'failed to allocate memory within 32-bit addressing range',0
|
||||
|
||||
include '..\..\errors.inc'
|
||||
include '..\..\symbdump.inc'
|
||||
include '..\..\preproce.inc'
|
||||
include '..\..\parser.inc'
|
||||
include '..\..\exprpars.inc'
|
||||
include '..\..\assemble.inc'
|
||||
include '..\..\exprcalc.inc'
|
||||
include '..\..\x86_64.inc'
|
||||
include '..\..\avx.inc'
|
||||
include '..\..\formats.inc'
|
||||
|
||||
include '..\..\tables.inc'
|
||||
include '..\..\messages.inc'
|
||||
|
||||
segment readable writeable
|
||||
|
||||
align 4
|
||||
|
||||
include '..\..\variable.inc'
|
||||
|
||||
command_line dq ?
|
||||
memory_setting dd ?
|
||||
path_pointer dd ?
|
||||
definitions_pointer dd ?
|
||||
environment dq ?
|
||||
timestamp dq ?
|
||||
start_time dd ?
|
||||
con_handle dd ?
|
||||
displayed_count dd ?
|
||||
last_displayed db ?
|
||||
character db ?
|
||||
preprocessing_done db ?
|
||||
|
||||
buffer rb 1000h
|
||||
predefinitions rb 1000h
|
||||
paths rb 10000h
|
186
toolchain/fasmw17332/SOURCE/LINUX/X64/MODES.INC
Normal file
186
toolchain/fasmw17332/SOURCE/LINUX/X64/MODES.INC
Normal file
@ -0,0 +1,186 @@
|
||||
|
||||
; flat assembler interface for Linux x64
|
||||
; Copyright (c) 1999-2022, Tomasz Grysztar.
|
||||
; All rights reserved.
|
||||
|
||||
esp equ +rsp
|
||||
|
||||
macro pushD [arg]
|
||||
{
|
||||
common
|
||||
local offset,total
|
||||
offset = 0
|
||||
lea rsp,[rsp-total]
|
||||
forward
|
||||
offset = offset + 4
|
||||
if arg eqtype eax
|
||||
mov dword [rsp+total-offset],arg
|
||||
else
|
||||
mov r8d,dword arg
|
||||
mov [rsp+total-offset],r8d
|
||||
end if
|
||||
common
|
||||
total = offset
|
||||
}
|
||||
|
||||
macro popD [arg]
|
||||
{
|
||||
common
|
||||
local offset
|
||||
offset = 0
|
||||
forward
|
||||
if arg eqtype [mem]
|
||||
mov r8d,[rsp+offset]
|
||||
mov dword arg,r8d
|
||||
else
|
||||
mov arg,dword [rsp+offset]
|
||||
end if
|
||||
offset = offset + 4
|
||||
common
|
||||
lea rsp,[rsp+offset]
|
||||
}
|
||||
|
||||
macro add dest,src
|
||||
{
|
||||
if dest eq esp
|
||||
add rsp,src
|
||||
else
|
||||
add dest,src
|
||||
end if
|
||||
}
|
||||
|
||||
macro mov dest,src
|
||||
{
|
||||
if src eq esp
|
||||
mov dest,ESP
|
||||
else
|
||||
mov dest,src
|
||||
end if
|
||||
}
|
||||
|
||||
macro cmp dest,src
|
||||
{
|
||||
if dest eq esp
|
||||
cmp ESP,src
|
||||
else
|
||||
cmp dest,src
|
||||
end if
|
||||
}
|
||||
|
||||
macro use32
|
||||
{
|
||||
|
||||
macro push args
|
||||
\{
|
||||
local list,arg,status
|
||||
define list
|
||||
define arg
|
||||
irps sym, args \\{
|
||||
define status
|
||||
match =dword, sym \\\{
|
||||
define status :
|
||||
\\\}
|
||||
match [any, status arg sym \\\{
|
||||
define arg [any
|
||||
match [mem], arg \\\\{
|
||||
match previous, list \\\\\{ define list previous,[mem] \\\\\}
|
||||
match , list \\\\\{ define list [mem] \\\\\}
|
||||
define arg
|
||||
\\\\}
|
||||
define status :
|
||||
\\\}
|
||||
match [, status arg sym \\\{
|
||||
define arg [
|
||||
define status :
|
||||
\\\}
|
||||
match , status \\\{
|
||||
match previous, list \\\\{ define list previous,sym \\\\}
|
||||
match , list \\\\{ define list sym \\\\}
|
||||
\\\}
|
||||
\\}
|
||||
match arg, list \\{ pushD arg \\}
|
||||
\}
|
||||
|
||||
macro pop args
|
||||
\{
|
||||
local list,arg,status
|
||||
define list
|
||||
define arg
|
||||
irps sym, args \\{
|
||||
define status
|
||||
match =dword, sym \\\{
|
||||
define status :
|
||||
\\\}
|
||||
match [any, status arg sym \\\{
|
||||
define arg [any
|
||||
match [mem], arg \\\\{
|
||||
match previous, list \\\\\{ define list previous,[mem] \\\\\}
|
||||
match , list \\\\\{ define list [mem] \\\\\}
|
||||
define arg
|
||||
\\\\}
|
||||
define status :
|
||||
\\\}
|
||||
match [, status arg sym \\\{
|
||||
define arg [
|
||||
define status :
|
||||
\\\}
|
||||
match , status \\\{
|
||||
match previous, list \\\\{ define list previous,sym \\\\}
|
||||
match , list \\\\{ define list sym \\\\}
|
||||
\\\}
|
||||
\\}
|
||||
match arg, list \\{ popD arg \\}
|
||||
\}
|
||||
|
||||
macro jmp arg
|
||||
\{
|
||||
if arg eq near eax
|
||||
jmp near rax
|
||||
else if arg eq near edx
|
||||
jmp near rdx
|
||||
else if arg eqtype [mem]
|
||||
mov r8d,arg
|
||||
jmp near r8
|
||||
else
|
||||
jmp arg
|
||||
end if
|
||||
\}
|
||||
|
||||
macro call arg
|
||||
\{
|
||||
if 1
|
||||
match =near =dword [mem], arg \\{
|
||||
mov r8d,[mem]
|
||||
call near r8
|
||||
else
|
||||
\\}
|
||||
call arg
|
||||
end if
|
||||
\}
|
||||
|
||||
macro salc ; for fasm's core it does not need to preserve flags
|
||||
\{
|
||||
setc al
|
||||
neg al
|
||||
\}
|
||||
|
||||
macro jcxz target ; for fasm's core it does not need to preserve flags
|
||||
\{
|
||||
test cx,cx
|
||||
jz target
|
||||
\}
|
||||
|
||||
use64
|
||||
|
||||
}
|
||||
|
||||
macro use16
|
||||
{
|
||||
|
||||
purge push,pop,jmp,call,salc,jcxz
|
||||
|
||||
use16
|
||||
|
||||
}
|
||||
|
||||
use32
|
548
toolchain/fasmw17332/SOURCE/LINUX/X64/SYSTEM.INC
Normal file
548
toolchain/fasmw17332/SOURCE/LINUX/X64/SYSTEM.INC
Normal file
@ -0,0 +1,548 @@
|
||||
|
||||
; flat assembler interface for Linux x64
|
||||
; Copyright (c) 1999-2022, Tomasz Grysztar.
|
||||
; All rights reserved.
|
||||
|
||||
O_ACCMODE = 0003o
|
||||
O_RDONLY = 0000o
|
||||
O_WRONLY = 0001o
|
||||
O_RDWR = 0002o
|
||||
O_CREAT = 0100o
|
||||
O_EXCL = 0200o
|
||||
O_NOCTTY = 0400o
|
||||
O_TRUNC = 1000o
|
||||
O_APPEND = 2000o
|
||||
O_NONBLOCK = 4000o
|
||||
|
||||
S_ISUID = 4000o
|
||||
S_ISGID = 2000o
|
||||
S_ISVTX = 1000o
|
||||
S_IRUSR = 0400o
|
||||
S_IWUSR = 0200o
|
||||
S_IXUSR = 0100o
|
||||
S_IRGRP = 0040o
|
||||
S_IWGRP = 0020o
|
||||
S_IXGRP = 0010o
|
||||
S_IROTH = 0004o
|
||||
S_IWOTH = 0002o
|
||||
S_IXOTH = 0001o
|
||||
|
||||
init_memory:
|
||||
mov eax,esp
|
||||
and eax,not 0FFFh
|
||||
add eax,1000h-10000h
|
||||
mov [stack_limit],eax
|
||||
xor edi,edi
|
||||
mov eax,12
|
||||
syscall
|
||||
mov ecx,[memory_setting]
|
||||
shl ecx,10
|
||||
jnz allocate_memory
|
||||
mov ecx,1000000h
|
||||
allocate_memory:
|
||||
mov r9d,eax
|
||||
cmp rax,r9
|
||||
jne high_brk
|
||||
mov [additional_memory],eax
|
||||
lea edi,[eax+ecx]
|
||||
mov eax,12
|
||||
syscall
|
||||
mov r9d,eax
|
||||
cmp rax,r9
|
||||
jne no_low_memory
|
||||
mov [memory_end],eax
|
||||
sub eax,[additional_memory]
|
||||
shr eax,2
|
||||
add eax,[additional_memory]
|
||||
mov [additional_memory_end],eax
|
||||
mov [memory_start],eax
|
||||
ret
|
||||
high_brk:
|
||||
xor r9d,r9d
|
||||
or r8,-1
|
||||
mov r10d,62h ; MAP_PRIVATE + MAP_ANONYMOUS + MAP_32BIT
|
||||
mov edx,3 ; PROT_READ + PROT_WRITE
|
||||
mov esi,ecx
|
||||
xor edi,edi
|
||||
mov eax,9 ; sys_mmap
|
||||
syscall
|
||||
cmp eax,-1
|
||||
je mmap_with_hint
|
||||
mov r9d,eax
|
||||
cmp rax,r9
|
||||
jne mmap_unusable
|
||||
add r9d,esi
|
||||
jnc mmap_ok
|
||||
mmap_unusable:
|
||||
mov rdi,rax
|
||||
mov eax,11 ; sys_munmap
|
||||
syscall
|
||||
mmap_with_hint:
|
||||
mov r10d,22h ; MAP_PRIVATE + MAP_ANONYMOUS
|
||||
mov edx,3 ; PROT_READ + PROT_WRITE
|
||||
mov edi,480000h
|
||||
mov eax,9 ; sys_mmap
|
||||
syscall
|
||||
cmp eax,-1
|
||||
je no_low_memory
|
||||
mov r9d,eax
|
||||
cmp rax,r9
|
||||
jne no_low_memory
|
||||
add r9d,esi
|
||||
jnc mmap_ok
|
||||
no_low_memory:
|
||||
mov esi,lf
|
||||
call display_string
|
||||
push _no_low_memory
|
||||
jmp fatal_error
|
||||
mmap_ok:
|
||||
mov [additional_memory],eax
|
||||
lea edi,[eax+esi]
|
||||
mov [memory_end],edi
|
||||
shr esi,2
|
||||
add eax,esi
|
||||
mov [additional_memory_end],eax
|
||||
mov [memory_start],eax
|
||||
ret
|
||||
|
||||
exit_program:
|
||||
movzx edi,al
|
||||
mov eax,60
|
||||
syscall
|
||||
|
||||
get_environment_variable:
|
||||
mov ecx,esi
|
||||
mov rbx,[environment]
|
||||
next_variable:
|
||||
mov rsi,[rbx]
|
||||
test rsi,rsi
|
||||
jz no_environment_variable
|
||||
add rbx,8
|
||||
compare_variable_names:
|
||||
mov edx,ecx
|
||||
compare_character:
|
||||
lodsb
|
||||
mov ah,[edx]
|
||||
inc edx
|
||||
cmp al,'='
|
||||
je end_of_variable_name
|
||||
or ah,ah
|
||||
jz next_variable
|
||||
sub ah,al
|
||||
jz compare_character
|
||||
cmp ah,20h
|
||||
jne next_variable
|
||||
cmp al,41h
|
||||
jb next_variable
|
||||
cmp al,5Ah
|
||||
jna compare_character
|
||||
jmp next_variable
|
||||
no_environment_variable:
|
||||
ret
|
||||
end_of_variable_name:
|
||||
or ah,ah
|
||||
jnz next_variable
|
||||
copy_variable_value:
|
||||
lodsb
|
||||
cmp edi,[memory_end]
|
||||
jae out_of_memory
|
||||
stosb
|
||||
or al,al
|
||||
jnz copy_variable_value
|
||||
dec edi
|
||||
ret
|
||||
|
||||
open:
|
||||
mov r12d,esi
|
||||
mov r13d,edi
|
||||
call adapt_path
|
||||
mov eax,2
|
||||
mov edi,buffer
|
||||
mov esi,O_RDONLY
|
||||
xor edx,edx
|
||||
syscall
|
||||
mov esi,r12d
|
||||
mov edi,r13d
|
||||
test eax,eax
|
||||
js 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 out_of_memory
|
||||
ret
|
||||
create:
|
||||
mov r12d,esi
|
||||
mov r13d,edi
|
||||
mov r15d,edx
|
||||
call adapt_path
|
||||
mov edi,buffer
|
||||
mov esi,O_CREAT+O_TRUNC+O_WRONLY
|
||||
mov edx,S_IRUSR+S_IWUSR+S_IRGRP+S_IROTH
|
||||
cmp r15d,[output_file]
|
||||
jne do_create
|
||||
cmp [output_format],5
|
||||
jne do_create
|
||||
bt [format_flags],0
|
||||
jnc do_create
|
||||
or edx,S_IXUSR+S_IXGRP+S_IXOTH
|
||||
do_create:
|
||||
mov eax,2
|
||||
syscall
|
||||
mov esi,r12d
|
||||
mov edi,r13d
|
||||
test eax,eax
|
||||
js file_error
|
||||
mov ebx,eax
|
||||
clc
|
||||
ret
|
||||
close:
|
||||
mov r13d,edi
|
||||
mov edi,ebx
|
||||
mov eax,3
|
||||
syscall
|
||||
mov edi,r13d
|
||||
ret
|
||||
read:
|
||||
mov r12d,esi
|
||||
mov r13d,edi
|
||||
mov eax,0
|
||||
mov edi,ebx
|
||||
mov esi,edx
|
||||
mov edx,ecx
|
||||
syscall
|
||||
mov ecx,edx
|
||||
mov edx,esi
|
||||
mov esi,r12d
|
||||
mov edi,r13d
|
||||
test eax,eax
|
||||
js file_error
|
||||
cmp eax,ecx
|
||||
jne file_error
|
||||
clc
|
||||
ret
|
||||
file_error:
|
||||
stc
|
||||
ret
|
||||
write:
|
||||
mov r12d,esi
|
||||
mov r13d,edi
|
||||
mov eax,1
|
||||
mov edi,ebx
|
||||
mov esi,edx
|
||||
mov edx,ecx
|
||||
syscall
|
||||
mov ecx,edx
|
||||
mov edx,esi
|
||||
mov esi,r12d
|
||||
mov edi,r13d
|
||||
test eax,eax
|
||||
js file_error
|
||||
clc
|
||||
ret
|
||||
lseek:
|
||||
mov r12d,esi
|
||||
mov r13d,edi
|
||||
mov edi,ebx
|
||||
mov esi,edx
|
||||
xor edx,edx
|
||||
mov dl,al
|
||||
mov eax,8
|
||||
syscall
|
||||
mov esi,r12d
|
||||
mov edi,r13d
|
||||
cmp eax,-1
|
||||
je file_error
|
||||
clc
|
||||
ret
|
||||
|
||||
display_string:
|
||||
mov edi,esi
|
||||
mov edx,esi
|
||||
or ecx,-1
|
||||
xor al,al
|
||||
repne scasb
|
||||
neg ecx
|
||||
sub ecx,2
|
||||
mov eax,1
|
||||
mov edi,[con_handle]
|
||||
mov esi,edx
|
||||
mov edx,ecx
|
||||
syscall
|
||||
ret
|
||||
display_character:
|
||||
mov r12d,esi
|
||||
mov r13d,edi
|
||||
mov [character],dl
|
||||
mov eax,1
|
||||
mov edi,[con_handle]
|
||||
mov esi,character
|
||||
mov edx,1
|
||||
syscall
|
||||
mov esi,r12d
|
||||
mov edi,r13d
|
||||
ret
|
||||
display_number:
|
||||
mov r14d,ebx
|
||||
mov ecx,1000000000
|
||||
xor edx,edx
|
||||
xor bl,bl
|
||||
display_loop:
|
||||
div ecx
|
||||
mov r15d,edx
|
||||
cmp ecx,1
|
||||
je display_digit
|
||||
or bl,bl
|
||||
jnz display_digit
|
||||
or al,al
|
||||
jz digit_ok
|
||||
not bl
|
||||
display_digit:
|
||||
mov dl,al
|
||||
add dl,30h
|
||||
mov r10d,ecx
|
||||
call display_character
|
||||
mov ecx,r10d
|
||||
digit_ok:
|
||||
mov eax,ecx
|
||||
xor edx,edx
|
||||
mov ecx,10
|
||||
div ecx
|
||||
mov ecx,eax
|
||||
mov eax,r15d
|
||||
or ecx,ecx
|
||||
jnz display_loop
|
||||
mov ebx,r14d
|
||||
ret
|
||||
|
||||
display_user_messages:
|
||||
mov [displayed_count],0
|
||||
call show_display_buffer
|
||||
cmp [displayed_count],0
|
||||
je line_break_ok
|
||||
cmp [last_displayed],0Ah
|
||||
je line_break_ok
|
||||
mov dl,0Ah
|
||||
call display_character
|
||||
line_break_ok:
|
||||
ret
|
||||
display_block:
|
||||
jecxz block_displayed
|
||||
add [displayed_count],ecx
|
||||
mov al,[esi+ecx-1]
|
||||
mov [last_displayed],al
|
||||
mov r13d,edi
|
||||
mov eax,1
|
||||
mov edi,[con_handle]
|
||||
mov edx,ecx
|
||||
syscall
|
||||
mov edi,r13d
|
||||
block_displayed:
|
||||
ret
|
||||
|
||||
fatal_error:
|
||||
mov [con_handle],2
|
||||
mov esi,error_prefix
|
||||
call display_string
|
||||
pop esi
|
||||
call display_string
|
||||
mov esi,error_suffix
|
||||
call display_string
|
||||
mov al,0FFh
|
||||
jmp exit_program
|
||||
assembler_error:
|
||||
mov [con_handle],2
|
||||
call display_user_messages
|
||||
mov ebx,[current_line]
|
||||
test ebx,ebx
|
||||
jz display_error_message
|
||||
push dword 0
|
||||
get_error_lines:
|
||||
mov eax,[ebx]
|
||||
cmp byte [eax],0
|
||||
je get_next_error_line
|
||||
push ebx
|
||||
test byte [ebx+7],80h
|
||||
jz display_error_line
|
||||
mov edx,ebx
|
||||
find_definition_origin:
|
||||
mov edx,[edx+12]
|
||||
test byte [edx+7],80h
|
||||
jnz find_definition_origin
|
||||
push edx
|
||||
get_next_error_line:
|
||||
mov ebx,[ebx+8]
|
||||
jmp get_error_lines
|
||||
display_error_line:
|
||||
mov esi,[ebx]
|
||||
call display_string
|
||||
mov esi,line_number_start
|
||||
call display_string
|
||||
mov eax,[ebx+4]
|
||||
and eax,7FFFFFFFh
|
||||
call display_number
|
||||
mov dl,']'
|
||||
call display_character
|
||||
pop esi
|
||||
cmp ebx,esi
|
||||
je line_number_ok
|
||||
mov dl,20h
|
||||
call display_character
|
||||
push esi
|
||||
mov esi,[esi]
|
||||
movzx ecx,byte [esi]
|
||||
inc esi
|
||||
call display_block
|
||||
mov esi,line_number_start
|
||||
call display_string
|
||||
pop esi
|
||||
mov eax,[esi+4]
|
||||
and eax,7FFFFFFFh
|
||||
call display_number
|
||||
mov dl,']'
|
||||
call display_character
|
||||
line_number_ok:
|
||||
mov esi,line_data_start
|
||||
call display_string
|
||||
mov esi,ebx
|
||||
mov edx,[esi]
|
||||
call open
|
||||
mov al,2
|
||||
xor edx,edx
|
||||
call lseek
|
||||
mov edx,[esi+8]
|
||||
sub eax,edx
|
||||
jz line_data_displayed
|
||||
push eax
|
||||
xor al,al
|
||||
call lseek
|
||||
mov ecx,[esp]
|
||||
mov edx,[additional_memory]
|
||||
lea eax,[edx+ecx]
|
||||
cmp eax,[additional_memory_end]
|
||||
ja out_of_memory
|
||||
call read
|
||||
call close
|
||||
pop ecx
|
||||
mov esi,[additional_memory]
|
||||
get_line_data:
|
||||
mov al,[esi]
|
||||
cmp al,0Ah
|
||||
je display_line_data
|
||||
cmp al,0Dh
|
||||
je display_line_data
|
||||
cmp al,1Ah
|
||||
je display_line_data
|
||||
or al,al
|
||||
jz display_line_data
|
||||
inc esi
|
||||
loop get_line_data
|
||||
display_line_data:
|
||||
mov ecx,esi
|
||||
mov esi,[additional_memory]
|
||||
sub ecx,esi
|
||||
call display_block
|
||||
line_data_displayed:
|
||||
mov esi,lf
|
||||
call display_string
|
||||
pop ebx
|
||||
or ebx,ebx
|
||||
jnz display_error_line
|
||||
cmp [preprocessing_done],0
|
||||
je display_error_message
|
||||
mov esi,preprocessed_instruction_prefix
|
||||
call display_string
|
||||
mov esi,[current_line]
|
||||
add esi,16
|
||||
mov edi,[additional_memory]
|
||||
xor dl,dl
|
||||
convert_instruction:
|
||||
lodsb
|
||||
cmp al,1Ah
|
||||
je copy_symbol
|
||||
cmp al,22h
|
||||
je copy_symbol
|
||||
cmp al,3Bh
|
||||
je instruction_converted
|
||||
stosb
|
||||
or al,al
|
||||
jz instruction_converted
|
||||
xor dl,dl
|
||||
jmp convert_instruction
|
||||
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_instruction
|
||||
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_instruction
|
||||
instruction_converted:
|
||||
xor al,al
|
||||
stosb
|
||||
mov esi,[additional_memory]
|
||||
call display_string
|
||||
mov esi,lf
|
||||
call display_string
|
||||
display_error_message:
|
||||
mov esi,error_prefix
|
||||
call display_string
|
||||
pop esi
|
||||
call display_string
|
||||
mov esi,error_suffix
|
||||
call display_string
|
||||
mov al,2
|
||||
jmp exit_program
|
||||
|
||||
make_timestamp:
|
||||
mov r13d,edi
|
||||
mov eax,201
|
||||
mov edi,timestamp
|
||||
syscall
|
||||
mov eax,dword [timestamp]
|
||||
mov edx,dword [timestamp+4]
|
||||
mov edi,r13d
|
||||
ret
|
||||
|
||||
error_prefix db 'error: ',0
|
||||
error_suffix db '.'
|
||||
lf db 0xA,0
|
||||
line_number_start db ' [',0
|
||||
line_data_start db ':',0xA,0
|
||||
preprocessed_instruction_prefix db 'processed: ',0
|
Reference in New Issue
Block a user