+++ /dev/null
-
-; 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
+++ /dev/null
-
-; 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