📄 parser.inc
字号:
; flat assembler core
; Copyright (c) 1999-2006, Tomasz Grysztar.
; All rights reserved.
parser:
mov eax,[memory_end]
mov [labels_list],eax
mov eax,[additional_memory]
mov [free_additional_memory],eax
xor eax,eax
mov [current_locals_prefix],eax
mov [anonymous_reverse],eax
mov [anonymous_forward],eax
mov [hash_tree],eax
mov [blocks_stack],eax
mov esi,[memory_start]
mov edi,[source_start]
parser_loop:
mov [current_line],esi
lea eax,[edi+100h]
cmp eax,[labels_list]
jae out_of_memory
cmp byte [esi+16],0
je empty_line
mov al,0Fh
stos byte [edi]
mov eax,esi
stos dword [edi]
add esi,16
parse_line:
cmp byte [esi],1Ah
jne empty_instruction
push edi
add esi,2
movzx ecx,byte [esi-1]
cmp byte [esi+ecx],':'
je simple_label
cmp byte [esi+ecx],'='
je constant_label
call get_instruction
jnc main_instruction_identified
cmp byte [esi+ecx],1Ah
jne no_data_label
push esi ecx
lea esi,[esi+ecx+2]
movzx ecx,byte [esi-1]
call get_data_directive
jnc data_label
pop ecx esi
no_data_label:
call get_data_directive
jnc main_instruction_identified
pop edi
sub esi,2
xor bx,bx
call parse_line_contents
jmp parse_next_line
simple_label:
pop edi
call identify_label
mov byte [edi],2
inc edi
stos dword [edi]
inc esi
xor al,al
stos byte [edi]
jmp parse_line
constant_label:
pop edi
call get_label_id
mov byte [edi],3
inc edi
stos dword [edi]
xor al,al
stos byte [edi]
inc esi
xor bx,bx
call parse_line_contents
jmp parse_next_line
data_label:
pop ecx edx
pop edi
push eax ebx esi
mov esi,edx
movzx ecx,byte [esi-1]
call identify_label
mov byte [edi],2
inc edi
stos dword [edi]
pop esi ebx eax
stos byte [edi]
push edi
main_instruction_identified:
pop edi
mov dl,al
mov al,1
stos byte [edi]
mov ax,bx
stos word [edi]
mov al,dl
stos byte [edi]
cmp bx,if_directive-assembler
je parse_block
cmp bx,repeat_directive-assembler
je parse_block
cmp bx,while_directive-assembler
je parse_block
cmp bx,end_directive-assembler
je parse_end_directive
cmp bx,else_directive-assembler
je parse_else
common_parse:
call parse_line_contents
jmp parse_next_line
empty_instruction:
lods byte [esi]
or al,al
jz parse_next_line
cmp al,':'
je invalid_name
cmp al,3Bh
je skip_preprocessed_symbol
dec esi
call parse_argument
jmp parse_next_line
skip_preprocessed_symbol:
lods byte [esi]
movzx eax,al
add esi,eax
skip_next:
lods byte [esi]
or al,al
jz parse_next_line
cmp al,1Ah
je skip_preprocessed_symbol
cmp al,3Bh
je skip_preprocessed_symbol
cmp al,22h
je skip_preprocessed_string
jmp skip_next
skip_preprocessed_string:
lods dword [esi]
add esi,eax
jmp skip_next
empty_line:
add esi,17
parse_next_line:
cmp esi,[source_start]
jb parser_loop
source_parsed:
cmp [blocks_stack],0
je blocks_stack_ok
pop eax
pop [current_line]
jmp missing_end_directive
blocks_stack_ok:
xor al,al
stos byte [edi]
mov eax,[error_line]
mov [current_line],eax
cmp [anonymous_forward],0
jne invalid_value
add edi,0Fh
and edi,not 0Fh
mov [code_start],edi
ret
parse_block:
mov eax,esp
sub eax,100h
jc stack_overflow
cmp eax,[stack_limit]
jb stack_overflow
push [current_line]
mov ax,bx
shl eax,16
push eax
inc [blocks_stack]
cmp bx,if_directive-assembler
je parse_if
cmp bx,while_directive-assembler
je parse_while
call parse_line_contents
jmp parse_next_line
parse_end_directive:
cmp byte [esi],1Ah
jne common_parse
push edi
inc esi
movzx ecx,byte [esi]
inc esi
call get_instruction
pop edi
jnc parse_end_block
sub esi,2
jmp common_parse
parse_end_block:
mov dl,al
mov al,1
stos byte [edi]
mov ax,bx
stos word [edi]
mov al,dl
stos byte [edi]
lods byte [esi]
or al,al
jnz extra_characters_on_line
cmp bx,if_directive-assembler
je close_parsing_block
cmp bx,repeat_directive-assembler
je close_parsing_block
cmp bx,while_directive-assembler
je close_parsing_block
jmp parse_next_line
close_parsing_block:
cmp [blocks_stack],0
je unexpected_instruction
cmp bx,[esp+2]
jne unexpected_instruction
dec [blocks_stack]
pop eax edx
cmp bx,if_directive-assembler
jne parse_next_line
test al,1100b
jz parse_next_line
test al,10000b
jnz parse_next_line
sub edi,8
jmp parse_next_line
parse_if:
push edi
call parse_line_contents
xor al,al
stos byte [edi]
xchg esi,[esp]
mov edi,esi
call preevaluate_logical_expression
pop esi
cmp al,'0'
je parse_false_condition_block
cmp al,'1'
je parse_true_condition_block
or byte [esp],10000b
jmp parse_next_line
parse_while:
push edi
call parse_line_contents
xor al,al
stos byte [edi]
xchg esi,[esp]
mov edi,esi
call preevaluate_logical_expression
pop esi
cmp al,'0'
je parse_false_condition_block
cmp al,'1'
jne parse_next_line
stos byte [edi]
jmp parse_next_line
parse_false_condition_block:
or byte [esp],1
sub edi,4
jmp skip_parsing
parse_true_condition_block:
or byte [esp],100b
sub edi,4
jmp parse_next_line
parse_else:
cmp [blocks_stack],0
je unexpected_instruction
cmp word [esp+2],if_directive-assembler
jne unexpected_instruction
lods byte [esi]
or al,al
jz parse_pure_else
cmp al,1Ah
jne extra_characters_on_line
push edi
movzx ecx,byte [esi]
inc esi
call get_instruction
jc extra_characters_on_line
pop edi
cmp bx,if_directive-assembler
jne extra_characters_on_line
test byte [esp],100b
jnz skip_true_condition_else
mov dl,al
mov al,1
stos byte [edi]
mov ax,bx
stos word [edi]
mov al,dl
stos byte [edi]
jmp parse_if
skip_true_condition_else:
sub edi,4
or byte [esp],1
jmp skip_parsing_contents
parse_pure_else:
bts dword [esp],1
jc unexpected_instruction
test byte [esp],100b
jz parse_next_line
sub edi,4
or byte [esp],1
jmp skip_parsing
skip_parsing:
cmp esi,[source_start]
jae source_parsed
mov [current_line],esi
add esi,16
skip_parsing_line:
cmp byte [esi],1Ah
jne skip_parsing_contents
inc esi
movzx ecx,byte [esi]
inc esi
cmp byte [esi+ecx],':'
je skip_parsing_label
push edi
call get_instruction
pop edi
jnc skip_parsing_instruction
add esi,ecx
jmp skip_parsing_contents
skip_parsing_label:
lea esi,[esi+ecx+1]
jmp skip_parsing_line
skip_parsing_instruction:
cmp bx,if_directive-assembler
je skip_parsing_block
cmp bx,repeat_directive-assembler
je skip_parsing_block
cmp bx,while_directive-assembler
je skip_parsing_block
cmp bx,end_directive-assembler
je skip_parsing_end_directive
cmp bx,else_directive-assembler
je skip_parsing_else
skip_parsing_contents:
lods byte [esi]
or al,al
jz skip_parsing
cmp al,1Ah
je skip_parsing_symbol
cmp al,3Bh
je skip_parsing_symbol
cmp al,22h
je skip_parsing_string
jmp skip_parsing_contents
skip_parsing_symbol:
lods byte [esi]
movzx eax,al
add esi,eax
jmp skip_parsing_contents
skip_parsing_string:
lods dword [esi]
add esi,eax
jmp skip_parsing_contents
skip_parsing_block:
mov eax,esp
sub eax,100h
jc stack_overflow
cmp eax,[stack_limit]
jb stack_overflow
push [current_line]
mov ax,bx
shl eax,16
push eax
inc [blocks_stack]
jmp skip_parsing_contents
skip_parsing_end_directive:
cmp byte [esi],1Ah
jne skip_parsing_contents
push edi
inc esi
movzx ecx,byte [esi]
inc esi
call get_instruction
pop edi
jnc skip_parsing_end_block
add esi,ecx
jmp skip_parsing_contents
skip_parsing_end_block:
lods byte [esi]
or al,al
jnz extra_characters_on_line
cmp bx,if_directive-assembler
je close_skip_parsing_block
cmp bx,repeat_directive-assembler
je close_skip_parsing_block
cmp bx,while_directive-assembler
je close_skip_parsing_block
jmp skip_parsing
close_skip_parsing_block:
cmp [blocks_stack],0
je unexpected_instruction
cmp bx,[esp+2]
jne unexpected_instruction
dec [blocks_stack]
pop eax edx
test al,1
jz skip_parsing
cmp bx,if_directive-assembler
jne parse_next_line
test al,10000b
jz parse_next_line
mov al,0Fh
stos byte [edi]
mov eax,[current_line]
stos dword [edi]
mov eax,1 + (end_directive-assembler) shl 8
stos dword [edi]
mov eax,1 + (if_directive-assembler) shl 8
stos dword [edi]
jmp parse_next_line
skip_parsing_else:
cmp [blocks_stack],0
je unexpected_instruction
cmp word [esp+2],if_directive-assembler
jne unexpected_instruction
lods byte [esi]
or al,al
jz skip_parsing_pure_else
cmp al,1Ah
jne extra_characters_on_line
push edi
movzx ecx,byte [esi]
inc esi
call get_instruction
jc extra_characters_on_line
pop edi
cmp bx,if_directive-assembler
jne extra_characters_on_line
mov al,[esp]
test al,1
jz skip_parsing_contents
test al,100b
jnz skip_parsing_contents
test al,10000b
jnz parse_else_if
xor al,al
mov [esp],al
mov al,0Fh
stos byte [edi]
mov eax,[current_line]
stos dword [edi]
parse_else_if:
mov eax,1 + (if_directive-assembler) shl 8
stos dword [edi]
jmp parse_if
skip_parsing_pure_else:
bts dword [esp],1
jc unexpected_instruction
mov al,[esp]
test al,1
jz skip_parsing
test al,100b
jnz skip_parsing
and al,not 1
or al,1000b
mov [esp],al
jmp parse_next_line
parse_line_contents:
mov [parenthesis_stack],0
parse_instruction_arguments:
cmp bx,prefix_instruction-assembler
je allow_embedded_instruction
cmp bx,times_directive-assembler
je parse_times_directive
cmp bx,end_directive-assembler
je allow_embedded_instruction
cmp bx,label_directive-assembler
je parse_label_directive
cmp bx,segment_directive-assembler
je parse_label_directive
cmp bx,load_directive-assembler
je parse_load_directive
cmp bx,extrn_directive-assembler
je parse_extrn_directive
cmp bx,public_directive-assembler
je parse_public_directive
parse_argument:
lea eax,[edi+100h]
cmp eax,[labels_list]
jae out_of_memory
lods byte [esi]
cmp al,':'
je instruction_separator
cmp al,','
je separator
cmp al,'='
je separator
cmp al,'|'
je separator
cmp al,'&'
je separator
cmp al,'~'
je separator
cmp al,'>'
je greater
cmp al,'<'
je less
cmp al,')'
je close_parenthesis
or al,al
jz contents_parsed
cmp al,'['
je address_argument
cmp al,']'
je separator
cmp al,'{'
je unallowed_character
cmp al,'}'
je unallowed_character
cmp al,'#'
je unallowed_character
cmp al,'`'
je unallowed_character
dec esi
cmp al,1Ah
jne expression_argument
push edi
mov edi,directive_operators
call get_operator
or al,al
jnz operator_argument
inc esi
movzx ecx,byte [esi]
inc esi
call get_symbol
jnc symbol_argument
cmp ecx,1
jne check_argument
cmp byte [esi],'?'
jne check_argument
pop edi
movs byte [edi],[esi]
jmp argument_parsed
symbol_argument:
pop edi
stos word [edi]
jmp argument_parsed
operator_argument:
pop edi
cmp al,85h
je ptr_argument
stos byte [edi]
cmp al,80h
je forced_expression
cmp al,81h
je forced_parenthesis
cmp al,82h
je parse_from_operator
cmp al,89h
je parse_label_operator
jmp argument_parsed
allow_embedded_instruction:
cmp byte [esi],1Ah
jne parse_argument
push edi
inc esi
movzx ecx,byte [esi]
inc esi
call get_instruction
jnc embedded_instruction
call get_data_directive
jnc embedded_instruction
pop edi
sub esi,2
jmp parse_argument
embedded_instruction:
pop edi
mov dl,al
mov al,1
stos byte [edi]
mov ax,bx
stos word [edi]
mov al,dl
stos byte [edi]
jmp parse_instruction_arguments
parse_times_directive:
mov al,'('
stos byte [edi]
call convert_expression
mov al,')'
stos byte [edi]
cmp byte [esi],':'
jne allow_embedded_instruction
movs byte [edi],[esi]
jmp allow_embedded_instruction
parse_label_directive:
cmp byte [esi],1Ah
jne argument_parsed
push esi
inc esi
movzx ecx,byte [esi]
inc esi
call identify_label
pop ebx
cmp eax,0Fh
je non_label_identified
mov byte [edi],2
inc edi
stos dword [edi]
xor al,al
stos byte [edi]
jmp argument_parsed
non_label_identified:
mov esi,ebx
jmp argument_parsed
parse_load_directive:
cmp byte [esi],1Ah
jne argument_parsed
push esi
inc esi
movzx ecx,byte [esi]
inc esi
call get_label_id
pop ebx
cmp eax,0Fh
je non_label_identified
mov byte [edi],2
inc edi
stos dword [edi]
xor al,al
stos byte [edi]
jmp argument_parsed
parse_public_directive:
cmp byte [esi],1Ah
jne parse_argument
inc esi
push esi
movzx ecx,byte [esi]
inc esi
mov al,2
stos byte [edi]
call get_label_id
stos dword [edi]
mov ax,8600h
stos word [edi]
pop ebx
push ebx esi edi
mov edi,directive_operators
call get_operator
pop edi edx ebx
cmp al,86h
je argument_parsed
mov esi,edx
xchg esi,ebx
movzx ecx,byte [esi]
inc esi
mov ax,'('
stos word [edi]
mov eax,ecx
stos dword [edi]
rep movs byte [edi],[esi]
xor al,al
stos byte [edi]
xchg esi,ebx
jmp argument_parsed
parse_extrn_directive:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -