fasm/SOURCE/ASSEMBLE.INC
Tomasz Grysztar 2edc86c9b2 release 1.44
2003-01-19 12:00:00 +00:00

1624 lines
29 KiB
PHP

; flat assembler core
; Copyright (c) 1999-2003, Tomasz Grysztar.
; All rights reserved.
assembler:
mov ecx,[memory_end]
mov edi,ecx
sub ecx,[labels_list]
shr ecx,3
imul ecx,20
sub edi,ecx
cmp edi,[code_start]
jbe out_of_memory
mov [labels_list],edi
shr ecx,2
xor eax,eax
rep stos dword [edi]
mov [stub_size],eax
mov [number_of_sections],eax
mov [current_pass],al
mov [times_working],al
assembler_loop:
mov eax,[labels_list]
mov [display_buffer],eax
mov eax,[additional_memory]
mov [free_additional_memory],eax
mov eax,[additional_memory_end]
mov [structures_buffer],eax
mov [next_pass_needed],0
mov [code_type],16
mov [reloc_labels],0
mov [virtual_data],0
mov esi,[source_start]
mov edi,[code_start]
xor eax,eax
mov [output_format],al
mov [org_origin],edi
mov [org_start],edi
mov [org_sib],eax
mov [error_line],eax
mov [counter],eax
mov [format_flags],eax
mov [number_of_relocations],eax
mov [undefined_data_end],eax
pass_loop:
call assemble_line
jnc pass_loop
mov eax,[structures_buffer]
cmp eax,[additional_memory_end]
jne unexpected_end_of_file
call close_pass
cmp [next_pass_needed],0
je check_pass
next_pass:
inc [current_pass]
cmp [current_pass],0
je code_cannot_be_generated
jmp assembler_loop
pass_error:
mov [current_line],eax
jmp near [error]
check_pass:
mov eax,[labels_list]
check_symbols:
cmp eax,[memory_end]
jae symbols_checked
test byte [eax+8],8
jz symbol_defined_ok
mov cl,[current_pass]
cmp cl,[eax+16]
jne symbol_defined_ok
test byte [eax+8],1
jz symbol_defined_ok
sub cl,[eax+9]
cmp cl,1
jne symbol_defined_ok
and byte [eax+8],not 1
or [next_pass_needed],-1
symbol_defined_ok:
test byte [eax+8],10h
jz check_next_symbol
mov cl,[current_pass]
cmp cl,[eax+17]
jne check_next_symbol
test byte [eax+8],20h
jnz check_used_prediction
cmp cl,[eax+16]
jne check_next_symbol
test byte [eax+8],8
jz check_next_symbol
jmp not_as_predicted
check_used_prediction:
test byte [eax+8],8
jz not_as_predicted
cmp cl,[eax+16]
je check_next_symbol
not_as_predicted:
or [next_pass_needed],-1
check_next_symbol:
add eax,20
jmp check_symbols
symbols_checked:
cmp [next_pass_needed],0
jne next_pass
mov eax,[error_line]
or eax,eax
jnz pass_error
call flush_display_buffer
assemble_ok:
ret
assemble_line:
mov eax,[display_buffer]
sub eax,100h
cmp edi,eax
ja out_of_memory
lods byte [esi]
or al,al
jz source_end
cmp al,1
je assemble_instruction
cmp al,2
je define_label
cmp al,3
je define_constant
cmp al,0Fh
je new_line
cmp al,13h
je code_type_setting
cmp al,10h
jne illegal_instruction
lods byte [esi]
jmp segment_prefix
code_type_setting:
lods byte [esi]
mov [code_type],al
jmp line_assembled
new_line:
lods dword [esi]
mov [current_line],eax
continue_line:
cmp byte [esi],0Fh
je line_assembled
jmp assemble_line
define_label:
lods dword [esi]
cmp eax,0Fh
jb invalid_use_of_symbol
je reserved_word_used_as_symbol
mov ebx,eax
lods byte [esi]
mov cl,al
shl ecx,16
mov eax,edi
sub eax,[org_origin]
cdq
xor ch,ch
cmp [reloc_labels],0
je label_reloc_ok
mov ch,2
mov edx,[current_section]
label_reloc_ok:
xchg ch,[ebx+11]
mov cl,[current_pass]
test byte [ebx+8],1
jz new_label
cmp cl,[ebx+9]
je symbol_already_defined
mov [ebx+9],cl
xchg [ebx],eax
xchg [ebx+4],edx
mov ebp,[org_sib]
xchg [ebx+12],ebp
cmp [current_pass],0
je continue_line
cmp eax,[ebx]
jne changed_label
cmp edx,[ebx+4]
jne changed_label
cmp ebp,[ebx+12]
jne changed_label
cmp ch,[ebx+11]
jne changed_label
shr ecx,16
cmp cl,[ebx+10]
je continue_line
mov [ebx+10],cl
changed_label:
test byte [ebx+8],8
jz continue_line
mov al,[current_pass]
cmp al,[ebx+16]
jne continue_line
or [next_pass_needed],-1
jmp continue_line
new_label:
or byte [ebx+8],1
mov [ebx+9],cl
shr ecx,16
mov [ebx+10],cl
mov [ebx],eax
mov dword [ebx+4],edx
mov eax,[org_sib]
mov [ebx+12],eax
jmp continue_line
define_constant:
lods dword [esi]
inc esi
or eax,eax
jz org_directive
cmp eax,0Fh
jb invalid_use_of_symbol
je reserved_word_used_as_symbol
mov edx,[eax+8]
push edx
cmp [current_pass],0
je get_constant_value
test dl,4
jnz get_constant_value
mov dh,[current_pass]
cmp dh,[eax+9]
je get_constant_value
and dl,not 1
mov [eax+8],dl
get_constant_value:
push eax
mov al,byte [esi-1]
push eax
call get_value
pop ebx
mov ch,bl
pop ebx
pop dword [ebx+8]
or ebx,ebx
jz set_org
cmp ebx,0Fh
jb invalid_use_of_symbol
je reserved_word_used_as_symbol
mov cl,[value_type]
or cl,cl
jz make_constant
mov ebp,eax
shr ebp,31
neg ebp
cmp ebp,edx
jne value_out_of_range
mov edx,[symbol_identifier]
make_constant:
test byte [ebx+8],1
jz new_constant
mov ch,[current_pass]
cmp ch,[ebx+9]
jne redefine_constant
test byte [ebx+8],2
jz symbol_already_defined
or byte [ebx+8],4
redefine_constant:
mov [ebx+9],ch
xchg [ebx+11],cl
xchg [ebx],eax
xchg [ebx+4],edx
cmp [current_pass],0
je continue_line
cmp eax,[ebx]
jne changed_constant
cmp edx,[ebx+4]
jne changed_constant
cmp cl,[ebx+11]
jne changed_constant
cmp byte [ebx+10],0
je continue_line
mov byte [ebx+10],0
changed_constant:
test byte [ebx+8],4
jnz continue_line
test byte [ebx+8],8
jz continue_line
mov al,[current_pass]
cmp al,[ebx+16]
jne continue_line
or [next_pass_needed],-1
jmp continue_line
new_constant:
or byte [ebx+8],1+2
mov [ebx+11],cl
mov cl,[current_pass]
mov word [ebx+9],cx
mov [ebx],eax
mov [ebx+4],edx
jmp continue_line
assemble_instruction:
mov [operand_size],0
mov [forced_size],0
lods word [esi]
movzx ebx,ax
add ebx,assembler
lods byte [esi]
jmp near ebx
instruction_assembled:
mov al,[esi]
cmp al,0Fh
je line_assembled
or al,al
jnz extra_characters_on_line
line_assembled:
clc
ret
source_end:
dec esi
stc
ret
skip_line:
call skip_symbol
jnc skip_line
ret
skip_symbol:
lods byte [esi]
or al,al
jz nothing_to_skip
cmp al,0Fh
je nothing_to_skip
cmp al,1
je skip_instruction
cmp al,2
je skip_label
cmp al,3
je skip_label
cmp al,20h
jb skip_assembler_symbol
cmp al,'('
je skip_expression
cmp al,'['
je skip_address
skip_done:
clc
ret
skip_label:
add esi,2
skip_instruction:
add esi,2
skip_assembler_symbol:
inc esi
jmp skip_done
skip_address:
mov al,[esi]
and al,11110000b
cmp al,60h
jb skip_expression
cmp al,70h
ja skip_expression
inc esi
jmp skip_address
skip_expression:
lods byte [esi]
or al,al
jz skip_string
cmp al,'.'
je skip_fp_value
cmp al,')'
je skip_done
cmp al,']'
je skip_done
cmp al,0Fh
je skip_expression
cmp al,10h
je skip_register
cmp al,11h
je skip_label_value
cmp al,80h
jae skip_expression
movzx eax,al
add esi,eax
jmp skip_expression
skip_label_value:
add esi,3
skip_register:
inc esi
jmp skip_expression
skip_fp_value:
add esi,12
jmp skip_done
skip_string:
lods dword [esi]
add esi,eax
inc esi
jmp skip_done
nothing_to_skip:
dec esi
stc
ret
org_directive:
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_dword_value
set_org:
mov [reloc_labels],0
mov dl,[value_type]
or dl,dl
jz org_ok
cmp dl,2
jne invalid_use_of_symbol
or [reloc_labels],-1
cmp [next_pass_needed],0
jne org_ok
cmp [output_format],4
jne org_ok
dec [reloc_labels]
mov edx,[symbol_identifier]
cmp edx,[current_section]
jne org_ok
mov ecx,edi
sub ecx,[edx+8]
cmp eax,ecx
jne org_ok
inc [reloc_labels]
org_ok:
mov ecx,edi
sub ecx,eax
mov [org_origin],ecx
mov [org_sib],0
mov [org_start],edi
jmp instruction_assembled
label_directive:
lods byte [esi]
cmp al,2
jne invalid_argument
lods dword [esi]
cmp eax,0Fh
jb invalid_use_of_symbol
je reserved_word_used_as_symbol
inc esi
mov ebx,eax
xor cl,cl
lods byte [esi]
cmp al,':'
je get_label_size
dec esi
cmp al,11h
jne label_size_ok
get_label_size:
lods word [esi]
cmp al,11h
jne invalid_argument
mov cl,ah
label_size_ok:
mov eax,edi
sub eax,[org_origin]
cdq
mov ebp,[org_sib]
shl ecx,16
cmp byte [esi],80h
jne define_free_label
inc esi
lods byte [esi]
cmp al,'('
jne invalid_argument
push dword [ebx+8]
push ebx ecx
and byte [ebx+8],not 1
cmp byte [esi],'.'
je invalid_value
call get_address_value
or bh,bh
setnz ch
xchg ch,cl
mov bp,cx
shl ebp,16
xchg bl,bh
mov bp,bx
pop ecx ebx
pop dword [ebx+8]
cdq
or ch,[value_type]
jz free_label_reloc_ok
cmp ch,1
je invalid_use_of_symbol
mov edx,[symbol_identifier]
jmp free_label_reloc_ok
define_free_label:
xor ch,ch
cmp [reloc_labels],0
je free_label_reloc_ok
mov ch,2
mov edx,[current_section]
free_label_reloc_ok:
xchg ch,[ebx+11]
mov cl,[current_pass]
test byte [ebx+8],1
jz new_free_label
cmp cl,[ebx+9]
je symbol_already_defined
mov [ebx+9],cl
xchg [ebx],eax
xchg [ebx+4],edx
xchg [ebx+12],ebp
cmp [current_pass],0
je instruction_assembled
cmp eax,[ebx]
jne changed_free_label
cmp edx,[ebx+4]
jne changed_free_label
cmp ebp,[ebx+12]
jne changed_free_label
cmp ch,[ebx+11]
jne changed_free_label
shr ecx,16
cmp cl,[ebx+10]
je instruction_assembled
mov [ebx+10],cl
changed_free_label:
test byte [ebx+8],8
jz instruction_assembled
mov al,[current_pass]
cmp al,[ebx+16]
jne instruction_assembled
or [next_pass_needed],-1
jmp instruction_assembled
new_free_label:
or byte [ebx+8],1
mov [ebx+9],cl
shr ecx,16
mov [ebx+10],cl
mov [ebx],eax
mov dword [ebx+4],edx
mov [ebx+12],ebp
jmp instruction_assembled
load_directive:
lods byte [esi]
cmp al,2
jne invalid_argument
lods dword [esi]
cmp eax,0Fh
jb invalid_use_of_symbol
je reserved_word_used_as_symbol
inc esi
push eax
mov al,1
cmp byte [esi],11h
jne load_size_ok
lods byte [esi]
lods byte [esi]
load_size_ok:
cmp al,8
ja invalid_value
mov [operand_size],al
mov dword [value],0
mov dword [value+4],0
lods word [esi]
cmp ax,82h+'(' shl 8
jne invalid_argument
cmp byte [esi],0
jne load_from_code
inc esi
lea edx,[esi+4]
mov eax,[esi]
lea esi,[esi+4+eax+1]
call open
jc file_not_found
mov al,2
xor edx,edx
call lseek
xor edx,edx
cmp byte [esi],':'
jne load_position_ok
inc esi
cmp byte [esi],'('
jne invalid_argument
inc esi
cmp byte [esi],'.'
je invalid_value
push ebx
call get_dword_value
pop ebx
mov edx,eax
load_position_ok:
xor al,al
call lseek
movzx ecx,[operand_size]
mov edx,value
call read
jc error_reading_file
call close
value_loaded:
mov eax,dword [value]
mov edx,dword [value+4]
pop ebx
xor cx,cx
jmp make_constant
load_from_code:
cmp byte [esi],'.'
je invalid_value
call get_relative_offset
neg eax
cmp [next_pass_needed],0
jne load_address_ok
cmp [value_type],0
jne invalid_use_of_symbol
load_address_ok:
push esi edi
mov esi,edi
sub esi,eax
jc value_out_of_range
cmp esi,[org_start]
jb value_out_of_range
mov edi,value
movzx ecx,[operand_size]
cmp ecx,eax
ja value_out_of_range
rep movs byte [edi],[esi]
pop edi esi
jmp value_loaded
display_directive:
push esi edi
prepare_display:
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],0
jne display_byte
inc esi
lods dword [esi]
mov ecx,eax
rep movs byte [edi],[esi]
inc esi
jmp display_next
display_byte:
call get_byte_value
stos byte [edi]
display_next:
cmp edi,[display_buffer]
ja out_of_memory
lods byte [esi]
or al,al
jz do_display
cmp al,0Fh
je do_display
cmp al,','
jne extra_characters_on_line
jmp prepare_display
do_display:
dec esi
mov ebp,edi
pop edi ebx
push esi edi
mov esi,edi
mov ecx,ebp
sub ecx,esi
mov edi,[display_buffer]
sub edi,ecx
sub edi,4
cmp edi,esi
jbe out_of_memory
mov [display_buffer],edi
mov eax,ecx
rep movs byte [edi],[esi]
stos dword [edi]
pop edi esi
jmp instruction_assembled
flush_display_buffer:
mov eax,[display_buffer]
or eax,eax
jz display_done
mov esi,[labels_list]
cmp esi,eax
je display_done
display_messages:
sub esi,4
mov ecx,[esi]
sub esi,ecx
push esi
call display_block
pop esi
cmp esi,[display_buffer]
jne display_messages
mov eax,[labels_list]
mov [display_buffer],eax
display_done:
ret
times_directive:
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_dword_value
cmp [next_pass_needed],0
jne times_value_ok
cmp [value_type],0
jne invalid_use_of_symbol
times_value_ok:
cmp eax,0
je zero_times
jl negative_times
cmp byte [esi],':'
jne times_argument_ok
inc esi
times_argument_ok:
push [counter] [counter_limit]
mov [counter_limit],eax
mov [counter],1
times_loop:
push esi
or [times_working],-1
call continue_line
mov eax,[counter_limit]
cmp [counter],eax
je times_done
inc [counter]
pop esi
jmp times_loop
times_done:
mov [times_working],0
pop eax
pop [counter_limit] [counter]
jmp instruction_assembled
negative_times:
cmp [error_line],0
jne zero_times
mov eax,[current_line]
mov [error_line],eax
mov [error],invalid_value
zero_times:
call skip_line
jmp instruction_assembled
virtual_directive:
lods byte [esi]
cmp al,80h
jne virtual_at_current
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_address_value
xor ch,ch
or bh,bh
jz set_virtual
mov ch,1
jmp set_virtual
virtual_at_current:
dec esi
mov eax,edi
sub eax,[org_origin]
xor bx,bx
xor cx,cx
mov [value_type],0
cmp [reloc_labels],0
je set_virtual
mov [value_type],2
set_virtual:
mov edx,[org_sib]
mov byte [org_sib],bh
mov byte [org_sib+1],bl
mov byte [org_sib+2],ch
mov byte [org_sib+3],cl
call allocate_structure_data
mov word [ebx],virtual_directive-assembler
neg eax
add eax,edi
xchg [org_origin],eax
mov [ebx+4],eax
mov [ebx+8],edx
mov al,[virtual_data]
mov [ebx+2],al
mov al,[reloc_labels]
mov [ebx+3],al
mov eax,edi
xchg eax,[org_start]
mov [ebx+0Ch],eax
mov [ebx+10h],edi
or [virtual_data],-1
mov [reloc_labels],0
cmp [value_type],1
je invalid_use_of_symbol
cmp [value_type],2
jne instruction_assembled
or [reloc_labels],-1
jmp instruction_assembled
allocate_structure_data:
mov ebx,[structures_buffer]
sub ebx,14h
cmp ebx,[free_additional_memory]
jb out_of_memory
mov [structures_buffer],ebx
ret
find_structure_data:
mov ebx,[structures_buffer]
scan_structures:
cmp ebx,[additional_memory_end]
je no_such_structure
cmp ax,[ebx]
jne next_structure
clc
ret
next_structure:
cmp ax,repeat_directive-assembler
jne if_structure_ok
cmp word [ebx],if_directive-assembler
je no_such_structure
if_structure_ok:
cmp ax,if_directive-assembler
jne repeat_structure_ok
cmp word [ebx],repeat_directive-assembler
je no_such_structure
repeat_structure_ok:
add ebx,14h
jmp scan_structures
no_such_structure:
stc
ret
end_virtual:
call find_structure_data
jc unexpected_instruction
mov al,[ebx+2]
mov [virtual_data],al
mov al,[ebx+3]
mov [reloc_labels],al
mov eax,[ebx+4]
mov [org_origin],eax
mov eax,[ebx+8]
mov [org_sib],eax
mov eax,[ebx+0Ch]
mov [org_start],eax
mov edi,[ebx+10h]
remove_structure_data:
push esi edi
mov esi,[structures_buffer]
mov ecx,ebx
sub ecx,esi
lea edi,[esi+14h]
mov [structures_buffer],edi
shr ecx,2
rep movs dword [edi],[esi]
pop edi esi
jmp instruction_assembled
repeat_directive:
cmp [times_working],0
jne unexpected_instruction
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_dword_value
cmp [next_pass_needed],0
jne repeat_value_ok
cmp [value_type],0
jne invalid_use_of_symbol
repeat_value_ok:
cmp eax,0
je zero_repeat
jl negative_repeat
call allocate_structure_data
mov word [ebx],repeat_directive-assembler
xchg eax,[counter_limit]
mov [ebx+4],eax
mov eax,1
xchg eax,[counter]
mov [ebx+8],eax
mov [ebx+0Ch],esi
jmp instruction_assembled
end_repeat:
cmp [times_working],0
jne unexpected_instruction
call find_structure_data
jc unexpected_instruction
mov eax,[counter_limit]
inc [counter]
cmp [counter],eax
jbe continue_repeating
mov eax,[ebx+4]
mov [counter_limit],eax
mov eax,[ebx+8]
mov [counter],eax
jmp remove_structure_data
continue_repeating:
mov esi,[ebx+0Ch]
jmp instruction_assembled
negative_repeat:
cmp [error_line],0
jne zero_repeat
mov eax,[current_line]
mov [error_line],eax
mov [error],invalid_value
zero_repeat:
mov al,[esi]
or al,al
jz unexpected_end_of_file
cmp al,0Fh
jne extra_characters_on_line
call find_end_repeat
jmp instruction_assembled
find_end_repeat:
call find_structure_end
cmp ax,repeat_directive-assembler
jne unexpected_instruction
ret
find_structure_end:
call skip_line
lods byte [esi]
cmp al,0Fh
jne unexpected_end_of_file
lods dword [esi]
mov [current_line],eax
skip_labels:
cmp byte [esi],2
jne labels_ok
add esi,6
jmp skip_labels
labels_ok:
cmp byte [esi],1
jne find_structure_end
mov ax,[esi+1]
cmp ax,prefix_instruction-assembler
je find_structure_end
add esi,4
cmp ax,repeat_directive-assembler
je skip_repeat
cmp ax,if_directive-assembler
je skip_if
cmp ax,else_directive-assembler
je structure_end
cmp ax,end_directive-assembler
jne find_structure_end
cmp byte [esi],1
jne find_structure_end
mov ax,[esi+1]
add esi,4
cmp ax,repeat_directive-assembler
je structure_end
cmp ax,if_directive-assembler
jne find_structure_end
structure_end:
ret
skip_repeat:
call find_end_repeat
jmp find_structure_end
if_directive:
cmp [times_working],0
jne unexpected_instruction
call calculate_logical_expression
mov dl,al
mov al,[esi]
or al,al
jz unexpected_end_of_file
cmp al,0Fh
jne extra_characters_on_line
or dl,dl
jnz if_true
call find_else
jc instruction_assembled
mov al,[esi]
cmp al,1
jne else_true
cmp word [esi+1],if_directive-assembler
jne else_true
add esi,4
jmp if_directive
if_true:
call allocate_structure_data
mov word [ebx],if_directive-assembler
mov byte [ebx+2],0
jmp instruction_assembled
else_true:
or al,al
jz unexpected_end_of_file
cmp al,0Fh
jne extra_characters_on_line
call allocate_structure_data
mov word [ebx],if_directive-assembler
or byte [ebx+2],-1
jmp instruction_assembled
else_directive:
cmp [times_working],0
jne unexpected_instruction
mov ax,if_directive-assembler
call find_structure_data
jc unexpected_instruction
cmp byte [ebx+2],0
jne unexpected_instruction
found_else:
mov al,[esi]
cmp al,1
jne skip_else
cmp word [esi+1],if_directive-assembler
jne skip_else
add esi,4
call find_else
jnc found_else
jmp remove_structure_data
skip_else:
or al,al
jz unexpected_end_of_file
cmp al,0Fh
jne extra_characters_on_line
call find_end_if
jmp remove_structure_data
end_if:
cmp [times_working],0
jne unexpected_instruction
call find_structure_data
jc unexpected_instruction
jmp remove_structure_data
skip_if:
call find_else
jc find_structure_end
cmp byte [esi],1
jne skip_after_else
cmp word [esi+1],if_directive-assembler
jne skip_after_else
add esi,4
jmp skip_if
skip_after_else:
call find_end_if
jmp find_structure_end
find_else:
call find_structure_end
cmp ax,else_directive-assembler
je else_found
cmp ax,if_directive-assembler
jne unexpected_instruction
stc
ret
else_found:
clc
ret
find_end_if:
call find_structure_end
cmp ax,if_directive-assembler
jne unexpected_instruction
ret
end_directive:
lods byte [esi]
cmp al,1
jne invalid_argument
lods word [esi]
inc esi
cmp ax,virtual_directive-assembler
je end_virtual
cmp ax,repeat_directive-assembler
je end_repeat
cmp ax,if_directive-assembler
je end_if
cmp ax,data_directive-assembler
je end_data
jmp invalid_argument
data_bytes:
lods byte [esi]
cmp al,'('
je get_byte
cmp al,'?'
jne invalid_argument
mov eax,edi
mov byte [edi],0
inc edi
call undefined_data
jmp byte_ok
get_byte:
cmp byte [esi],0
je get_string
call get_byte_value
stos byte [edi]
byte_ok:
cmp edi,[display_buffer]
ja out_of_memory
lods byte [esi]
or al,al
jz data_end
cmp al,0Fh
je data_end
cmp al,','
jne extra_characters_on_line
jmp data_bytes
data_end:
dec esi
jmp instruction_assembled
get_string:
inc esi
lods dword [esi]
mov ecx,eax
lea eax,[edi+ecx]
cmp eax,[display_buffer]
ja out_of_memory
rep movs byte [edi],[esi]
inc esi
jmp byte_ok
undefined_data:
cmp [virtual_data],0
je mark_undefined_data
ret
mark_undefined_data:
cmp eax,[undefined_data_end]
je undefined_data_ok
mov [undefined_data_start],eax
undefined_data_ok:
mov [undefined_data_end],edi
ret
data_unicode:
or [base_code],-1
jmp get_words_data
data_words:
mov [base_code],0
get_words_data:
lods byte [esi]
cmp al,'('
je get_word
cmp al,'?'
jne invalid_argument
mov eax,edi
mov word [edi],0
scas word [edi]
call undefined_data
jmp word_ok
get_word:
cmp [base_code],0
je word_data_value
cmp byte [esi],0
je word_string
word_data_value:
call get_word_value
call mark_relocation
stos word [edi]
word_ok:
cmp edi,[display_buffer]
ja out_of_memory
lods byte [esi]
or al,al
jz data_end
cmp al,0Fh
je data_end
cmp al,','
jne extra_characters_on_line
jmp get_words_data
word_string:
inc esi
lods dword [esi]
mov ecx,eax
jecxz word_string_ok
lea eax,[edi+ecx*2]
cmp eax,[display_buffer]
ja out_of_memory
xor ah,ah
copy_word_string:
lods byte [esi]
stos word [edi]
loop copy_word_string
word_string_ok:
inc esi
jmp word_ok
data_dwords:
lods byte [esi]
cmp al,'('
je get_dword
cmp al,'?'
jne invalid_argument
mov eax,edi
mov dword [edi],0
scas dword [edi]
call undefined_data
jmp dword_ok
get_dword:
push esi
call get_dword_value
pop ebx
cmp byte [esi],':'
je complex_dword
call mark_relocation
stos dword [edi]
jmp dword_ok
complex_dword:
mov esi,ebx
cmp byte [esi],'.'
je invalid_value
call get_word_value
push eax
inc esi
lods byte [esi]
cmp al,'('
jne invalid_operand
mov al,[value_type]
push eax
cmp byte [esi],'.'
je invalid_value
call get_word_value
call mark_relocation
stos word [edi]
pop eax
mov [value_type],al
pop eax
call mark_relocation
stos word [edi]
dword_ok:
cmp edi,[display_buffer]
ja out_of_memory
lods byte [esi]
or al,al
jz data_end
cmp al,0Fh
je data_end
cmp al,','
jne extra_characters_on_line
jmp data_dwords
data_pwords:
lods byte [esi]
cmp al,'('
je get_pword
cmp al,'?'
jne invalid_argument
mov eax,edi
mov dword [edi],0
scas dword [edi]
mov word [edi],0
scas word [edi]
call undefined_data
jmp pword_ok
get_pword:
push esi
call get_pword_value
pop ebx
cmp byte [esi],':'
je complex_pword
call mark_relocation
stos dword [edi]
mov ax,dx
stos word [edi]
jmp pword_ok
complex_pword:
mov esi,ebx
cmp byte [esi],'.'
je invalid_value
call get_word_value
push eax
inc esi
lods byte [esi]
cmp al,'('
jne invalid_operand
mov al,[value_type]
push eax
cmp byte [esi],'.'
je invalid_value
call get_dword_value
call mark_relocation
stos dword [edi]
pop eax
mov [value_type],al
pop eax
call mark_relocation
stos word [edi]
pword_ok:
cmp edi,[display_buffer]
ja out_of_memory
lods byte [esi]
or al,al
jz data_end
cmp al,0Fh
je data_end
cmp al,','
jne extra_characters_on_line
jmp data_pwords
data_qwords:
lods byte [esi]
cmp al,'('
je get_qword
cmp al,'?'
jne invalid_argument
mov eax,edi
mov dword [edi],0
scas dword [edi]
mov dword [edi],0
scas dword [edi]
call undefined_data
jmp qword_ok
get_qword:
call get_qword_value
call mark_relocation
stos dword [edi]
mov eax,edx
stos dword [edi]
qword_ok:
cmp edi,[display_buffer]
ja out_of_memory
lods byte [esi]
or al,al
jz data_end
cmp al,0Fh
je data_end
cmp al,','
jne extra_characters_on_line
jmp data_qwords
data_twords:
lods byte [esi]
cmp al,'('
je get_tbyte
cmp al,'?'
jne invalid_argument
mov eax,edi
mov dword [edi],0
scas dword [edi]
mov dword [edi],0
scas dword [edi]
mov word [edi],0
scas word [edi]
call undefined_data
jmp tbyte_ok
get_tbyte:
lods byte [esi]
cmp al,'.'
jne invalid_value
cmp word [esi+8],8000h
je fp_zero_tbyte
mov eax,[esi]
stos dword [edi]
mov eax,[esi+4]
stos dword [edi]
mov ax,[esi+8]
add ax,3FFFh
cmp ax,8000h
jae value_out_of_range
mov bl,[esi+11]
shl bx,15
or ax,bx
stos word [edi]
add esi,12
jmp tbyte_ok
fp_zero_tbyte:
xor eax,eax
stos dword [edi]
stos dword [edi]
mov al,[esi+11]
shl ax,15
stos word [edi]
add esi,12
tbyte_ok:
cmp edi,[display_buffer]
ja out_of_memory
lods byte [esi]
or al,al
jz data_end
cmp al,0Fh
je data_end
cmp al,','
jne extra_characters_on_line
jmp data_twords
data_file:
lods word [esi]
cmp ax,'('
jne invalid_argument
lea edx,[esi+4]
mov eax,[esi]
lea esi,[esi+4+eax+1]
call open
jc file_not_found
mov al,2
xor edx,edx
call lseek
push eax
xor edx,edx
cmp byte [esi],':'
jne position_ok
inc esi
cmp byte [esi],'('
jne invalid_argument
inc esi
cmp byte [esi],'.'
je invalid_value
push ebx
call get_dword_value
pop ebx
mov edx,eax
sub [esp],edx
position_ok:
cmp byte [esi],','
jne size_ok
inc esi
cmp byte [esi],'('
jne invalid_argument
inc esi
cmp byte [esi],'.'
je invalid_value
push ebx edx
call get_dword_value
pop edx ebx
mov [esp],eax
size_ok:
cmp [next_pass_needed],0
jne file_reserve
xor al,al
call lseek
pop ecx
mov edx,edi
add edi,ecx
jc out_of_memory
cmp edi,[display_buffer]
ja out_of_memory
call read
jc error_reading_file
call close
check_for_next_name:
lods byte [esi]
cmp al,','
je data_file
dec esi
jmp instruction_assembled
file_reserve:
call close
pop ecx
add edi,ecx
jc out_of_memory
cmp edi,[display_buffer]
ja out_of_memory
jmp check_for_next_name
reserve_bytes:
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_dword_value
cmp [next_pass_needed],0
jne rb_value_ok
cmp [value_type],0
jne invalid_use_of_symbol
rb_value_ok:
cmp eax,0
jl reserve_negative
mov ecx,eax
mov edx,ecx
add edx,edi
jc out_of_memory
cmp edx,[display_buffer]
ja out_of_memory
push edi
cmp [next_pass_needed],0
je zero_bytes
add edi,ecx
jmp reserved_data
zero_bytes:
xor eax,eax
shr ecx,1
jnc bytes_stosb_ok
stos byte [edi]
bytes_stosb_ok:
shr ecx,1
jnc bytes_stosw_ok
stos word [edi]
bytes_stosw_ok:
rep stos dword [edi]
reserved_data:
pop eax
call undefined_data
jmp instruction_assembled
reserve_negative:
cmp [error_line],0
jne instruction_assembled
mov eax,[current_line]
mov [error_line],eax
mov [error],invalid_value
jmp instruction_assembled
reserve_words:
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_dword_value
cmp [next_pass_needed],0
jne rw_value_ok
cmp [value_type],0
jne invalid_use_of_symbol
rw_value_ok:
cmp eax,0
jl reserve_negative
mov ecx,eax
mov edx,ecx
shl edx,1
jc out_of_memory
add edx,edi
jc out_of_memory
cmp edx,[display_buffer]
ja out_of_memory
push edi
cmp [next_pass_needed],0
je zero_words
lea edi,[edi+ecx*2]
jmp reserved_data
zero_words:
xor eax,eax
shr ecx,1
jnc words_stosw_ok
stos word [edi]
words_stosw_ok:
rep stos dword [edi]
jmp reserved_data
reserve_dwords:
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_dword_value
cmp [next_pass_needed],0
jne rd_value_ok
cmp [value_type],0
jne invalid_use_of_symbol
rd_value_ok:
cmp eax,0
jl reserve_negative
mov ecx,eax
mov edx,ecx
shl edx,1
jc out_of_memory
shl edx,1
jc out_of_memory
add edx,edi
jc out_of_memory
cmp edx,[display_buffer]
ja out_of_memory
push edi
cmp [next_pass_needed],0
je zero_dwords
lea edi,[edi+ecx*4]
jmp reserved_data
zero_dwords:
xor eax,eax
rep stos dword [edi]
jmp reserved_data
reserve_pwords:
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_dword_value
cmp [next_pass_needed],0
jne rp_value_ok
cmp [value_type],0
jne invalid_use_of_symbol
rp_value_ok:
cmp eax,0
jl reserve_negative
mov ecx,eax
shl ecx,1
jc out_of_memory
add ecx,eax
mov edx,ecx
shl edx,1
jc out_of_memory
add edx,edi
jc out_of_memory
cmp edx,[display_buffer]
ja out_of_memory
push edi
cmp [next_pass_needed],0
je zero_words
lea edi,[edi+ecx*2]
jmp reserved_data
reserve_qwords:
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_dword_value
cmp [next_pass_needed],0
jne rq_value_ok
cmp [value_type],0
jne invalid_use_of_symbol
rq_value_ok:
cmp eax,0
jl reserve_negative
mov ecx,eax
shl ecx,1
jc out_of_memory
mov edx,ecx
shl edx,1
jc out_of_memory
shl edx,1
jc out_of_memory
add edx,edi
jc out_of_memory
cmp edx,[display_buffer]
ja out_of_memory
push edi
cmp [next_pass_needed],0
je zero_dwords
lea edi,[edi+ecx*4]
jmp reserved_data
reserve_twords:
lods byte [esi]
cmp al,'('
jne invalid_argument
cmp byte [esi],'.'
je invalid_value
call get_dword_value
cmp [next_pass_needed],0
jne rt_value_ok
cmp [value_type],0
jne invalid_use_of_symbol
rt_value_ok:
cmp eax,0
jl reserve_negative
mov ecx,eax
shl ecx,2
jc out_of_memory
add ecx,eax
mov edx,ecx
shl edx,1
jc out_of_memory
add edx,edi
jc out_of_memory
cmp edx,[display_buffer]
ja out_of_memory
push edi
cmp [next_pass_needed],0
je zero_words
lea edi,[edi+ecx*2]
jmp reserved_data