/programs/fasm/trunk/assemble.inc |
---|
0,0 → 1,1960 |
; flat assembler core |
; Copyright (c) 1999-2005, Tomasz Grysztar. |
; All rights reserved. |
assembler: |
mov ecx,[memory_end] |
mov edi,[labels_list] |
sub ecx,edi |
cmp edi,[code_start] |
jbe out_of_memory |
shr ecx,2 |
xor eax,eax |
rep stos dword [edi] |
mov [stub_size],eax |
mov [number_of_sections],eax |
mov [current_pass],ax |
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 esi,[source_start] |
mov edi,[code_start] |
xor eax,eax |
mov dword [adjustment],eax |
mov dword [adjustment+4],eax |
mov dword [org_origin],edi |
mov dword [org_origin+4],eax |
mov [org_start],edi |
mov [org_registers],eax |
mov [org_symbol],eax |
mov [error_line],eax |
mov [counter],eax |
mov [format_flags],eax |
mov [number_of_relocations],eax |
mov [undefined_data_end],eax |
mov [next_pass_needed],al |
mov [output_format],al |
mov [labels_type],al |
mov [virtual_data],al |
mov [code_type],16 |
pass_loop: |
call assemble_line |
jnc pass_loop |
mov eax,[additional_memory_end] |
cmp eax,[structures_buffer] |
je pass_done |
sub eax,20h |
mov eax,[eax+4] |
mov [current_line],eax |
jmp missing_end_directive |
pass_done: |
call close_pass |
mov eax,[labels_list] |
check_symbols: |
cmp eax,[memory_end] |
jae symbols_checked |
test byte [eax+8],8 |
jz symbol_defined_ok |
mov cx,[current_pass] |
cmp cx,[eax+18] |
jne symbol_defined_ok |
test byte [eax+8],1 |
jz symbol_defined_ok |
sub cx,[eax+16] |
cmp cx,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 use_prediction_ok |
mov cx,[current_pass] |
and byte [eax+8],not 10h |
test byte [eax+8],20h |
jnz check_use_prediction |
cmp cx,[eax+18] |
jne use_prediction_ok |
test byte [eax+8],8 |
jz use_prediction_ok |
jmp use_misprediction |
check_use_prediction: |
test byte [eax+8],8 |
jz use_misprediction |
cmp cx,[eax+18] |
je use_prediction_ok |
use_misprediction: |
or [next_pass_needed],-1 |
use_prediction_ok: |
test byte [eax+8],40h |
jz check_next_symbol |
and byte [eax+8],not 40h |
test byte [eax+8],4 |
jnz define_misprediction |
mov cx,[current_pass] |
test byte [eax+8],80h |
jnz check_define_prediction |
cmp cx,[eax+16] |
jne check_next_symbol |
test byte [eax+8],1 |
jz check_next_symbol |
jmp define_misprediction |
check_define_prediction: |
test byte [eax+8],1 |
jz define_misprediction |
cmp cx,[eax+16] |
je check_next_symbol |
define_misprediction: |
or [next_pass_needed],-1 |
check_next_symbol: |
add eax,24 |
jmp check_symbols |
symbols_checked: |
cmp [next_pass_needed],0 |
jne next_pass |
mov eax,[error_line] |
or eax,eax |
jz assemble_ok |
mov [current_line],eax |
jmp near [error] |
next_pass: |
inc [current_pass] |
mov ax,[current_pass] |
cmp ax,[passes_limit] |
je code_cannot_be_generated |
jmp assembler_loop |
assemble_ok: |
ret |
assemble_line: |
mov eax,[display_buffer] |
sub eax,100h |
cmp edi,eax |
ja out_of_memory |
lods byte [esi] |
cmp al,1 |
je assemble_instruction |
jb source_end |
cmp al,3 |
jb define_label |
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 |
mov [prefixed_instruction],0 |
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 |
mov eax,edi |
xor edx,edx |
sub eax,dword [org_origin] |
sbb edx,dword [org_origin+4] |
mov ch,[labels_type] |
cmp [virtual_data],0 |
jne make_virtual_label |
or byte [ebx+9],1 |
xchg eax,[ebx] |
xchg edx,[ebx+4] |
sub eax,[ebx] |
sbb edx,[ebx+4] |
mov dword [adjustment],eax |
mov dword [adjustment+4],edx |
or eax,edx |
setnz ah |
jmp finish_label_symbol |
make_virtual_label: |
and byte [ebx+9],not 1 |
cmp eax,[ebx] |
mov [ebx],eax |
setne ah |
cmp edx,[ebx+4] |
mov [ebx+4],edx |
setne al |
or ah,al |
finish_label_symbol: |
cmp cl,[ebx+10] |
mov [ebx+10],cl |
setne al |
or ah,al |
cmp ch,[ebx+11] |
mov [ebx+11],ch |
setne al |
or ah,al |
mov edx,[org_registers] |
cmp edx,[ebx+12] |
mov [ebx+12],edx |
setne al |
or ah,al |
or ch,ch |
jz label_symbol_ok |
mov edx,[org_symbol] |
cmp edx,[ebx+20] |
mov [ebx+20],edx |
setne al |
or ah,al |
label_symbol_ok: |
mov cx,[current_pass] |
xchg [ebx+16],cx |
and byte [ebx+8],not 2 |
test byte [ebx+8],1 |
jz new_label |
cmp cx,[ebx+16] |
je symbol_already_defined |
inc cx |
sub cx,[ebx+16] |
setnz al |
or ah,al |
jz continue_line |
test byte [ebx+8],8 |
jz continue_line |
mov cx,[current_pass] |
cmp cx,[ebx+18] |
jne continue_line |
or [next_pass_needed],-1 |
jmp continue_line |
new_label: |
or byte [ebx+8],1 |
jmp continue_line |
define_constant: |
lods dword [esi] |
inc esi |
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 cx,[current_pass] |
cmp cx,[eax+16] |
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] |
cmp ebx,0Fh |
jb invalid_use_of_symbol |
je reserved_word_used_as_symbol |
xor cl,cl |
mov ch,[value_type] |
cmp ch,3 |
je invalid_use_of_symbol |
make_constant: |
and byte [ebx+9],not 1 |
cmp eax,[ebx] |
mov [ebx],eax |
setne ah |
cmp edx,[ebx+4] |
mov [ebx+4],edx |
setne al |
or ah,al |
cmp cl,[ebx+10] |
mov [ebx+10],cl |
setne al |
or ah,al |
cmp ch,[ebx+11] |
mov [ebx+11],ch |
setne al |
or ah,al |
xor edx,edx |
cmp edx,[ebx+12] |
mov [ebx+12],edx |
setne al |
or ah,al |
or ch,ch |
jz constant_symbol_ok |
mov edx,[symbol_identifier] |
cmp edx,[ebx+20] |
mov [ebx+20],edx |
setne al |
or ah,al |
constant_symbol_ok: |
mov cx,[current_pass] |
xchg [ebx+16],cx |
test byte [ebx+8],1 |
jz new_constant |
cmp cx,[ebx+16] |
jne redeclare_constant |
test byte [ebx+8],2 |
jz symbol_already_defined |
or byte [ebx+8],4 |
jmp instruction_assembled |
redeclare_constant: |
inc cx |
sub cx,[ebx+16] |
setnz al |
or ah,al |
jz instruction_assembled |
test byte [ebx+8],4 |
jnz instruction_assembled |
test byte [ebx+8],8 |
jz instruction_assembled |
mov cx,[current_pass] |
cmp cx,[ebx+18] |
jne instruction_assembled |
or [next_pass_needed],-1 |
jmp instruction_assembled |
new_constant: |
or byte [ebx+8],1+2 |
jmp instruction_assembled |
assemble_instruction: |
mov [operand_size],0 |
mov [size_override],0 |
mov [operand_prefix],0 |
mov [rex_prefix],0 |
mov [immediate_size],0 |
movzx ebx,word [esi] |
mov al,[esi+2] |
add ebx,assembler |
add esi,3 |
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_qword_value |
mov cl,[value_type] |
test cl,1 |
jnz invalid_use_of_symbol |
mov [labels_type],cl |
mov ecx,edi |
sub ecx,eax |
sbb edx,0 |
mov dword [org_origin],ecx |
mov dword [org_origin+4],edx |
mov [org_registers],0 |
mov [org_start],edi |
mov edx,[symbol_identifier] |
mov [org_symbol],edx |
cmp [output_format],1 |
ja instruction_assembled |
cmp edi,[code_start] |
jne instruction_assembled |
cmp eax,100h |
jne instruction_assembled |
bts [format_flags],0 |
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 |
xor edx,edx |
sub eax,dword [org_origin] |
sbb edx,dword [org_origin+4] |
mov ebp,[org_registers] |
cmp byte [esi],80h |
je get_free_label_value |
mov ch,[labels_type] |
push [org_symbol] |
pop [address_symbol] |
cmp [virtual_data],0 |
jne make_free_label |
or byte [ebx+9],1 |
xchg eax,[ebx] |
xchg edx,[ebx+4] |
sub eax,[ebx] |
sbb edx,[ebx+4] |
mov dword [adjustment],eax |
mov dword [adjustment+4],edx |
or eax,edx |
setne ah |
jmp finish_label |
get_free_label_value: |
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] |
mov ch,[value_type] |
or ch,ch |
jz make_free_label |
cmp ch,2 |
jne invalid_use_of_symbol |
make_free_label: |
and byte [ebx+9],not 1 |
cmp eax,[ebx] |
mov [ebx],eax |
setne ah |
cmp edx,[ebx+4] |
mov [ebx+4],edx |
setne al |
or ah,al |
jmp finish_label |
finish_label: |
cmp cl,[ebx+10] |
mov [ebx+10],cl |
setne al |
or ah,al |
cmp ch,[ebx+11] |
mov [ebx+11],ch |
setne al |
or ah,al |
cmp ebp,[ebx+12] |
mov [ebx+12],ebp |
setne al |
or ah,al |
or ch,ch |
jz free_label_symbol_ok |
mov edx,[address_symbol] |
cmp edx,[ebx+20] |
mov [ebx+20],edx |
setne al |
or ah,al |
free_label_symbol_ok: |
mov cx,[current_pass] |
xchg [ebx+16],cx |
and byte [ebx+8],not 2 |
test byte [ebx+8],1 |
jz new_free_label |
cmp cx,[ebx+16] |
je symbol_already_defined |
inc cx |
sub cx,[ebx+16] |
setnz al |
or ah,al |
jz instruction_assembled |
test byte [ebx+8],8 |
jz instruction_assembled |
mov cx,[current_pass] |
cmp cx,[ebx+18] |
jne instruction_assembled |
or [next_pass_needed],-1 |
jmp instruction_assembled |
new_free_label: |
or byte [ebx+8],1 |
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 |
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 bad_load_address |
cmp esi,[org_start] |
jb bad_load_address |
mov edi,value |
movzx ecx,[operand_size] |
cmp ecx,eax |
ja bad_load_address |
rep movs byte [edi],[esi] |
jmp value_loaded |
bad_load_address: |
cmp [error_line],0 |
jne value_loaded |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],value_out_of_range |
value_loaded: |
pop edi esi |
mov eax,dword [value] |
mov edx,dword [value+4] |
pop ebx |
xor cx,cx |
jmp make_constant |
store_directive: |
cmp byte [esi],11h |
je sized_store |
lods byte [esi] |
cmp al,'(' |
jne invalid_argument |
call get_byte_value |
xor edx,edx |
movzx eax,al |
mov [operand_size],1 |
jmp store_value_ok |
sized_store: |
call get_value |
store_value_ok: |
cmp [value_type],0 |
jne invalid_use_of_symbol |
mov dword [value],eax |
mov dword [value+4],edx |
lods word [esi] |
cmp ax,80h+'(' shl 8 |
jne invalid_argument |
cmp byte [esi],'.' |
je invalid_value |
call get_relative_offset |
neg eax |
cmp [next_pass_needed],0 |
jne store_address_ok |
cmp [value_type],0 |
jne invalid_use_of_symbol |
store_address_ok: |
push esi edi |
sub edi,eax |
jc bad_store_address |
cmp edi,[org_start] |
jb bad_store_address |
mov esi,value |
movzx ecx,[operand_size] |
cmp ecx,eax |
ja bad_store_address |
rep movs byte [edi],[esi] |
mov eax,edi |
pop edi esi |
cmp edi,[undefined_data_end] |
jne instruction_assembled |
cmp eax,[undefined_data_start] |
jbe instruction_assembled |
mov [undefined_data_start],eax |
jmp instruction_assembled |
bad_store_address: |
pop edi esi |
cmp [error_line],0 |
jne instruction_assembled |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],value_out_of_range |
jmp instruction_assembled |
display_directive: |
lods byte [esi] |
cmp al,'(' |
jne invalid_argument |
cmp byte [esi],0 |
jne display_byte |
inc esi |
lods dword [esi] |
mov ecx,eax |
push edi |
mov edi,[display_buffer] |
sub edi,4 |
sub edi,eax |
mov [display_buffer],edi |
rep movs byte [edi],[esi] |
stos dword [edi] |
pop edi |
inc esi |
jmp display_next |
display_byte: |
call get_byte_value |
push edi |
mov edi,[display_buffer] |
sub edi,4+1 |
mov [display_buffer],edi |
stos byte [edi] |
mov eax,1 |
stos dword [edi] |
pop edi |
display_next: |
cmp edi,[display_buffer] |
ja out_of_memory |
lods byte [esi] |
cmp al,',' |
je display_directive |
dec 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] |
push [counter_limit] |
mov [counter_limit],eax |
mov [counter],1 |
times_loop: |
mov eax,esp |
sub eax,100h |
jc stack_overflow |
cmp eax,[stack_limit] |
jb stack_overflow |
push esi |
or [prefixed_instruction],-1 |
call continue_line |
mov eax,[counter_limit] |
cmp [counter],eax |
je times_done |
inc [counter] |
pop esi |
jmp times_loop |
times_done: |
pop eax |
pop [counter_limit] |
pop [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 |
mov ebp,[address_symbol] |
xor ch,ch |
or bh,bh |
jz set_virtual |
mov ch,1 |
jmp set_virtual |
virtual_at_current: |
dec esi |
mov al,[labels_type] |
mov [value_type],al |
mov ebp,[org_symbol] |
mov eax,edi |
xor edx,edx |
sub eax,dword [org_origin] |
sbb edx,dword [org_origin+4] |
xor bx,bx |
xor cx,cx |
set_virtual: |
push [org_registers] |
mov byte [org_registers],bh |
mov byte [org_registers+1],bl |
mov byte [org_registers+2],ch |
mov byte [org_registers+3],cl |
call allocate_structure_data |
mov word [ebx],virtual_directive-assembler |
not eax |
not edx |
add eax,1 |
adc edx,0 |
add eax,edi |
adc edx,0 |
xchg dword [org_origin],eax |
xchg dword [org_origin+4],edx |
mov [ebx+10h],eax |
mov [ebx+14h],edx |
pop eax |
mov [ebx+18h],eax |
mov al,[virtual_data] |
mov [ebx+2],al |
mov al,[labels_type] |
mov [ebx+3],al |
mov eax,edi |
xchg eax,[org_start] |
mov [ebx+0Ch],eax |
xchg ebp,[org_symbol] |
mov [ebx+1Ch],ebp |
mov [ebx+8],edi |
mov eax,[current_line] |
mov [ebx+4],eax |
or [virtual_data],-1 |
mov al,[value_type] |
test al,1 |
jnz invalid_use_of_symbol |
mov [labels_type],al |
jmp instruction_assembled |
allocate_structure_data: |
mov ebx,[structures_buffer] |
sub ebx,20h |
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,if_directive-assembler |
je check_structure_overlapping |
cmp ax,repeat_directive-assembler |
je check_structure_overlapping |
cmp ax,while_directive-assembler |
je check_structure_overlapping |
add ebx,20h |
jmp scan_structures |
check_structure_overlapping: |
cmp word [ebx],if_directive-assembler |
je no_such_structure |
cmp word [ebx],repeat_directive-assembler |
je no_such_structure |
cmp word [ebx],while_directive-assembler |
je no_such_structure |
add ebx,20h |
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 [labels_type],al |
mov eax,[ebx+10h] |
mov dword [org_origin],eax |
mov eax,[ebx+14h] |
mov dword [org_origin+4],eax |
mov eax,[ebx+18h] |
mov [org_registers],eax |
mov eax,[ebx+0Ch] |
mov [org_start],eax |
mov eax,[ebx+1Ch] |
mov [org_symbol],eax |
mov edi,[ebx+8] |
remove_structure_data: |
push esi edi |
mov esi,[structures_buffer] |
mov ecx,ebx |
sub ecx,esi |
lea edi,[esi+20h] |
mov [structures_buffer],edi |
shr ecx,2 |
rep movs dword [edi],[esi] |
pop edi esi |
ret |
repeat_directive: |
cmp [prefixed_instruction],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+10h],eax |
mov eax,1 |
xchg eax,[counter] |
mov [ebx+14h],eax |
mov [ebx+8],esi |
mov eax,[current_line] |
mov [ebx+4],eax |
jmp instruction_assembled |
end_repeat: |
cmp [prefixed_instruction],0 |
jne unexpected_instruction |
call find_structure_data |
jc unexpected_instruction |
mov eax,[counter_limit] |
inc [counter] |
cmp [counter],eax |
jbe continue_repeating |
stop_repeat: |
mov eax,[ebx+10h] |
mov [counter_limit],eax |
mov eax,[ebx+14h] |
mov [counter],eax |
call remove_structure_data |
jmp instruction_assembled |
continue_repeating: |
mov esi,[ebx+8] |
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 missing_end_directive |
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 |
while_directive: |
cmp [prefixed_instruction],0 |
jne unexpected_instruction |
call allocate_structure_data |
mov word [ebx],while_directive-assembler |
mov eax,1 |
xchg eax,[counter] |
mov [ebx+10h],eax |
mov [ebx+8],esi |
mov eax,[current_line] |
mov [ebx+4],eax |
do_while: |
push ebx |
call calculate_logical_expression |
or al,al |
jnz while_true |
mov al,[esi] |
or al,al |
jz missing_end_directive |
cmp al,0Fh |
jne extra_characters_on_line |
stop_while: |
call find_end_while |
pop ebx |
mov eax,[ebx+10h] |
mov [counter],eax |
call remove_structure_data |
jmp instruction_assembled |
while_true: |
pop ebx |
jmp instruction_assembled |
end_while: |
cmp [prefixed_instruction],0 |
jne unexpected_instruction |
call find_structure_data |
jc unexpected_instruction |
mov eax,[ebx+4] |
mov [current_line],eax |
inc [counter] |
jz too_many_repeats |
mov esi,[ebx+8] |
jmp do_while |
find_end_while: |
call find_structure_end |
cmp ax,while_directive-assembler |
jne unexpected_instruction |
ret |
if_directive: |
cmp [prefixed_instruction],0 |
jne unexpected_instruction |
call calculate_logical_expression |
mov dl,al |
mov al,[esi] |
or al,al |
jz missing_end_directive |
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: |
xor al,al |
make_if_structure: |
call allocate_structure_data |
mov word [ebx],if_directive-assembler |
mov byte [ebx+2],al |
mov eax,[current_line] |
mov [ebx+4],eax |
jmp instruction_assembled |
else_true: |
or al,al |
jz missing_end_directive |
cmp al,0Fh |
jne extra_characters_on_line |
or al,-1 |
jmp make_if_structure |
else_directive: |
cmp [prefixed_instruction],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 |
call remove_structure_data |
jmp instruction_assembled |
skip_else: |
or al,al |
jz missing_end_directive |
cmp al,0Fh |
jne extra_characters_on_line |
call find_end_if |
call remove_structure_data |
jmp instruction_assembled |
end_if: |
cmp [prefixed_instruction],0 |
jne unexpected_instruction |
call find_structure_data |
jc unexpected_instruction |
call remove_structure_data |
jmp instruction_assembled |
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 |
find_structure_end: |
push [error_line] |
mov eax,[current_line] |
mov [error_line],eax |
find_end_directive: |
call skip_line |
lods byte [esi] |
cmp al,0Fh |
jne no_end_directive |
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_end_directive |
mov ax,[esi+1] |
cmp ax,prefix_instruction-assembler |
je find_end_directive |
add esi,4 |
cmp ax,repeat_directive-assembler |
je skip_repeat |
cmp ax,while_directive-assembler |
je skip_while |
cmp ax,if_directive-assembler |
je skip_if |
cmp ax,else_directive-assembler |
je structure_end |
cmp ax,end_directive-assembler |
jne find_end_directive |
cmp byte [esi],1 |
jne find_end_directive |
mov ax,[esi+1] |
add esi,4 |
cmp ax,repeat_directive-assembler |
je structure_end |
cmp ax,while_directive-assembler |
je structure_end |
cmp ax,if_directive-assembler |
jne find_end_directive |
structure_end: |
pop [error_line] |
ret |
no_end_directive: |
mov eax,[error_line] |
mov [current_line],eax |
jmp missing_end_directive |
skip_repeat: |
call find_end_repeat |
jmp find_end_directive |
skip_while: |
call find_end_while |
jmp find_end_directive |
skip_if: |
call skip_if_block |
jmp find_end_directive |
skip_if_block: |
call find_else |
jc if_block_skipped |
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_block |
skip_after_else: |
call find_end_if |
if_block_skipped: |
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,while_directive-assembler |
je end_while |
cmp ax,if_directive-assembler |
je end_if |
cmp ax,data_directive-assembler |
je end_data |
jmp invalid_argument |
break_directive: |
mov ebx,[structures_buffer] |
mov al,[esi] |
or al,al |
jz find_breakable_structure |
cmp al,0Fh |
jne extra_characters_on_line |
find_breakable_structure: |
cmp ebx,[additional_memory_end] |
je unexpected_instruction |
mov ax,[ebx] |
cmp ax,repeat_directive-assembler |
je break_repeat |
cmp ax,while_directive-assembler |
je break_while |
cmp ax,if_directive-assembler |
je break_if |
add ebx,20h |
jmp find_breakable_structure |
break_if: |
push [current_line] |
mov eax,[ebx+4] |
mov [current_line],eax |
call remove_structure_data |
call skip_if_block |
pop [current_line] |
mov ebx,[structures_buffer] |
jmp find_breakable_structure |
break_repeat: |
push ebx |
call find_end_repeat |
pop ebx |
jmp stop_repeat |
break_while: |
push ebx |
jmp stop_while |
data_bytes: |
call define_data |
lods byte [esi] |
cmp al,'(' |
je get_byte |
cmp al,'?' |
jne invalid_argument |
mov eax,edi |
mov byte [edi],0 |
inc edi |
jmp undefined_data |
get_byte: |
cmp byte [esi],0 |
je get_string |
call get_byte_value |
stos byte [edi] |
ret |
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 |
ret |
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 |
define_data: |
cmp edi,[display_buffer] |
jae out_of_memory |
cmp byte [esi],'(' |
jne simple_data_value |
mov ebx,esi |
inc esi |
call skip_expression |
xchg esi,ebx |
cmp byte [ebx],81h |
jne simple_data_value |
inc esi |
call get_dword_value |
cmp [next_pass_needed],0 |
jne dup_value_ok |
cmp [value_type],0 |
jne invalid_use_of_symbol |
dup_value_ok: |
inc esi |
cmp eax,0 |
jg dup_positive |
cmp [error_line],0 |
jne dup_invalid |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],invalid_value |
dup_invalid: |
mov eax,1 |
dup_positive: |
cmp byte [esi],'{' |
jne duplicate_single_data_value |
inc esi |
duplicate_data: |
push eax esi |
duplicated_values: |
cmp edi,[display_buffer] |
jae out_of_memory |
call near dword [esp+8] |
lods byte [esi] |
cmp al,',' |
je duplicated_values |
cmp al,'}' |
jne invalid_argument |
pop ebx eax |
dec eax |
jz data_defined |
mov esi,ebx |
jmp duplicate_data |
duplicate_single_data_value: |
cmp edi,[display_buffer] |
jae out_of_memory |
push eax esi |
call near dword [esp+8] |
pop ebx eax |
dec eax |
jz data_defined |
mov esi,ebx |
jmp duplicate_single_data_value |
simple_data_value: |
cmp edi,[display_buffer] |
jae out_of_memory |
call near dword [esp] |
data_defined: |
lods byte [esi] |
cmp al,',' |
je define_data |
dec esi |
add esp,4 |
jmp instruction_assembled |
data_unicode: |
or [base_code],-1 |
jmp define_words |
data_words: |
mov [base_code],0 |
define_words: |
call define_data |
lods byte [esi] |
cmp al,'(' |
je get_word |
cmp al,'?' |
jne invalid_argument |
mov eax,edi |
mov word [edi],0 |
scas word [edi] |
jmp undefined_data |
ret |
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] |
ret |
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 |
ret |
data_dwords: |
call define_data |
lods byte [esi] |
cmp al,'(' |
je get_dword |
cmp al,'?' |
jne invalid_argument |
mov eax,edi |
mov dword [edi],0 |
scas dword [edi] |
jmp undefined_data |
get_dword: |
push esi |
call get_dword_value |
pop ebx |
cmp byte [esi],':' |
je complex_dword |
call mark_relocation |
stos dword [edi] |
ret |
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] |
ret |
data_pwords: |
call define_data |
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] |
jmp undefined_data |
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] |
ret |
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] |
ret |
data_qwords: |
call define_data |
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] |
jmp undefined_data |
get_qword: |
call get_qword_value |
call mark_relocation |
stos dword [edi] |
mov eax,edx |
stos dword [edi] |
ret |
data_twords: |
call define_data |
lods byte [esi] |
cmp al,'(' |
je get_tword |
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] |
jmp undefined_data |
get_tword: |
cmp byte [esi],'.' |
jne complex_tword |
inc esi |
cmp word [esi+8],8000h |
je fp_zero_tword |
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,13 |
ret |
fp_zero_tword: |
xor eax,eax |
stos dword [edi] |
stos dword [edi] |
mov al,[esi+11] |
shl ax,15 |
stos word [edi] |
add esi,13 |
ret |
complex_tword: |
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_qword_value |
call mark_relocation |
stos dword [edi] |
mov eax,edx |
stos dword [edi] |
pop eax |
mov [value_type],al |
pop eax |
call mark_relocation |
stos word [edi] |
ret |
data_file: |
lods word [esi] |
cmp ax,'(' |
jne invalid_argument |
add esi,4 |
call open_binary_file |
mov eax,[esi-4] |
lea esi,[esi+eax+1] |
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: |
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 |
lods byte [esi] |
cmp al,',' |
je data_file |
dec esi |
jmp instruction_assembled |
open_binary_file: |
push esi |
push edi |
mov esi,[current_line] |
mov esi,[esi] |
get_current_path: |
lodsb |
stosb |
or al,al |
jnz get_current_path |
cut_current_path: |
cmp edi,[esp] |
je current_path_ok |
cmp byte [edi-1],'\' |
je current_path_ok |
cmp byte [edi-1],'/' |
je current_path_ok |
dec edi |
jmp cut_current_path |
current_path_ok: |
mov esi,[esp+4] |
call preprocess_path |
pop edx |
mov esi,edx |
call open |
jnc file_opened |
mov edi,esi |
mov esi,[esp] |
push edi |
call preprocess_path |
pop edx |
mov esi,edx |
call open |
jc file_not_found |
file_opened: |
mov edi,esi |
pop esi |
ret |
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 |
align_directive: |
lods byte [esi] |
cmp al,'(' |
jne invalid_argument |
cmp byte [esi],'.' |
je invalid_value |
call get_dword_value |
cmp [value_type],0 |
jne invalid_use_of_symbol |
mov edx,eax |
dec edx |
test eax,edx |
jnz invalid_value |
or eax,eax |
jz invalid_value |
cmp eax,1 |
je instruction_assembled |
mov ecx,edi |
sub ecx,dword [org_origin] |
cmp [org_registers],0 |
jne section_not_aligned_enough |
cmp [labels_type],0 |
je make_alignment |
cmp [output_format],3 |
je pe_alignment |
mov ebx,[org_symbol] |
cmp byte [ebx],0 |
jne section_not_aligned_enough |
cmp eax,[ebx+10h] |
jbe make_alignment |
jmp section_not_aligned_enough |
pe_alignment: |
cmp eax,1000h |
ja section_not_aligned_enough |
make_alignment: |
dec eax |
and ecx,eax |
jz instruction_assembled |
neg ecx |
add ecx,eax |
inc ecx |
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 nops |
add edi,ecx |
jmp reserved_data |
nops: |
mov eax,90909090h |
shr ecx,1 |
jnc nops_stosb_ok |
stos byte [edi] |
nops_stosb_ok: |
shr ecx,1 |
jnc nops_stosw_ok |
stos word [edi] |
nops_stosw_ok: |
rep stos dword [edi] |
jmp reserved_data |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/programs/fasm/trunk/build_en.bat |
---|
0,0 → 1,4 |
@erase lang.inc |
@echo lang fix en >lang.inc |
@fasm fasm.asm fasm |
@pause |
/programs/fasm/trunk/build_ru.bat |
---|
0,0 → 1,4 |
@erase lang.inc |
@echo lang fix ru >lang.inc |
@fasm fasm.asm fasm |
@pause |
/programs/fasm/trunk/errors.inc |
---|
0,0 → 1,131 |
; flat assembler core |
; Copyright (c) 1999-2005, Tomasz Grysztar. |
; All rights reserved. |
out_of_memory: |
call fatal_error |
db 'out of memory',0 |
stack_overflow: |
call fatal_error |
db 'out of stack space',0 |
main_file_not_found: |
call fatal_error |
db 'source file not found',0 |
unexpected_end_of_file: |
call fatal_error |
db 'unexpected end of file',0 |
code_cannot_be_generated: |
call fatal_error |
db 'code cannot be generated',0 |
format_limitations_exceeded: |
call fatal_error |
db 'format limitations exceeded',0 |
write_failed: |
call fatal_error |
db 'write failed',0 |
file_not_found: |
call assembler_error |
db 'file not found',0 |
error_reading_file: |
call assembler_error |
db 'error reading file',0 |
invalid_file_format: |
call assembler_error |
db 'invalid file format',0 |
invalid_macro_arguments: |
call assembler_error |
db 'invalid macro arguments',0 |
incomplete_macro: |
call assembler_error |
db 'incomplete macro',0 |
unexpected_characters: |
call assembler_error |
db 'unexpected characters',0 |
invalid_argument: |
call assembler_error |
db 'invalid argument',0 |
illegal_instruction: |
call assembler_error |
db 'illegal instruction',0 |
invalid_operand: |
call assembler_error |
db 'invalid operand',0 |
invalid_operand_size: |
call assembler_error |
db 'invalid size of operand',0 |
operand_size_not_specified: |
call assembler_error |
db 'operand size not specified',0 |
operand_sizes_do_not_match: |
call assembler_error |
db 'operand sizes do not match',0 |
invalid_address_size: |
call assembler_error |
db 'invalid size of address value',0 |
address_sizes_do_not_agree: |
call assembler_error |
db 'address sizes do not agree',0 |
prefix_conflict: |
call assembler_error |
db 'disallowed combination of registers',0 |
long_immediate_not_encodable: |
call assembler_error |
db 'not encodable with long immediate',0 |
relative_jump_out_of_range: |
call assembler_error |
db 'relative jump out of range',0 |
invalid_expression: |
call assembler_error |
db 'invalid expression',0 |
invalid_address: |
call assembler_error |
db 'invalid address',0 |
invalid_value: |
call assembler_error |
db 'invalid value',0 |
value_out_of_range: |
call assembler_error |
db 'value out of range',0 |
undefined_symbol: |
call assembler_error |
db 'undefined symbol',0 |
invalid_use_of_symbol: |
call assembler_error |
db 'invalid use of symbol',0 |
name_too_long: |
call assembler_error |
db 'name too long',0 |
invalid_name: |
call assembler_error |
db 'invalid name',0 |
reserved_word_used_as_symbol: |
call assembler_error |
db 'reserved word used as symbol',0 |
symbol_already_defined: |
call assembler_error |
db 'symbol already defined',0 |
missing_end_quote: |
call assembler_error |
db 'missing end quote',0 |
missing_end_directive: |
call assembler_error |
db 'missing end directive',0 |
unexpected_instruction: |
call assembler_error |
db 'unexpected instruction',0 |
extra_characters_on_line: |
call assembler_error |
db 'extra characters on line',0 |
section_not_aligned_enough: |
call assembler_error |
db 'section is not aligned enough',0 |
setting_already_specified: |
call assembler_error |
db 'setting already specified',0 |
data_already_defined: |
call assembler_error |
db 'data already defined',0 |
too_many_repeats: |
call assembler_error |
db 'too many repeats',0 |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/programs/fasm/trunk/expressi.inc |
---|
0,0 → 1,2443 |
; flat assembler core |
; Copyright (c) 1999-2005, Tomasz Grysztar. |
; All rights reserved. |
convert_expression: |
push ebp |
call get_fp_value |
jnc fp_expression |
mov ebp,esp |
expression_loop: |
push ebp edi |
mov edi,single_operand_operators |
call get_operator |
pop edi |
push eax |
mov al,[esi] |
cmp al,1Ah |
je expression_number |
cmp al,22h |
je expression_number |
cmp al,'(' |
je expression_number |
mov al,11h |
stos byte [edi] |
or eax,-1 |
stos dword [edi] |
jmp expression_number_ok |
expression_number: |
call convert_number |
expression_number_ok: |
pop eax |
or al,al |
jz expression_operator |
stos byte [edi] |
expression_operator: |
push edi |
mov edi,operators |
call get_operator |
pop edi ebp |
or al,al |
jz expression_end |
operators_loop: |
cmp esp,ebp |
je push_operator |
mov bl,al |
and bl,0F0h |
mov bh,byte [esp] |
and bh,0F0h |
cmp bl,bh |
ja push_operator |
pop ebx |
mov byte [edi],bl |
inc edi |
jmp operators_loop |
push_operator: |
push eax |
jmp expression_loop |
expression_end: |
cmp esp,ebp |
je expression_converted |
pop eax |
stos byte [edi] |
jmp expression_end |
expression_converted: |
pop ebp |
ret |
fp_expression: |
mov al,'.' |
stos byte [edi] |
mov eax,[fp_value] |
stos dword [edi] |
mov eax,[fp_value+4] |
stos dword [edi] |
mov eax,[fp_value+8] |
stos dword [edi] |
pop ebp |
ret |
convert_number: |
cmp byte [esi],'(' |
je expression_value |
inc edi |
call get_number |
jc symbol_value |
or ebp,ebp |
jz valid_number |
mov byte [edi-1],0Fh |
ret |
valid_number: |
cmp dword [edi+4],0 |
jne qword_number |
cmp word [edi+2],0 |
jne dword_number |
cmp byte [edi+1],0 |
jne word_number |
byte_number: |
mov byte [edi-1],1 |
inc edi |
ret |
qword_number: |
mov byte [edi-1],8 |
add edi,8 |
ret |
dword_number: |
mov byte [edi-1],4 |
scas dword [edi] |
ret |
word_number: |
mov byte [edi-1],2 |
scas word [edi] |
ret |
expression_value: |
mov eax,esp |
sub eax,100h |
jc stack_overflow |
cmp eax,[stack_limit] |
jb stack_overflow |
inc esi |
call convert_expression |
lods byte [esi] |
cmp al,')' |
jne invalid_expression |
ret |
symbol_value: |
lods byte [esi] |
cmp al,1Ah |
jne invalid_value |
lods byte [esi] |
movzx ecx,al |
push ecx esi edi |
mov edi,address_registers |
call get_symbol |
jnc register_value |
mov edi,directive_operators |
call get_symbol |
pop edi esi ecx |
jnc broken_value |
call get_label_id |
store_label_value: |
mov byte [edi-1],11h |
stos dword [edi] |
ret |
broken_value: |
sub esi,2 |
or eax,-1 |
jmp store_label_value |
register_value: |
pop edi |
add esp,8 |
mov byte [edi-1],10h |
mov al,ah |
stos byte [edi] |
ret |
get_number: |
xor ebp,ebp |
lods byte [esi] |
cmp al,22h |
je get_text_number |
cmp al,1Ah |
jne not_number |
lods byte [esi] |
movzx ecx,al |
mov [number_start],esi |
mov al,[esi] |
cmp al,'$' |
je number_begin |
sub al,30h |
cmp al,9 |
ja invalid_number |
number_begin: |
mov ebx,esi |
add esi,ecx |
push esi |
dec esi |
mov dword [edi],0 |
mov dword [edi+4],0 |
cmp byte [ebx],'$' |
je pascal_hex_number |
cmp word [ebx],'0x' |
je get_hex_number |
mov al,[esi] |
dec esi |
cmp al,'h' |
je get_hex_number |
cmp al,'b' |
je get_bin_number |
cmp al,'d' |
je get_dec_number |
cmp al,'o' |
je get_oct_number |
cmp al,'H' |
je get_hex_number |
cmp al,'B' |
je get_bin_number |
cmp al,'D' |
je get_dec_number |
cmp al,'O' |
je get_oct_number |
inc esi |
get_dec_number: |
mov ebx,esi |
mov esi,[number_start] |
get_dec_digit: |
cmp esi,ebx |
ja number_ok |
xor edx,edx |
mov eax,[edi] |
shld edx,eax,2 |
shl eax,2 |
add eax,[edi] |
adc edx,0 |
add eax,eax |
adc edx,edx |
mov [edi],eax |
mov eax,[edi+4] |
add eax,eax |
jc dec_out_of_range |
add eax,eax |
jc dec_out_of_range |
add eax,[edi+4] |
jc dec_out_of_range |
add eax,eax |
jc dec_out_of_range |
add eax,edx |
jc dec_out_of_range |
mov [edi+4],eax |
movzx eax,byte [esi] |
sub al,30h |
cmp al,9 |
ja bad_number |
add [edi],eax |
adc dword [edi+4],0 |
jc dec_out_of_range |
inc esi |
jmp get_dec_digit |
dec_out_of_range: |
or ebp,-1 |
inc esi |
jmp get_dec_digit |
bad_number: |
pop eax |
invalid_number: |
mov esi,[number_start] |
dec esi |
not_number: |
dec esi |
stc |
ret |
get_bin_number: |
xor bl,bl |
get_bin_digit: |
cmp esi,[number_start] |
jb number_ok |
movzx eax,byte [esi] |
sub al,30h |
cmp al,1 |
ja bad_number |
xor edx,edx |
mov cl,bl |
dec esi |
cmp bl,64 |
je bin_out_of_range |
inc bl |
cmp cl,32 |
jae bin_digit_high |
shl eax,cl |
or dword [edi],eax |
jmp get_bin_digit |
bin_digit_high: |
sub cl,32 |
shl eax,cl |
or dword [edi+4],eax |
jmp get_bin_digit |
bin_out_of_range: |
or al,al |
jz get_bin_digit |
or ebp,-1 |
jmp get_bin_digit |
pascal_hex_number: |
cmp cl,1 |
je bad_number |
get_hex_number: |
xor bl,bl |
get_hex_digit: |
cmp esi,[number_start] |
jb number_ok |
movzx eax,byte [esi] |
cmp al,'x' |
je hex_number_ok |
cmp al,'$' |
je pascal_hex_ok |
sub al,30h |
cmp al,9 |
jbe hex_digit_ok |
sub al,7 |
cmp al,15 |
jbe hex_letter_digit_ok |
sub al,20h |
cmp al,15 |
ja bad_number |
hex_letter_digit_ok: |
cmp al,10 |
jb bad_number |
hex_digit_ok: |
xor edx,edx |
mov cl,bl |
dec esi |
cmp bl,64 |
je hex_out_of_range |
add bl,4 |
cmp cl,32 |
jae hex_digit_high |
shl eax,cl |
or dword [edi],eax |
jmp get_hex_digit |
hex_digit_high: |
sub cl,32 |
shl eax,cl |
or dword [edi+4],eax |
jmp get_hex_digit |
hex_out_of_range: |
or al,al |
jz get_hex_digit |
or ebp,-1 |
jmp get_hex_digit |
get_oct_number: |
xor bl,bl |
get_oct_digit: |
cmp esi,[number_start] |
jb number_ok |
movzx eax,byte [esi] |
sub al,30h |
cmp al,7 |
ja bad_number |
oct_digit_ok: |
xor edx,edx |
mov cl,bl |
dec esi |
cmp bl,64 |
jae oct_out_of_range |
add bl,3 |
cmp cl,30 |
je oct_digit_wrap |
ja oct_digit_high |
shl eax,cl |
or dword [edi],eax |
jmp get_oct_digit |
oct_digit_wrap: |
shl eax,cl |
adc dword [edi+4],0 |
or dword [edi],eax |
jmp get_oct_digit |
oct_digit_high: |
sub cl,32 |
shl eax,cl |
or dword [edi+4],eax |
jmp get_oct_digit |
oct_out_of_range: |
or al,al |
jz get_oct_digit |
or ebp,-1 |
jmp get_oct_digit |
hex_number_ok: |
dec esi |
pascal_hex_ok: |
cmp esi,[number_start] |
jne bad_number |
number_ok: |
pop esi |
number_done: |
clc |
ret |
get_text_number: |
lods dword [esi] |
mov edx,eax |
xor bl,bl |
mov dword [edi],0 |
mov dword [edi+4],0 |
get_text_character: |
sub edx,1 |
jc number_done |
movzx eax,byte [esi] |
inc esi |
mov cl,bl |
cmp bl,64 |
je text_out_of_range |
add bl,8 |
cmp cl,32 |
jae text_character_high |
shl eax,cl |
or dword [edi],eax |
jmp get_text_character |
text_character_high: |
sub cl,32 |
shl eax,cl |
or dword [edi+4],eax |
jmp get_text_character |
text_out_of_range: |
or ebp,-1 |
jmp get_text_character |
get_fp_value: |
push edi esi |
lods byte [esi] |
cmp al,1Ah |
je fp_value_start |
cmp al,'-' |
je fp_sign_ok |
cmp al,'+' |
jne not_fp_value |
fp_sign_ok: |
lods byte [esi] |
cmp al,1Ah |
jne not_fp_value |
fp_value_start: |
lods byte [esi] |
movzx ecx,al |
cmp cl,1 |
jbe not_fp_value |
lea edx,[esi+1] |
xor ah,ah |
check_fp_value: |
lods byte [esi] |
cmp al,'.' |
je fp_character_dot |
cmp al,'E' |
je fp_character_exp |
cmp al,'e' |
je fp_character_exp |
cmp al,'F' |
je fp_last_character |
cmp al,'f' |
je fp_last_character |
digit_expected: |
cmp al,'0' |
jb not_fp_value |
cmp al,'9' |
ja not_fp_value |
jmp fp_character_ok |
fp_character_dot: |
cmp esi,edx |
je not_fp_value |
or ah,ah |
jnz not_fp_value |
or ah,1 |
lods byte [esi] |
loop digit_expected |
not_fp_value: |
pop esi edi |
stc |
ret |
fp_character_exp: |
cmp esi,edx |
je not_fp_value |
cmp ah,1 |
ja not_fp_value |
or ah,2 |
cmp ecx,1 |
jne fp_character_ok |
cmp byte [esi],'+' |
je fp_exp_sign |
cmp byte [esi],'-' |
jne fp_character_ok |
fp_last_character: |
cmp cl,1 |
jne not_fp_value |
or ah,4 |
jmp fp_character_ok |
fp_exp_sign: |
inc esi |
cmp byte [esi],1Ah |
jne not_fp_value |
inc esi |
lods byte [esi] |
movzx ecx,al |
inc ecx |
fp_character_ok: |
dec ecx |
jnz check_fp_value |
or ah,ah |
jz not_fp_value |
pop esi |
lods byte [esi] |
mov [fp_sign],0 |
cmp al,1Ah |
je fp_get |
inc esi |
cmp al,'+' |
je fp_get |
mov [fp_sign],1 |
fp_get: |
lods byte [esi] |
movzx ecx,al |
xor edx,edx |
mov edi,fp_value |
mov [edi],edx |
mov [edi+4],edx |
mov [edi+12],edx |
call fp_optimize |
mov [fp_format],0 |
mov al,[esi] |
fp_before_dot: |
lods byte [esi] |
cmp al,'.' |
je fp_dot |
cmp al,'E' |
je fp_exponent |
cmp al,'e' |
je fp_exponent |
cmp al,'F' |
je fp_done |
cmp al,'f' |
je fp_done |
sub al,30h |
mov edi,fp_value+16 |
xor edx,edx |
mov dword [edi+12],edx |
mov dword [edi],edx |
mov dword [edi+4],edx |
mov [edi+7],al |
mov dl,7 |
mov dword [edi+8],edx |
call fp_optimize |
mov edi,fp_value |
push ecx |
mov ecx,10 |
call fp_mul |
pop ecx |
mov ebx,fp_value+16 |
call fp_add |
loop fp_before_dot |
fp_dot: |
mov edi,fp_value+16 |
xor edx,edx |
mov [edi],edx |
mov [edi+4],edx |
mov byte [edi+7],80h |
mov [edi+8],edx |
mov dword [edi+12],edx |
dec ecx |
jz fp_done |
fp_after_dot: |
lods byte [esi] |
cmp al,'E' |
je fp_exponent |
cmp al,'e' |
je fp_exponent |
cmp al,'F' |
je fp_done |
cmp al,'f' |
je fp_done |
inc [fp_format] |
cmp [fp_format],80h |
jne fp_counter_ok |
mov [fp_format],7Fh |
fp_counter_ok: |
dec esi |
mov edi,fp_value+16 |
push ecx |
mov ecx,10 |
call fp_div |
push dword [edi] |
push dword [edi+4] |
push dword [edi+8] |
push dword [edi+12] |
lods byte [esi] |
sub al,30h |
movzx ecx,al |
call fp_mul |
mov ebx,edi |
mov edi,fp_value |
call fp_add |
mov edi,fp_value+16 |
pop dword [edi+12] |
pop dword [edi+8] |
pop dword [edi+4] |
pop dword [edi] |
pop ecx |
loop fp_after_dot |
jmp fp_done |
fp_exponent: |
or [fp_format],80h |
xor edx,edx |
xor ebp,ebp |
dec ecx |
jnz get_exponent |
cmp byte [esi],'+' |
je fp_exponent_sign |
cmp byte [esi],'-' |
jne fp_done |
not ebp |
fp_exponent_sign: |
add esi,2 |
lods byte [esi] |
movzx ecx,al |
get_exponent: |
movzx eax,byte [esi] |
inc esi |
sub al,30h |
cmp al,10 |
jae exponent_ok |
imul edx,10 |
cmp edx,8000h |
jae value_out_of_range |
add edx,eax |
loop get_exponent |
exponent_ok: |
mov edi,fp_value |
or edx,edx |
jz fp_done |
mov ecx,edx |
or ebp,ebp |
jnz fp_negative_power |
fp_power: |
push ecx |
mov ecx,10 |
call fp_mul |
pop ecx |
loop fp_power |
jmp fp_done |
fp_negative_power: |
push ecx |
mov ecx,10 |
call fp_div |
pop ecx |
loop fp_negative_power |
fp_done: |
mov edi,fp_value |
mov al,[fp_format] |
mov [edi+10],al |
mov al,[fp_sign] |
mov [edi+11],al |
test byte [edi+15],80h |
jz fp_ok |
add dword [edi],1 |
adc dword [edi+4],0 |
jnc fp_ok |
mov eax,[edi+4] |
shrd [edi],eax,1 |
shr eax,1 |
or eax,80000000h |
mov [edi+4],eax |
inc word [edi+8] |
fp_ok: |
pop edi |
clc |
ret |
fp_mul: |
or ecx,ecx |
jz fp_zero |
mov eax,[edi+12] |
mul ecx |
mov [edi+12],eax |
mov ebx,edx |
mov eax,[edi] |
mul ecx |
add eax,ebx |
adc edx,0 |
mov [edi],eax |
mov ebx,edx |
mov eax,[edi+4] |
mul ecx |
add eax,ebx |
adc edx,0 |
mov [edi+4],eax |
.loop: |
or edx,edx |
jz .done |
mov eax,[edi] |
shrd [edi+12],eax,1 |
mov eax,[edi+4] |
shrd [edi],eax,1 |
shrd eax,edx,1 |
mov [edi+4],eax |
shr edx,1 |
inc dword [edi+8] |
cmp dword [edi+8],8000h |
jge value_out_of_range |
jmp .loop |
.done: |
ret |
fp_div: |
mov eax,[edi+4] |
xor edx,edx |
div ecx |
mov [edi+4],eax |
mov eax,[edi] |
div ecx |
mov [edi],eax |
mov eax,[edi+12] |
div ecx |
mov [edi+12],eax |
mov ebx,eax |
or ebx,[edi] |
or ebx,[edi+4] |
jz fp_zero |
.loop: |
test byte [edi+7],80h |
jnz .exp_ok |
mov eax,[edi] |
shld [edi+4],eax,1 |
mov eax,[edi+12] |
shld [edi],eax,1 |
add eax,eax |
mov [edi+12],eax |
dec dword [edi+8] |
add edx,edx |
jmp .loop |
.exp_ok: |
mov eax,edx |
xor edx,edx |
div ecx |
add [edi+12],eax |
adc dword [edi],0 |
adc dword [edi+4],0 |
jnc .done |
mov eax,[edi+4] |
mov ebx,[edi] |
shrd [edi],eax,1 |
shrd [edi+12],ebx,1 |
shr eax,1 |
or eax,80000000h |
mov [edi+4],eax |
inc dword [edi+8] |
.done: |
ret |
fp_add: |
cmp dword [ebx+8],8000h |
je .done |
cmp dword [edi+8],8000h |
je .copy |
mov eax,[ebx+8] |
cmp eax,[edi+8] |
jge .exp_ok |
mov eax,[edi+8] |
.exp_ok: |
call .change_exp |
xchg ebx,edi |
call .change_exp |
xchg ebx,edi |
mov edx,[ebx+12] |
mov eax,[ebx] |
mov ebx,[ebx+4] |
add [edi+12],edx |
adc [edi],eax |
adc [edi+4],ebx |
jnc .done |
mov eax,[edi] |
shrd [edi+12],eax,1 |
mov eax,[edi+4] |
shrd [edi],eax,1 |
shr eax,1 |
or eax,80000000h |
mov [edi+4],eax |
inc dword [edi+8] |
.done: |
ret |
.copy: |
mov eax,[ebx] |
mov [edi],eax |
mov eax,[ebx+4] |
mov [edi+4],eax |
mov eax,[ebx+8] |
mov [edi+8],eax |
mov eax,[ebx+12] |
mov [edi+12],eax |
ret |
.change_exp: |
push ecx |
mov ecx,eax |
sub ecx,[ebx+8] |
mov edx,[ebx+4] |
jecxz .exp_done |
.exp_loop: |
mov ebp,[ebx] |
shrd [ebx+12],ebp,1 |
shrd [ebx],edx,1 |
shr edx,1 |
inc dword [ebx+8] |
loop .exp_loop |
.exp_done: |
mov [ebx+4],edx |
pop ecx |
ret |
fp_optimize: |
mov eax,[edi] |
mov ebp,[edi+4] |
or ebp,[edi] |
or ebp,[edi+12] |
jz fp_zero |
.loop: |
test byte [edi+7],80h |
jnz .done |
shld [edi+4],eax,1 |
mov ebp,[edi+12] |
shld eax,ebp,1 |
mov [edi],eax |
shl dword [edi+12],1 |
dec dword [edi+8] |
jmp .loop |
.done: |
ret |
fp_zero: |
mov dword [edi+8],8000h |
ret |
calculate_expression: |
mov [current_offset],edi |
mov [value_undefined],0 |
calculation_loop: |
lods byte [esi] |
or al,al |
jz get_string_value |
cmp al,'.' |
je convert_fp |
cmp al,1 |
je get_byte_number |
cmp al,2 |
je get_word_number |
cmp al,4 |
je get_dword_number |
cmp al,8 |
je get_qword_number |
cmp al,0Fh |
je value_out_of_range |
cmp al,10h |
je get_register |
cmp al,11h |
je get_label |
cmp al,')' |
je expression_calculated |
cmp al,']' |
je expression_calculated |
sub edi,14h |
mov ebx,edi |
sub ebx,14h |
cmp al,0E0h |
je calculate_rva |
cmp al,0D0h |
je calculate_not |
cmp al,0D1h |
je calculate_neg |
mov dx,[ebx+8] |
or dx,[edi+8] |
cmp al,80h |
je calculate_add |
cmp al,81h |
je calculate_sub |
mov ah,[ebx+12] |
or ah,[edi+12] |
jz absolute_values_calculation |
cmp [error_line],0 |
jne absolute_values_calculation |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],invalid_use_of_symbol |
absolute_values_calculation: |
cmp al,90h |
je calculate_mul |
cmp al,91h |
je calculate_div |
or dx,dx |
jnz invalid_expression |
cmp al,0A0h |
je calculate_mod |
cmp al,0B0h |
je calculate_and |
cmp al,0B1h |
je calculate_or |
cmp al,0B2h |
je calculate_xor |
cmp al,0C0h |
je calculate_shl |
cmp al,0C1h |
je calculate_shr |
jmp invalid_expression |
expression_calculated: |
sub edi,14h |
cmp [value_undefined],0 |
je expression_value_ok |
xor eax,eax |
mov [edi],eax |
mov [edi+4],eax |
expression_value_ok: |
ret |
get_byte_number: |
mov word [edi+8],0 |
mov byte [edi+12],0 |
xor eax,eax |
lods byte [esi] |
stos dword [edi] |
xor al,al |
stos dword [edi] |
add edi,0Ch |
jmp calculation_loop |
get_word_number: |
mov word [edi+8],0 |
mov byte [edi+12],0 |
xor eax,eax |
lods word [esi] |
stos dword [edi] |
xor ax,ax |
stos dword [edi] |
add edi,0Ch |
jmp calculation_loop |
get_dword_number: |
mov word [edi+8],0 |
mov byte [edi+12],0 |
movs dword [edi],[esi] |
xor eax,eax |
stos dword [edi] |
add edi,0Ch |
jmp calculation_loop |
get_qword_number: |
mov word [edi+8],0 |
mov byte [edi+12],0 |
movs dword [edi],[esi] |
movs dword [edi],[esi] |
add edi,0Ch |
jmp calculation_loop |
get_register: |
mov byte [edi+9],0 |
mov byte [edi+12],0 |
lods byte [esi] |
mov [edi+8],al |
mov byte [edi+10],1 |
xor eax,eax |
stos dword [edi] |
stos dword [edi] |
add edi,0Ch |
jmp calculation_loop |
get_label: |
xor eax,eax |
mov [edi+8],eax |
mov [edi+12],al |
mov [edi+20],eax |
lods dword [esi] |
cmp eax,0Fh |
jb predefined_label |
je reserved_word_used_as_symbol |
cmp eax,-1 |
je invalid_expression |
mov ebx,eax |
mov ax,[current_pass] |
mov [ebx+18],ax |
or byte [ebx+8],8 |
test byte [ebx+8],1 |
jz label_undefined |
cmp ax,[ebx+16] |
je label_defined |
test byte [ebx+8],4 |
jnz label_undefined |
test byte [ebx+9],1 |
jz label_defined |
mov eax,[ebx] |
sub eax,dword [adjustment] |
stos dword [edi] |
mov eax,[ebx+4] |
sbb eax,dword [adjustment+4] |
stos dword [edi] |
mov eax,dword [adjustment] |
or eax,dword [adjustment+4] |
jz got_label |
or [next_pass_needed],-1 |
jmp got_label |
label_defined: |
mov eax,[ebx] |
stos dword [edi] |
mov eax,[ebx+4] |
stos dword [edi] |
got_label: |
mov al,[ebx+11] |
mov [edi-8+12],al |
mov eax,[ebx+12] |
mov [edi-8+8],eax |
mov eax,[ebx+20] |
mov [edi-8+16],eax |
add edi,0Ch |
mov al,[ebx+10] |
or al,al |
jz calculation_loop |
cmp [size_override],-1 |
je calculation_loop |
cmp [size_override],0 |
je check_size |
cmp [operand_size],0 |
jne calculation_loop |
mov [operand_size],al |
jmp calculation_loop |
check_size: |
xchg [operand_size],al |
or al,al |
jz calculation_loop |
cmp al,[operand_size] |
jne operand_sizes_do_not_match |
jmp calculation_loop |
current_offset_label: |
mov al,[labels_type] |
mov [edi+12],al |
mov eax,[org_symbol] |
mov [edi+16],eax |
mov eax,[current_offset] |
xor edx,edx |
sub eax,dword [org_origin] |
sbb edx,dword [org_origin+4] |
stos dword [edi] |
mov eax,edx |
stos dword [edi] |
mov eax,[org_registers] |
stos dword [edi] |
add edi,8 |
jmp calculation_loop |
org_origin_label: |
mov al,[labels_type] |
mov [edi+12],al |
mov eax,[org_symbol] |
mov [edi+16],eax |
mov eax,[org_start] |
xor edx,edx |
sub eax,dword [org_origin] |
sbb edx,dword [org_origin+4] |
stos dword [edi] |
mov eax,edx |
stos dword [edi] |
mov eax,[org_registers] |
stos dword [edi] |
add edi,8 |
jmp calculation_loop |
counter_label: |
mov eax,[counter] |
make_dword_label_value: |
stos dword [edi] |
xor eax,eax |
stos dword [edi] |
add edi,0Ch |
jmp calculation_loop |
timestamp_label: |
call make_timestamp |
jmp make_dword_label_value |
predefined_label: |
or eax,eax |
jz current_offset_label |
cmp eax,1 |
je counter_label |
cmp eax,2 |
je timestamp_label |
cmp eax,3 |
je org_origin_label |
label_undefined: |
cmp [current_pass],1 |
jbe force_next_pass |
cmp [error_line],0 |
jne undefined_value |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],undefined_symbol |
jmp undefined_value |
force_next_pass: |
or [next_pass_needed],-1 |
undefined_value: |
mov byte [edi+12],0 |
or [value_undefined],-1 |
xor eax,eax |
stos dword [edi] |
stos dword [edi] |
add edi,0Ch |
jmp calculation_loop |
calculate_add: |
mov ecx,[ebx+16] |
cmp byte [edi+12],0 |
je add_values |
mov ecx,[edi+16] |
cmp byte [ebx+12],0 |
je add_values |
cmp [error_line],0 |
jne add_values |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],invalid_use_of_symbol |
add_values: |
mov al,[edi+12] |
or [ebx+12],al |
mov [ebx+16],ecx |
mov eax,[edi] |
add [ebx],eax |
mov eax,[edi+4] |
adc [ebx+4],eax |
or dx,dx |
jz calculation_loop |
push esi |
mov esi,ebx |
lea ebx,[edi+10] |
mov cl,[edi+8] |
call add_register |
lea ebx,[edi+11] |
mov cl,[edi+9] |
call add_register |
pop esi |
jmp calculation_loop |
add_register: |
or cl,cl |
jz add_register_done |
add_register_start: |
cmp [esi+8],cl |
jne add_in_second_slot |
mov al,[ebx] |
add [esi+10],al |
jnz add_register_done |
mov byte [esi+8],0 |
ret |
add_in_second_slot: |
cmp [esi+9],cl |
jne create_in_first_slot |
mov al,[ebx] |
add [esi+11],al |
jnz add_register_done |
mov byte [esi+9],0 |
ret |
create_in_first_slot: |
cmp byte [esi+8],0 |
jne create_in_second_slot |
mov [esi+8],cl |
mov al,[ebx] |
mov [esi+10],al |
ret |
create_in_second_slot: |
cmp byte [esi+9],0 |
jne invalid_expression |
mov [esi+9],cl |
mov al,[ebx] |
mov [esi+11],al |
add_register_done: |
ret |
calculate_sub: |
xor ah,ah |
mov ah,[ebx+12] |
mov al,[edi+12] |
or al,al |
jz sub_values |
cmp al,ah |
jne invalid_sub |
xor ah,ah |
mov ecx,[edi+16] |
cmp ecx,[ebx+16] |
je sub_values |
cmp ecx,[org_symbol] |
jne invalid_sub |
test byte [ebx+12],1 |
jnz invalid_sub |
mov ah,3 |
sub_values: |
mov [ebx+12],ah |
mov eax,[edi] |
sub [ebx],eax |
mov eax,[edi+4] |
sbb [ebx+4],eax |
or dx,dx |
jz calculation_loop |
push esi |
mov esi,ebx |
lea ebx,[edi+10] |
mov cl,[edi+8] |
call sub_register |
lea ebx,[edi+11] |
mov cl,[edi+9] |
call sub_register |
pop esi |
jmp calculation_loop |
invalid_sub: |
cmp [error_line],0 |
jne sub_values |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],invalid_use_of_symbol |
jmp sub_values |
sub_register: |
or cl,cl |
jz add_register_done |
neg byte [ebx] |
jmp add_register_start |
calculate_mul: |
or dx,dx |
jz mul_start |
cmp word [ebx+8],0 |
jne mul_start |
mov eax,[ebx] |
xchg eax,[edi] |
mov [ebx],eax |
mov eax,[ebx+4] |
xchg eax,[edi+4] |
mov [ebx+4],eax |
mov eax,[ebx+8] |
xchg eax,[edi+8] |
mov [ebx+8],eax |
mov eax,[ebx+12] |
xchg eax,[edi+12] |
mov [ebx+12],eax |
mul_start: |
push esi edx |
mov esi,ebx |
xor bl,bl |
bt dword [esi+4],31 |
jnc mul_first_sign_ok |
not dword [esi] |
not dword [esi+4] |
add dword [esi],1 |
adc dword [esi+4],0 |
not bl |
mul_first_sign_ok: |
bt dword [edi+4],31 |
jnc mul_second_sign_ok |
not dword [edi] |
not dword [edi+4] |
add dword [edi],1 |
adc dword [edi+4],0 |
not bl |
mul_second_sign_ok: |
cmp dword [esi+4],0 |
jz mul_numbers |
cmp dword [edi+4],0 |
jnz value_out_of_range |
mul_numbers: |
mov eax,[esi+4] |
mul dword [edi] |
or edx,edx |
jnz value_out_of_range |
mov ecx,eax |
mov eax,[esi] |
mul dword [edi+4] |
or edx,edx |
jnz value_out_of_range |
add ecx,eax |
jc value_out_of_range |
mov eax,[esi] |
mul dword [edi] |
add edx,ecx |
jc value_out_of_range |
test edx,1 shl 31 |
jnz value_out_of_range |
mov [esi],eax |
mov [esi+4],edx |
or bl,bl |
jz mul_ok |
not dword [esi] |
not dword [esi+4] |
add dword [esi],1 |
adc dword [esi+4],0 |
mul_ok: |
pop edx |
or dx,dx |
jz mul_calculated |
cmp word [edi+8],0 |
jne invalid_value |
cmp byte [esi+8],0 |
je mul_first_register_ok |
mov al,[edi] |
cbw |
cwde |
cdq |
cmp edx,[edi+4] |
jne value_out_of_range |
cmp eax,[edi] |
jne value_out_of_range |
imul byte [esi+10] |
mov dl,ah |
cbw |
cmp ah,dl |
jne value_out_of_range |
mov [esi+10],al |
mul_first_register_ok: |
cmp byte [esi+9],0 |
je mul_calculated |
mov al,[edi] |
cbw |
cwde |
cdq |
cmp edx,[edi+4] |
jne value_out_of_range |
cmp eax,[edi] |
jne value_out_of_range |
imul byte [esi+11] |
mov dl,ah |
cbw |
cmp ah,dl |
jne value_out_of_range |
mov [esi+11],al |
mul_calculated: |
pop esi |
jmp calculation_loop |
calculate_div: |
push esi edx |
mov esi,ebx |
call div_64 |
pop edx |
or dx,dx |
jz div_calculated |
cmp byte [esi+8],0 |
je div_first_register_ok |
mov al,[edi] |
cbw |
cwde |
cdq |
cmp edx,[edi+4] |
jne value_out_of_range |
cmp eax,[edi] |
jne value_out_of_range |
or al,al |
jz value_out_of_range |
mov al,[esi+10] |
cbw |
idiv byte [edi] |
mov [esi+10],al |
div_first_register_ok: |
cmp byte [esi+9],0 |
je div_calculated |
mov al,[edi] |
cbw |
cwde |
cdq |
cmp edx,[edi+4] |
jne value_out_of_range |
cmp eax,[edi] |
jne value_out_of_range |
or al,al |
jz value_out_of_range |
mov al,[esi+11] |
cbw |
idiv byte [edi] |
mov [esi+11],al |
div_calculated: |
pop esi |
jmp calculation_loop |
calculate_mod: |
push esi |
mov esi,ebx |
call div_64 |
mov [esi],eax |
mov [esi+4],edx |
pop esi |
jmp calculation_loop |
calculate_and: |
mov eax,[edi] |
and [ebx],eax |
mov eax,[edi+4] |
and [ebx+4],eax |
jmp calculation_loop |
calculate_or: |
mov eax,[edi] |
or [ebx],eax |
mov eax,[edi+4] |
or [ebx+4],eax |
jmp calculation_loop |
calculate_xor: |
mov eax,[edi] |
xor [ebx],eax |
mov eax,[edi+4] |
xor [ebx+4],eax |
jmp calculation_loop |
shr_negative: |
not dword [edi] |
not dword [edi+4] |
add dword [edi],1 |
adc dword [edi+4],0 |
calculate_shl: |
mov eax,dword [edi+4] |
bt eax,31 |
jc shl_negative |
or eax,eax |
jnz zero_value |
mov ecx,[edi] |
cmp ecx,64 |
jae zero_value |
cmp ecx,32 |
jae shl_high |
mov edx,[ebx+4] |
mov eax,[ebx] |
shld edx,eax,cl |
shl eax,cl |
mov [ebx],eax |
mov [ebx+4],edx |
jmp calculation_loop |
shl_high: |
sub cl,32 |
mov eax,[ebx] |
shl eax,cl |
mov [ebx+4],eax |
mov dword [ebx],0 |
jmp calculation_loop |
shl_negative: |
not dword [edi] |
not dword [edi+4] |
add dword [edi],1 |
adc dword [edi+4],0 |
calculate_shr: |
mov eax,dword [edi+4] |
bt eax,31 |
jc shr_negative |
or eax,eax |
jnz zero_value |
mov ecx,[edi] |
cmp ecx,64 |
jae zero_value |
cmp ecx,32 |
jae shr_high |
mov edx,[ebx+4] |
mov eax,[ebx] |
shrd eax,edx,cl |
shr edx,cl |
mov [ebx],eax |
mov [ebx+4],edx |
jmp calculation_loop |
shr_high: |
sub cl,32 |
mov eax,[ebx+4] |
shr eax,cl |
mov [ebx],eax |
mov dword [ebx+4],0 |
jmp calculation_loop |
zero_value: |
mov dword [ebx],0 |
mov dword [ebx+4],0 |
jmp calculation_loop |
calculate_not: |
cmp word [edi+8],0 |
jne invalid_expression |
cmp byte [edi+12],0 |
je not_ok |
cmp [error_line],0 |
jne not_ok |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],invalid_use_of_symbol |
not_ok: |
cmp [value_size],1 |
je not_byte |
cmp [value_size],2 |
je not_word |
cmp [value_size],4 |
je not_dword |
cmp [value_size],6 |
je not_pword |
not_qword: |
not dword [edi] |
not dword [edi+4] |
add edi,14h |
jmp calculation_loop |
not_byte: |
cmp dword [edi+4],0 |
jne not_qword |
cmp word [edi+2],0 |
jne not_qword |
cmp byte [edi+1],0 |
jne not_qword |
not byte [edi] |
add edi,14h |
jmp calculation_loop |
not_word: |
cmp dword [edi+4],0 |
jne not_qword |
cmp word [edi+2],0 |
jne not_qword |
not word [edi] |
add edi,14h |
jmp calculation_loop |
not_dword: |
cmp dword [edi+4],0 |
jne not_qword |
not dword [edi] |
add edi,14h |
jmp calculation_loop |
not_pword: |
cmp word [edi+6],0 |
jne not_qword |
not dword [edi] |
not word [edi+4] |
add edi,14h |
jmp calculation_loop |
calculate_neg: |
cmp word [edi+8],0 |
jne invalid_expression |
cmp byte [edi+12],0 |
je neg_ok |
cmp [error_line],0 |
jne neg_ok |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],invalid_use_of_symbol |
neg_ok: |
mov eax,[edi] |
mov edx,[edi+4] |
mov dword [edi],0 |
mov dword [edi+4],0 |
sub [edi],eax |
sbb [edi+4],edx |
add edi,14h |
jmp calculation_loop |
calculate_rva: |
cmp [output_format],3 |
jne invalid_expression |
cmp word [edi+8],0 |
jne invalid_expression |
test [format_flags],8 |
jnz pe64_rva |
cmp byte [edi+12],2 |
je rva_ok |
cmp [error_line],0 |
jne rva_ok |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],invalid_use_of_symbol |
rva_ok: |
mov byte [edi+12],0 |
mov eax,[code_start] |
mov eax,[eax+34h] |
cdq |
sub [edi],eax |
sbb [edi+4],edx |
add edi,14h |
jmp calculation_loop |
pe64_rva: |
cmp byte [edi+12],4 |
je pe64_rva_ok |
cmp [error_line],0 |
jne pe64_rva_ok |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],invalid_use_of_symbol |
pe64_rva_ok: |
mov byte [edi+12],0 |
mov eax,[code_start] |
mov edx,[eax+34h] |
mov eax,[eax+30h] |
sub [edi],eax |
sbb [edi+4],edx |
add edi,14h |
jmp calculation_loop |
div_64: |
xor ebx,ebx |
cmp dword [edi],0 |
jne divider_ok |
cmp dword [edi+4],0 |
jne divider_ok |
cmp [next_pass_needed],0 |
je value_out_of_range |
jmp div_done |
divider_ok: |
bt dword [esi+4],31 |
jnc div_first_sign_ok |
not dword [esi] |
not dword [esi+4] |
add dword [esi],1 |
adc dword [esi+4],0 |
not bx |
div_first_sign_ok: |
bt dword [edi+4],31 |
jnc div_second_sign_ok |
not dword [edi] |
not dword [edi+4] |
add dword [edi],1 |
adc dword [edi+4],0 |
not bl |
div_second_sign_ok: |
cmp dword [edi+4],0 |
jne div_high |
mov ecx,[edi] |
mov eax,[esi+4] |
xor edx,edx |
div ecx |
mov [esi+4],eax |
mov eax,[esi] |
div ecx |
mov [esi],eax |
mov eax,edx |
xor edx,edx |
jmp div_done |
div_high: |
mov eax,[esi+4] |
xor edx,edx |
div dword [edi+4] |
mov ebx,[esi] |
mov [esi],eax |
mov dword [esi+4],0 |
mov ecx,edx |
mul dword [edi] |
div_high_loop: |
cmp ecx,edx |
ja div_high_done |
jb div_high_large_correction |
cmp ebx,eax |
jae div_high_done |
div_high_correction: |
dec dword [esi] |
sub eax,[edi] |
sbb edx,[edi+4] |
jnc div_high_loop |
div_high_done: |
sub ebx,eax |
sbb ecx,edx |
mov edx,ecx |
mov eax,ebx |
ret |
div_high_large_correction: |
push eax edx |
mov eax,edx |
sub eax,ecx |
xor edx,edx |
div dword [edi+4] |
shr eax,1 |
jz div_high_small_correction |
sub [esi],eax |
push eax |
mul dword [edi+4] |
sub dword [esp+4],eax |
pop eax |
mul dword [edi] |
sub dword [esp+4],eax |
sbb dword [esp],edx |
pop edx eax |
jmp div_high_loop |
div_high_small_correction: |
pop edx eax |
jmp div_high_correction |
div_done: |
or bh,bh |
jz remainder_ok |
not eax |
not edx |
add eax,1 |
adc edx,0 |
remainder_ok: |
or bl,bl |
jz div_ok |
not dword [esi] |
not dword [esi+4] |
add dword [esi],1 |
adc dword [esi+4],0 |
div_ok: |
ret |
convert_fp: |
mov word [edi+8],0 |
mov byte [edi+12],0 |
mov al,[value_size] |
cmp al,4 |
je convert_fp_dword |
cmp al,8 |
je convert_fp_qword |
jmp invalid_value |
convert_fp_dword: |
xor eax,eax |
cmp word [esi+8],8000h |
je fp_dword_store |
mov bx,[esi+8] |
mov eax,[esi+4] |
shl eax,1 |
shr eax,9 |
jnc fp_dword_ok |
inc eax |
bt eax,23 |
jnc fp_dword_ok |
and eax,1 shl 23 - 1 |
inc bx |
shr eax,1 |
fp_dword_ok: |
add bx,7Fh |
cmp bx,100h |
jae value_out_of_range |
shl ebx,23 |
or eax,ebx |
fp_dword_store: |
mov bl,[esi+11] |
shl ebx,31 |
or eax,ebx |
mov [edi],eax |
xor eax,eax |
mov [edi+4],eax |
add esi,13 |
ret |
convert_fp_qword: |
xor eax,eax |
xor edx,edx |
cmp word [esi+8],8000h |
je fp_qword_store |
mov bx,[esi+8] |
mov eax,[esi] |
mov edx,[esi+4] |
add eax,eax |
adc edx,edx |
mov ecx,edx |
shr edx,12 |
shrd eax,ecx,12 |
jnc fp_qword_ok |
add eax,1 |
adc edx,0 |
bt edx,20 |
jnc fp_qword_ok |
and edx,1 shl 20 - 1 |
inc bx |
shr edx,1 |
rcr eax,1 |
fp_qword_ok: |
add bx,3FFh |
cmp bx,800h |
jae value_out_of_range |
shl ebx,20 |
or edx,ebx |
fp_qword_store: |
mov bl,[esi+11] |
shl ebx,31 |
or edx,ebx |
mov [edi],eax |
mov [edi+4],edx |
add esi,13 |
ret |
get_string_value: |
lods dword [esi] |
mov ecx,eax |
cmp ecx,8 |
ja value_out_of_range |
mov edx,edi |
xor eax,eax |
stos dword [edi] |
stos dword [edi] |
mov edi,edx |
rep movs byte [edi],[esi] |
mov edi,edx |
inc esi |
mov word [edi+8],0 |
mov byte [edi+12],0 |
ret |
get_byte_value: |
mov [value_size],1 |
mov [size_override],-1 |
call calculate_expression |
mov eax,[edi+16] |
mov [symbol_identifier],eax |
mov [value_type],0 |
cmp word [edi+8],0 |
jne invalid_value |
cmp byte [edi+12],0 |
je check_byte_value |
cmp [error_line],0 |
jne check_byte_value |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],invalid_use_of_symbol |
check_byte_value: |
mov eax,[edi] |
mov edx,[edi+4] |
or edx,edx |
jz byte_positive |
cmp edx,-1 |
jne range_exceeded |
cmp eax,-80h |
jb range_exceeded |
ret |
byte_positive: |
cmp eax,100h |
jae range_exceeded |
return_byte_value: |
ret |
range_exceeded: |
xor eax,eax |
xor edx,edx |
cmp [error_line],0 |
jne return_byte_value |
mov ecx,[current_line] |
mov [error_line],ecx |
mov [error],value_out_of_range |
ret |
get_word_value: |
mov [value_size],2 |
mov [size_override],-1 |
call calculate_expression |
mov eax,[edi+16] |
mov [symbol_identifier],eax |
cmp word [edi+8],0 |
jne invalid_value |
mov al,[edi+12] |
mov [value_type],al |
cmp al,2 |
jb check_word_value |
cmp [error_line],0 |
jne check_word_value |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],invalid_use_of_symbol |
check_word_value: |
mov eax,[edi] |
mov edx,[edi+4] |
or edx,edx |
jz word_positive |
cmp edx,-1 |
jne range_exceeded |
cmp eax,-8000h |
jb range_exceeded |
ret |
word_positive: |
cmp eax,10000h |
jae range_exceeded |
ret |
get_dword_value: |
mov [value_size],4 |
mov [size_override],-1 |
call calculate_expression |
mov eax,[edi+16] |
mov [symbol_identifier],eax |
cmp word [edi+8],0 |
jne invalid_value |
mov al,[edi+12] |
mov [value_type],al |
cmp al,4 |
jb check_dword_value |
cmp [error_line],0 |
jne check_dword_value |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],invalid_use_of_symbol |
check_dword_value: |
mov eax,[edi] |
mov edx,[edi+4] |
or edx,edx |
jz dword_positive |
cmp edx,-1 |
jne range_exceeded |
bt eax,31 |
jnc range_exceeded |
dword_positive: |
ret |
get_pword_value: |
mov [value_size],6 |
mov [size_override],-1 |
call calculate_expression |
mov eax,[edi+16] |
mov [symbol_identifier],eax |
cmp word [edi+8],0 |
jne invalid_value |
mov al,[edi+12] |
mov [value_type],al |
cmp al,4 |
jb check_pword_value |
cmp [error_line],0 |
jne check_pword_value |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],invalid_use_of_symbol |
check_pword_value: |
mov eax,[edi] |
mov edx,[edi+4] |
cmp edx,10000h |
jge range_exceeded |
cmp edx,-8000h |
jl range_exceeded |
ret |
get_qword_value: |
mov [value_size],8 |
mov [size_override],-1 |
call calculate_expression |
mov eax,[edi+16] |
mov [symbol_identifier],eax |
cmp word [edi+8],0 |
jne invalid_value |
mov al,[edi+12] |
mov [value_type],al |
check_qword_value: |
mov eax,[edi] |
mov edx,[edi+4] |
ret |
get_value: |
mov [operand_size],0 |
lods byte [esi] |
call get_size_operator |
cmp al,'(' |
jne invalid_value |
mov al,[operand_size] |
cmp al,1 |
je value_byte |
cmp al,2 |
je value_word |
cmp al,4 |
je value_dword |
cmp al,6 |
je value_pword |
cmp al,8 |
je value_qword |
or al,al |
jnz invalid_value |
value_qword: |
call get_qword_value |
ret |
value_pword: |
call get_pword_value |
movzx edx,dx |
ret |
value_dword: |
call get_dword_value |
xor edx,edx |
ret |
value_word: |
call get_word_value |
xor edx,edx |
movzx eax,ax |
ret |
value_byte: |
call get_byte_value |
xor edx,edx |
movzx eax,al |
ret |
get_address_value: |
mov [address_size],0 |
mov [value_size],8 |
calculate_address: |
cmp byte [esi],'.' |
je invalid_address |
call calculate_expression |
mov eax,[edi+16] |
mov [address_symbol],eax |
mov al,[edi+12] |
test al,1 |
jnz invalid_use_of_symbol |
mov [value_type],al |
or al,al |
jz address_symbol_ok |
shl al,5 |
mov ah,[address_size] |
or [address_size],al |
shr al,4 |
or ah,ah |
jz address_symbol_ok |
cmp al,ah |
jne address_sizes_do_not_agree |
address_symbol_ok: |
xor bx,bx |
xor cl,cl |
mov ch,[address_size] |
cmp word [edi+8],0 |
je check_immediate_address |
mov al,[edi+8] |
mov dl,[edi+10] |
call get_address_register |
mov al,[edi+9] |
mov dl,[edi+11] |
call get_address_register |
mov ax,bx |
shr ah,4 |
shr al,4 |
or bh,bh |
jz check_address_registers |
or bl,bl |
jz check_address_registers |
cmp al,ah |
jne invalid_address |
check_address_registers: |
or al,ah |
cmp al,4 |
je sib_allowed |
cmp al,8 |
je sib_allowed |
or cl,cl |
jz check_word_value |
cmp cl,1 |
je check_word_value |
jmp invalid_address |
get_address_register: |
or al,al |
jz address_register_ok |
cmp dl,1 |
jne scaled_register |
or bh,bh |
jnz scaled_register |
mov bh,al |
address_register_ok: |
ret |
scaled_register: |
or bl,bl |
jnz invalid_address |
mov bl,al |
mov cl,dl |
jmp address_register_ok |
sib_allowed: |
or bh,bh |
jnz check_index_scale |
cmp cl,2 |
je special_index_scale |
cmp cl,3 |
je special_index_scale |
cmp cl,5 |
je special_index_scale |
cmp cl,9 |
je special_index_scale |
check_index_scale: |
or cl,cl |
jz address_registers_ok |
cmp cl,1 |
je address_registers_ok |
cmp cl,2 |
je address_registers_ok |
cmp cl,4 |
je address_registers_ok |
cmp cl,8 |
je address_registers_ok |
jmp invalid_address |
special_index_scale: |
mov bh,bl |
dec cl |
address_registers_ok: |
jmp check_dword_value |
check_immediate_address: |
cmp [code_type],64 |
jne check_dword_value |
jmp check_qword_value |
get_relative_offset: |
mov [value_size],4 |
mov [size_override],-1 |
call calculate_expression |
calculate_relative_offset: |
push esi |
add edi,14h |
mov esi,[display_buffer] |
sub esi,7 |
lea eax,[esi-14h] |
cmp eax,edi |
jb out_of_memory |
mov byte [esi],11h |
xor eax,eax |
mov dword [esi+1],eax |
mov word [esi+5],')' shl 8 + 81h |
call calculation_loop |
pop esi |
cmp word [edi+8],0 |
jne invalid_value |
mov al,[edi+12] |
mov [value_type],al |
mov eax,[edi+16] |
mov [symbol_identifier],eax |
mov eax,[edi] |
mov edx,[edi+4] |
or edx,edx |
jz offset_positive |
cmp edx,-1 |
jne range_exceeded |
bt eax,31 |
jnc range_exceeded |
ret |
offset_positive: |
bt eax,31 |
jc range_exceeded |
ret |
calculate_logical_expression: |
call get_logical_value |
logical_loop: |
cmp byte [esi],'|' |
je logical_or |
cmp byte [esi],'&' |
je logical_and |
ret |
logical_or: |
inc esi |
push eax |
call get_logical_value |
pop ebx |
or al,bl |
jmp logical_loop |
logical_and: |
inc esi |
push eax |
call get_logical_value |
pop ebx |
and al,bl |
jmp logical_loop |
get_logical_value: |
xor al,al |
check_for_negation: |
cmp byte [esi],'~' |
jne negation_ok |
inc esi |
xor al,-1 |
jmp check_for_negation |
negation_ok: |
push eax |
mov al,[esi] |
cmp al,'{' |
je logical_expression |
cmp al,88h |
je check_for_defined |
cmp al,89h |
je check_for_used |
push esi |
cmp al,11h |
jne check_for_values |
add esi,2 |
check_for_values: |
xor bl,bl |
cmp byte [esi],'(' |
jne find_eq_symbol |
call skip_symbol |
lods byte [esi] |
cmp al,'=' |
je compare_values |
cmp al,'>' |
je compare_values |
cmp al,'<' |
je compare_values |
cmp al,0F1h |
je compare_values |
cmp al,0F2h |
je compare_values |
cmp al,0F3h |
je compare_values |
dec esi |
find_eq_symbol: |
cmp byte [esi],0F0h |
je compare_symbols |
cmp byte [esi],0F7h |
je compare_symbol_types |
cmp byte [esi],0F6h |
je scan_symbols_list |
call check_character |
jc logical_number |
cmp al,',' |
jne next_eq_symbol |
mov bl,1 |
next_eq_symbol: |
call skip_symbol |
jmp find_eq_symbol |
compare_symbols: |
inc esi |
pop ebx |
mov edx,esi |
push edi |
mov edi,ebx |
mov ecx,esi |
dec ecx |
sub ecx,edi |
repe cmps byte [esi],[edi] |
pop edi |
je symbols_equal |
mov esi,edx |
symbols_different: |
call check_character |
jc return_false |
call skip_symbol |
jmp symbols_different |
symbols_equal: |
call check_character |
jc return_true |
jmp symbols_different |
compare_symbol_types: |
inc esi |
pop ebx |
type_comparision: |
call check_character |
jc types_compared |
mov al,[esi] |
cmp al,[ebx] |
jne symbols_different |
cmp al,'(' |
jne equal_type |
mov al,[esi+1] |
mov ah,[ebx+1] |
cmp al,ah |
je equal_type |
or al,al |
jz symbols_different |
or ah,ah |
jz symbols_different |
cmp al,'.' |
je symbols_different |
cmp ah,'.' |
je symbols_different |
equal_type: |
call skip_symbol |
xchg esi,ebx |
call skip_symbol |
xchg esi,ebx |
jmp type_comparision |
types_compared: |
cmp byte [ebx],0F7h |
jne return_false |
jmp return_true |
scan_symbols_list: |
or bl,bl |
jnz invalid_expression |
xor bp,bp |
inc esi |
lods byte [esi] |
cmp al,'<' |
jne invalid_expression |
pop ebx |
mov ecx,esi |
sub ecx,2 |
sub ecx,ebx |
compare_in_list: |
mov edx,esi |
push ecx edi |
mov edi,ebx |
repe cmps byte [esi],[edi] |
pop edi ecx |
jne not_equal_in_list |
cmp byte [esi],',' |
je skip_rest_of_list |
cmp byte [esi],'>' |
jne not_equal_in_list |
skip_rest_of_list: |
mov al,[esi] |
or al,al |
jz invalid_expression |
cmp al,0Fh |
je invalid_expression |
cmp al,'>' |
je list_return_true |
call skip_symbol |
jmp skip_rest_of_list |
list_return_true: |
inc esi |
jmp return_true |
not_equal_in_list: |
mov esi,edx |
skip_list_item: |
mov al,[esi] |
or al,al |
jz invalid_expression |
cmp al,0Fh |
je invalid_expression |
cmp al,'<' |
je invalid_expression |
cmp al,'>' |
je list_return_false |
cmp al,',' |
je next_in_list |
call skip_symbol |
jmp skip_list_item |
next_in_list: |
inc esi |
jmp compare_in_list |
list_return_false: |
inc esi |
jmp return_false |
check_character: |
mov al,[esi] |
or al,al |
jz stop |
cmp al,0Fh |
je stop |
cmp al,'}' |
je stop |
cmp al,'|' |
je stop |
cmp al,'&' |
je stop |
clc |
ret |
stop: |
stc |
ret |
compare_values: |
pop esi |
call get_value |
mov bl,[value_type] |
push eax edx ebx |
lods byte [esi] |
mov [compare_type],al |
call get_value |
pop ebx |
cmp [next_pass_needed],0 |
jne values_ok |
cmp bl,[value_type] |
jne invalid_use_of_symbol |
values_ok: |
pop ecx ebx |
cmp [compare_type],'=' |
je check_equal |
cmp [compare_type],'>' |
je check_greater |
cmp [compare_type],'<' |
je check_less |
cmp [compare_type],0F1h |
je check_not_equal |
cmp [compare_type],0F2h |
je check_not_less |
cmp [compare_type],0F3h |
je check_not_greater |
jmp invalid_expression |
check_equal: |
cmp eax,ebx |
jne return_false |
cmp edx,ecx |
jne return_false |
jmp return_true |
check_greater: |
cmp edx,ecx |
jl return_true |
jg return_false |
cmp eax,ebx |
jb return_true |
jae return_false |
check_less: |
cmp edx,ecx |
jl return_false |
jg return_true |
cmp eax,ebx |
jbe return_false |
ja return_true |
check_not_less: |
cmp edx,ecx |
jl return_true |
jg return_false |
cmp eax,ebx |
jbe return_true |
ja return_false |
check_not_greater: |
cmp edx,ecx |
jl return_false |
jg return_true |
cmp eax,ebx |
jb return_false |
jae return_true |
check_not_equal: |
cmp eax,ebx |
jne return_true |
cmp edx,ecx |
jne return_true |
jmp return_false |
logical_number: |
pop esi |
call get_value |
cmp [value_type],0 |
jne invalid_expression |
or eax,edx |
jnz return_true |
jmp return_false |
check_for_defined: |
or bl,-1 |
lods word [esi] |
cmp ah,'(' |
jne invalid_expression |
check_expression: |
lods byte [esi] |
or al,al |
jz defined_string |
cmp al,'.' |
je defined_fp_value |
cmp al,')' |
je expression_checked |
cmp al,0Fh |
je check_expression |
cmp al,10h |
je defined_register |
cmp al,11h |
je check_if_symbol_defined |
cmp al,80h |
jae check_expression |
movzx eax,al |
add esi,eax |
jmp check_expression |
defined_register: |
inc esi |
jmp check_expression |
defined_fp_value: |
add esi,12 |
jmp expression_checked |
defined_string: |
lods dword [esi] |
add esi,eax |
inc esi |
jmp expression_checked |
check_if_symbol_defined: |
lods dword [esi] |
cmp eax,-1 |
je invalid_expression |
cmp eax,0Fh |
jb check_expression |
je reserved_word_used_as_symbol |
test byte [eax+8],4 |
jnz no_prediction |
test byte [eax+8],1 |
jz symbol_predicted_undefined |
mov cx,[current_pass] |
sub cx,[eax+16] |
jz check_expression |
cmp cx,1 |
ja symbol_predicted_undefined |
or byte [eax+8],40h+80h |
jmp check_expression |
no_prediction: |
test byte [eax+8],1 |
jz symbol_undefined |
mov cx,[current_pass] |
sub cx,[eax+16] |
jz check_expression |
jmp symbol_undefined |
symbol_predicted_undefined: |
or byte [eax+8],40h |
and byte [eax+8],not 80h |
symbol_undefined: |
xor bl,bl |
jmp check_expression |
expression_checked: |
mov al,bl |
jmp logical_value_ok |
check_for_used: |
lods word [esi] |
cmp ah,2 |
jne invalid_expression |
lods dword [esi] |
cmp eax,0Fh |
jb invalid_use_of_symbol |
je reserved_word_used_as_symbol |
inc esi |
test byte [eax+8],8 |
jz not_used |
mov cx,[current_pass] |
sub cx,[eax+18] |
jz return_true |
cmp cx,1 |
ja not_used |
or byte [eax+8],10h+20h |
jmp return_true |
not_used: |
or byte [eax+8],10h |
and byte [eax+8],not 20h |
return_false: |
xor al,al |
jmp logical_value_ok |
return_true: |
or al,-1 |
jmp logical_value_ok |
logical_expression: |
inc esi |
call calculate_logical_expression |
push eax |
lods byte [esi] |
cmp al,'}' |
jne invalid_expression |
pop eax |
logical_value_ok: |
pop ebx |
xor al,bl |
ret |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/programs/fasm/trunk/fasm.asm |
---|
0,0 → 1,551 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; flat assembler source ;; |
;; Copyright (c) 1999-2004, Tomasz Grysztar ;; |
;; All rights reserved. ;; |
;; ;; |
;; Menuet port by VT ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
NORMAL_MODE = 8 |
CONSOLE_MODE = 32 |
MAGIC1 = 6*(text.line_size-1)+6*2+2 |
MAGIC2 = 14 |
MAGIC3 = 1 |
MAGIC4 = 7 |
OUTPUTXY = (5+MAGIC4) shl 16 + MAGIC2*3+MAGIC3+MAGIC4+1+2 |
MAX_PATH = 100 |
APP_MEMORY = 0x00800000 |
;; Menuet header |
use32 |
org 0x0 |
db 'MENUET01' ; 8 byte id |
dd 0x01 ; header version |
dd START ; program start |
dd program_end ; program image size |
dd APP_MEMORY ; required amount of memory |
dd 0xDFFF0 ; stack |
dd params,0x0 ; parameters,icon |
include 'lang.inc' |
include 'fasm.inc' |
;include 'debug2.inc' |
center fix true |
START: ; Start of execution |
cmp [params],0 |
jz noparams |
mov ecx,10 |
mov al,' ' |
mov edi,infile |
push ecx |
cld |
rep stosd |
mov ecx,[esp] |
mov edi,outfile |
rep stosd |
pop ecx |
mov edi,path |
rep stosd |
mov esi,params |
; DEBUGF "params: %s\n",esi |
mov edi,infile |
call mov_param_str |
; mov edi,infile |
; DEBUGF " input: %s\n",edi |
inc esi |
mov edi,outfile |
call mov_param_str |
; mov edi,outfile |
; DEBUGF "output: %s\n",edi |
inc esi |
mov edi,path |
call mov_param_str |
; mov edi,path |
; DEBUGF " path: %s\n",edi |
cmp [esi], dword ',run' |
jne @f |
mov [_run_outfile],1 |
@@: |
mov [_mode],CONSOLE_MODE |
jmp start |
noparams: |
call draw_window |
still: |
mcall 10 ; Wait here for event |
dec eax ; Redraw request |
jz red |
dec eax ; Key in buffer |
jz key |
dec eax ; Button in buffer |
jz button |
jmp still |
red: ; Redraw |
call draw_window |
jmp still |
key: ; Key |
mcall 2 ; Read it and ignore |
jmp still |
button: ; Button in Window |
mcall 17 |
cmp ah,2 ; Start compiling |
je start |
cmp ah,3 ; Start compiled file |
jnz norunout |
mov edx,outfile |
call make_fullpaths |
mcall 58,file_info_start |
; xor ecx,ecx |
jmp still |
norunout: |
mov ecx,[skinh] |
add ecx,MAGIC3+MAGIC2/2-3 |
mov [ya],ecx |
cmp ah,11 ; Infile |
je f1 |
cmp ah,12 ; Outfile |
je f2 |
cmp ah,13 ; Path |
je f3 |
dec ah ; Close application |
jnz still |
mcall -1 |
skinh dd ? |
draw_window: |
pusha |
mcall 12,1 ; Start of draw |
get_sys_colors 1,0 |
mcall 0,<50,280>,<50,250>,[sc.work] ; Draw Window |
draw_caption header,header.size ; Draw Window Label Text |
mov ecx,[skinh-2] |
mov cx,word[skinh] |
madd ecx,MAGIC3,MAGIC3 |
mov ebx,[pinfo.x_size] |
madd ebx,5,-5 |
push ecx |
madd ecx,MAGIC2*3+2,MAGIC2*3+2 |
mcall 38,,,[sc.work_graph] |
pop ecx |
sub ebx,MAGIC1+3 |
mcall |
madd ecx,MAGIC2,MAGIC2 |
mcall |
madd ecx,MAGIC2,MAGIC2 |
mcall |
madd ecx,MAGIC2,MAGIC2 |
mcall |
push ebx |
mpack ebx,MAGIC1+5,MAGIC1+5 |
sub cx,MAGIC2*3 |
mcall |
mov ebx,[esp-2] |
pop bx |
mcall |
add esp,2 |
mpack ebx,5,MAGIC1-1 |
mpack ecx,[skinh],MAGIC2-2 |
madd ecx,MAGIC3+1,0 |
mcall 8,,,0x4000000B ; Button: Enter Infile |
madd ecx,MAGIC2,0 |
mcall ,,,0x4000000C ; Button: Enter Outfile |
madd ecx,MAGIC2,0 |
mcall ,,,0x4000000D ; Button: Enter Path |
mpack ebx,[pinfo.x_size],MAGIC1 |
msub ebx,MAGIC1+5+1,0 |
mpack ecx,[skinh],MAGIC2*3/2-1 |
madd ecx,MAGIC3,0 |
mcall ,,,0x00000002,[sc.work_button] |
madd ecx,MAGIC2*3/2+1,0 |
mcall ,,,0x00000003 |
mpack ebx,5+6,[skinh] ; Draw Window Text |
add bx,MAGIC3+MAGIC2/2-3 |
mov ecx,[sc.work_text] |
mov edx,text |
mov esi,text.line_size |
mov eax,4 |
newline: |
mcall |
add ebx,MAGIC2 |
add edx,text.line_size |
cmp byte[edx],'x' |
jne newline |
mov ebx,[pinfo.x_size] |
sub ebx,MAGIC1+5+1-9 |
shl ebx,16 |
mov bx,word[skinh] |
add bx,MAGIC3+(MAGIC2*3/2-1)/2-3 |
mcall ,,[sc.work_button_text],s_compile,7 |
add ebx,MAGIC2*3/2+1 |
mcall ,,,s_run |
mpack ebx,MAGIC1+5+6,[skinh] |
add ebx,MAGIC3+MAGIC2/2-3+MAGIC2*0 |
mov esi,[pinfo.x_size] |
sub esi,MAGIC1*2+5*2+6+3 |
mov eax,esi |
mov cl,6 |
div cl |
cmp al,MAX_PATH |
jbe @f |
mov al,MAX_PATH |
@@: movzx esi,al |
mcall 4,,[sc.work_text],infile |
add ebx,MAGIC2 |
mcall ,,,outfile |
add ebx,MAGIC2 |
mcall ,,,path |
call draw_messages |
mcall 12,2 ; End of Draw |
popa |
ret |
bottom_right dd ? |
draw_messages: |
mov eax,13 ; clear work area |
mpack ebx,5+MAGIC4-2,[pinfo.x_size] |
sub ebx,5*2+MAGIC4*2-1-2*2 |
mpack ecx,[skinh],[pinfo.y_size] |
madd ecx,MAGIC2*3+MAGIC3+MAGIC4+1,-(MAGIC2*3+MAGIC3+MAGIC4*2+5)+2 |
mov word[bottom_right+2],bx |
mov word[bottom_right],cx |
msub [bottom_right],7,11 |
add [bottom_right],OUTPUTXY |
sub ecx,[skinh] |
mov edx,[sc.work] |
int 0x40 |
_cy = 0 |
_sy = 2 |
_cx = 4 |
_sx = 6 |
push ebx ecx |
mpack ebx,5+MAGIC4-3,5+MAGIC4-2 |
add bx,[esp+_cx] |
mov ecx,[esp+_sy-2] |
mov cx,[esp+_sy] |
msub ecx,1,1 |
mcall 38,,,[sc.work_graph] |
mov si,[esp+_cy] |
add cx,si |
shl esi,16 |
add ecx,esi |
madd ecx,1,1 |
mcall |
mpack ebx,5+MAGIC4-3,5+MAGIC4-3 |
mov esi,[esp+_sy-2] |
mov si,cx |
mov ecx,esi |
mcall |
mov si,[esp+_cx] |
add bx,si |
shl esi,16 |
add ebx,esi |
madd ebx,1,1 |
mcall |
pop ecx ebx |
ret |
; read string |
f1: mov [addr],infile |
add [ya],MAGIC2*0 |
jmp rk |
f2: mov [addr],outfile |
add [ya],MAGIC2*1 |
jmp rk |
f3: mov [addr],path |
add [ya],MAGIC2*2 |
rk: |
mov edi,[addr] |
mov al,0 |
mov ecx,MAX_PATH |
add edi,ecx |
dec edi |
std |
repe scasb |
sub ecx,MAX_PATH |
neg ecx |
mov al,$1C ; '' |
add edi,2 |
push edi |
cld |
rep stosb |
call print_text |
pop edi |
f11:mcall 10 |
cmp eax,2 |
jne read_done |
mcall; 2 |
shr eax,8 |
cmp al,13 |
je read_done |
cmp al,8 |
jne nobs |
cmp edi,[addr] |
je f11 |
sub edi,1 |
mov byte[edi],$1C ; '_' |
call print_text |
jmp f11 |
nobs: |
movzx ebx,al |
sub ebx,$20 |
jle f11 |
sub al,[sub_table+ebx] |
keyok: |
mov ecx,[addr] |
add ecx,MAX_PATH |
cmp edi,ecx |
jae f11 |
mov [edi],al |
call print_text |
inc edi |
jmp f11 |
read_done: |
mov ecx,[addr] |
add ecx,MAX_PATH |
sub ecx,edi |
mov al,0;' ' |
cld |
rep stosb |
call print_text |
jmp still |
print_text: |
mpack ebx,MAGIC1+5+6,[pinfo.x_size] |
sub ebx,MAGIC1*2+5*2+6+3 |
movzx esi,bx |
mov ecx,[ya-2] |
mov cx,8 |
mcall 13,,,[sc.work] |
mpack ebx,MAGIC1+5+6,[ya] |
mov eax,esi |
mov cl,6 |
div cl |
cmp al,MAX_PATH |
jbe @f |
mov al,MAX_PATH |
@@: movzx esi,al |
mcall 4,,[sc.work_text],[addr] |
ret |
; DATA |
sz header,'FASM FOR MENUET' |
text: |
db ' INFILE:' |
.line_size = $-text |
db 'OUTFILE:' |
db ' PATH:' |
db 'x' |
s_compile db 'COMPILE' |
s_run db ' RUN ' |
infile db 'EXAMPLE.ASM' |
times MAX_PATH+$-infile db 0 |
outfile db 'EXAMPLE' |
times MAX_PATH+$-outfile db 0 |
path db '/RD/1/' |
times MAX_PATH+$-path db 0 |
lf db 13,10,0 |
addr dd 0x0 |
ya dd 0x0 |
zero db 0x0 |
mov_param_str: |
@@: |
mov al,[esi] |
cmp al,',' |
je @f |
cmp al,0 |
je @f |
mov [edi],al |
inc esi |
inc edi |
jmp @b |
@@: |
mov al,0 |
stosb |
ret |
start: |
cmp [_mode],NORMAL_MODE |
jne @f |
call draw_messages |
push [skinh] |
pop [textxy] |
add [textxy],OUTPUTXY |
@@: |
mov esi,_logo |
call display_string |
; |
; Fasm native code |
; |
mov [input_file],infile |
mov [output_file],outfile |
call init_memory |
call make_timestamp |
mov [start_time],eax |
call preprocessor |
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 |
call make_timestamp |
sub eax,[start_time] |
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 |
cmp [_run_outfile],0 |
je @f |
mov edx,outfile |
call make_fullpaths |
mov eax,58 |
mov ebx,file_info_start |
xor ecx,ecx |
int 0x40 |
@@: |
jmp exit_program |
include 'system.inc' |
include 'version.inc' |
include 'errors.inc' |
include 'expressi.inc' |
include 'preproce.inc' |
include 'parser.inc' |
include 'assemble.inc' |
include 'formats.inc' |
include 'x86_64.inc' |
_logo db 'flat assembler version ',VERSION_STRING,13,10,0 |
_passes_suffix db ' passes, ',0 |
_seconds_suffix db ' seconds, ',0 |
_bytes_suffix db ' bytes.',13,10,0 |
_include db 'INCLUDE',0 |
_counter db 4,'0000' |
_mode dd NORMAL_MODE |
_run_outfile dd 0 |
sub_table: |
times $41 db $00 |
times $1A db $20 |
times $25 db $00 |
times $10 db $20 |
times $30 db $00 |
times $10 db $50 |
times $04 db $00,$01 |
times $08 db $00 |
;include_debug_strings |
params db 0 ; 'TINYPAD.ASM,TINYPAD,/HD/1/TPAD4/', |
program_end: |
rb 1000h |
align 4 |
include 'variable.inc' |
program_base dd ? |
buffer_address dd ? |
memory_setting dd ? |
start_time dd ? |
sc system_colors |
pinfo process_information |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/programs/fasm/trunk/fasm.inc |
---|
0,0 → 1,147 |
center fix false |
SYSTEMCOLORS fix sc |
PROCESSINFO fix pinfo |
macro get_sys_colors wnd_skin,font_1 { |
mcall 48,3,SYSTEMCOLORS,sizeof.system_colors |
if wnd_skin <> 0 |
or [SYSTEMCOLORS+system_colors.work],0x03000000 |
end if |
if font_1 <> 0 |
or [SYSTEMCOLORS+system_colors.grab_text],0x10000000 |
end if |
} |
macro draw_caption _edx,_esi { |
mov edx,_edx |
mov esi,_esi |
call __draw_caption |
} |
macro mpack dest, hsrc, lsrc |
{ |
if (hsrc eqtype 0) & (lsrc eqtype 0) |
mov dest, (hsrc) shl 16 + lsrc |
else |
if (hsrc eqtype 0) & (~lsrc eqtype 0) |
mov dest, (hsrc) shl 16 |
add dest, lsrc |
else |
mov dest, hsrc |
shl dest, 16 |
add dest, lsrc |
end if |
end if |
} |
macro __mov reg,a,b { |
if (~a eq)&(~b eq) |
mpack reg,a,b |
else if (~a eq)&(b eq) |
mov reg,a |
end if |
} |
macro mcall a,b,c,d,e,f { |
__mov eax,a |
__mov ebx,b |
__mov ecx,c |
__mov edx,d |
__mov esi,e |
__mov edi,f |
int 0x40 |
} |
macro sz name,[data] { |
if used name |
common |
label name |
forward |
db data |
common |
.size = $-name |
end if |
} |
macro lsz name,[lng,data] { |
if used name |
common |
label name |
forward |
if lang eq lng |
db data |
end if |
common |
.size = $-name |
end if |
} |
macro mmov reg,a1,a2 { |
mov reg,(a1) shl 16 + (a2) |
} |
macro madd reg,a1,a2 { |
add reg,(a1) shl 16 + (a2) |
} |
macro msub reg,a1,a2 { |
sub reg,(a1) shl 16 + (a2) |
} |
macro jmpe reg,def,[val,lab] { |
forward |
cmp reg,val |
je lab |
common |
if ~def eq |
jmp def |
end if |
} |
macro func name { |
if used name |
name: |
} |
macro endf { |
end if |
} |
@^ fix macro comment { |
^@ fix } |
; structure definition helper |
;include '%fasminc%struct.inc' |
include 'struct.inc' |
; structures used in MeOS |
struct process_information |
cpu_usage dd ? ; +0 |
window_stack_position dw ? ; +4 |
window_stack_value dw ? ; +6 |
not_used1 dw ? ; +8 |
process_name db 12 dup(?) ; +10 |
memory_start dd ? ; +22 |
used_memory dd ? ; +26 |
PID dd ? ; +30 |
x_start dd ? ; +34 |
y_start dd ? ; +38 |
x_size dd ? ; +42 |
y_size dd ? ; +46 |
slot_state dw ? ; +50 |
not_used2 db 1024-52 dup(?) |
ends |
struct system_colors |
frame dd ? |
grab dd ? |
grab_button dd ? |
grab_button_text dd ? |
grab_text dd ? |
work dd ? |
work_button dd ? |
work_button_text dd ? |
work_text dd ? |
work_graph dd ? |
ends |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/programs/fasm/trunk/formats.inc |
---|
0,0 → 1,3802 |
; flat assembler core |
; Copyright (c) 1999-2005, Tomasz Grysztar. |
; All rights reserved. |
formatter: |
cmp [output_file],0 |
jne output_path_ok |
push edi |
mov esi,[input_file] |
mov edi,[free_additional_memory] |
copy_output_path: |
lods byte [esi] |
cmp edi,[structures_buffer] |
jae out_of_memory |
stos byte [edi] |
or al,al |
jnz copy_output_path |
dec edi |
mov eax,edi |
find_extension: |
dec eax |
cmp eax,[free_additional_memory] |
jb extension_found |
cmp byte [eax],'\' |
je extension_found |
cmp byte [eax],'/' |
je extension_found |
cmp byte [eax],'.' |
jne find_extension |
mov edi,eax |
extension_found: |
lea eax,[edi+9] |
cmp eax,[structures_buffer] |
jae out_of_memory |
cmp [output_format],2 |
je exe_extension |
jb bin_extension |
cmp [output_format],4 |
je obj_extension |
cmp [output_format],5 |
je o_extension |
cmp [output_format],3 |
jne no_extension |
cmp [subsystem],1 |
je sys_extension |
bt [format_flags],8 |
jnc exe_extension |
mov eax,'.dll' |
jmp make_extension |
sys_extension: |
mov eax,'.sys' |
jmp make_extension |
bin_extension: |
mov eax,'.bin' |
bt [format_flags],0 |
jnc make_extension |
mov eax,'.com' |
jmp make_extension |
obj_extension: |
mov eax,'.obj' |
jmp make_extension |
o_extension: |
mov eax,'.o' |
bt [format_flags],0 |
jnc make_extension |
no_extension: |
xor eax,eax |
jmp make_extension |
exe_extension: |
mov eax,'.exe' |
make_extension: |
xchg eax,[edi] |
scas dword [edi] |
mov byte [edi],0 |
scas byte [edi] |
mov esi,edi |
stos dword [edi] |
sub edi,9 |
xor eax,eax |
mov ebx,characters |
adapt_case: |
mov al,[esi] |
or al,al |
jz adapt_next |
xlat byte [ebx] |
cmp al,[esi] |
je adapt_ok |
sub byte [edi],20h |
adapt_ok: |
inc esi |
adapt_next: |
inc edi |
cmp byte [edi],0 |
jne adapt_case |
mov esi,edi |
lea ecx,[esi+1] |
sub ecx,[free_additional_memory] |
mov edi,[structures_buffer] |
dec edi |
std |
rep movs byte [edi],[esi] |
cld |
inc edi |
mov [structures_buffer],edi |
mov [output_file],edi |
pop edi |
output_path_ok: |
cmp [output_format],4 |
je coff_formatter |
cmp [output_format],5 |
jne common_formatter |
bt [format_flags],0 |
jnc elf_formatter |
common_formatter: |
mov eax,edi |
sub eax,[code_start] |
mov [real_code_size],eax |
cmp edi,[undefined_data_end] |
jne calculate_code_size |
mov edi,[undefined_data_start] |
calculate_code_size: |
sub edi,[code_start] |
mov [code_size],edi |
mov [written_size],0 |
mov edx,[output_file] |
call create |
jc write_failed |
cmp [output_format],3 |
jne stub_written |
mov edx,[code_start] |
mov ecx,[stub_size] |
sub edx,ecx |
add [written_size],ecx |
call write |
stub_written: |
cmp [output_format],2 |
jne write_output |
call write_mz_header |
write_output: |
call write_code |
output_written: |
call close |
ret |
write_code: |
mov eax,[written_size] |
mov [headers_size],eax |
mov edx,[code_start] |
mov ecx,[code_size] |
add [written_size],ecx |
call write |
jc write_failed |
ret |
format_directive: |
cmp edi,[code_start] |
jne unexpected_instruction |
cmp [virtual_data],0 |
jne unexpected_instruction |
cmp [output_format],0 |
jne unexpected_instruction |
lods byte [esi] |
cmp al,17h |
je format_prefix |
cmp al,18h |
jne invalid_argument |
lods byte [esi] |
select_format: |
mov dl,al |
shr al,4 |
mov [output_format],al |
and edx,0Fh |
or [format_flags],edx |
cmp al,2 |
je format_mz |
cmp al,3 |
je format_pe |
cmp al,4 |
je format_coff |
cmp al,5 |
je format_elf |
jmp instruction_assembled |
format_prefix: |
lods byte [esi] |
mov ah,al |
lods byte [esi] |
cmp al,18h |
jne invalid_argument |
lods byte [esi] |
mov edx,eax |
shr dl,4 |
shr dh,4 |
cmp dl,dh |
jne invalid_argument |
or al,ah |
jmp select_format |
entry_directive: |
bts [format_flags],10h |
jc setting_already_specified |
mov al,[output_format] |
cmp al,2 |
je mz_entry |
cmp al,3 |
je pe_entry |
cmp al,5 |
jne illegal_instruction |
bt [format_flags],0 |
jc elf_entry |
jmp illegal_instruction |
stack_directive: |
bts [format_flags],11h |
jc setting_already_specified |
mov al,[output_format] |
cmp al,2 |
je mz_stack |
cmp al,3 |
je pe_stack |
jmp illegal_instruction |
heap_directive: |
bts [format_flags],12h |
jc setting_already_specified |
mov al,[output_format] |
cmp al,2 |
je mz_heap |
cmp al,3 |
je pe_heap |
jmp illegal_instruction |
section_directive: |
cmp [virtual_data],0 |
jne illegal_instruction |
mov al,[output_format] |
cmp al,3 |
je pe_section |
cmp al,4 |
je coff_section |
cmp al,5 |
je elf_section |
jmp illegal_instruction |
public_directive: |
mov al,[output_format] |
cmp al,4 |
je public_allowed |
cmp al,5 |
jne illegal_instruction |
bt [format_flags],0 |
jc illegal_instruction |
public_allowed: |
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 |
mov dx,[current_pass] |
mov [eax+18],dx |
or byte [eax+8],8 |
inc esi |
mov ebx,[free_additional_memory] |
lea edx,[ebx+10h] |
cmp edx,[structures_buffer] |
jae out_of_memory |
mov [free_additional_memory],edx |
mov [ebx+8],eax |
mov eax,[current_line] |
mov [ebx+0Ch],eax |
lods byte [esi] |
cmp al,86h |
jne invalid_argument |
lods word [esi] |
cmp ax,'(' |
jne invalid_argument |
mov [ebx+4],esi |
lods dword [esi] |
lea esi,[esi+eax+1] |
mov byte [ebx],80h |
jmp instruction_assembled |
extrn_directive: |
mov al,[output_format] |
cmp al,4 |
je extrn_allowed |
cmp al,5 |
jne illegal_instruction |
bt [format_flags],0 |
jc illegal_instruction |
extrn_allowed: |
lods word [esi] |
cmp ax,'(' |
jne invalid_argument |
mov ebx,esi |
lods dword [esi] |
lea esi,[esi+eax+1] |
mov edx,[free_additional_memory] |
lea eax,[edx+0Ch] |
cmp eax,[structures_buffer] |
jae out_of_memory |
mov [free_additional_memory],eax |
mov byte [edx],81h |
mov [edx+4],ebx |
lods byte [esi] |
cmp al,86h |
jne invalid_argument |
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 ah,ah |
lods byte [esi] |
cmp al,':' |
je get_extrn_size |
dec esi |
cmp al,11h |
jne extrn_size_ok |
get_extrn_size: |
lods word [esi] |
cmp al,11h |
jne invalid_argument |
extrn_size_ok: |
mov [address_symbol],edx |
movzx ecx,ah |
mov [edx+8],ecx |
xor eax,eax |
xor edx,edx |
xor ebp,ebp |
mov ch,2 |
test [format_flags],8 |
jz make_free_label |
mov ch,4 |
jmp make_free_label |
mark_relocation: |
cmp [value_type],0 |
je relocation_ok |
cmp [virtual_data],0 |
jne relocation_ok |
cmp [output_format],2 |
je mark_mz_relocation |
cmp [output_format],3 |
je mark_pe_relocation |
cmp [output_format],4 |
je mark_coff_relocation |
cmp [output_format],5 |
je mark_elf_relocation |
relocation_ok: |
ret |
close_pass: |
mov al,[output_format] |
cmp al,3 |
je close_pe |
cmp al,4 |
je close_coff |
cmp al,5 |
je close_elf |
ret |
format_mz: |
mov edx,[additional_memory] |
push edi |
mov edi,edx |
mov ecx,1Ch shr 2 |
xor eax,eax |
rep stos dword [edi] |
mov [free_additional_memory],edi |
pop edi |
mov word [edx+0Ch],0FFFFh |
mov word [edx+10h],1000h |
mov [code_type],16 |
jmp instruction_assembled |
mark_mz_relocation: |
push eax ebx |
inc [number_of_relocations] |
mov ebx,[free_additional_memory] |
mov eax,edi |
sub eax,[code_start] |
mov [ebx],ax |
shr eax,16 |
shl ax,12 |
mov [ebx+2],ax |
cmp word [ebx],0FFFFh |
jne mz_relocation_ok |
inc word [ebx+2] |
sub word [ebx],10h |
mz_relocation_ok: |
add ebx,4 |
cmp ebx,[structures_buffer] |
jae out_of_memory |
mov [free_additional_memory],ebx |
pop ebx eax |
ret |
segment_directive: |
cmp [output_format],2 |
jne illegal_instruction |
cmp [virtual_data],0 |
jne illegal_instruction |
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 |
mov eax,edi |
sub eax,[code_start] |
mov ecx,0Fh |
add eax,0Fh |
and eax,1111b |
sub ecx,eax |
mov edx,edi |
xor al,al |
rep stos byte [edi] |
mov dword [org_origin],edi |
mov dword [org_origin+4],0 |
mov [org_registers],0 |
mov [org_start],edi |
mov eax,edx |
call undefined_data |
mov eax,edi |
sub eax,[code_start] |
shr eax,4 |
cmp eax,10000h |
jae value_out_of_range |
mov edx,eax |
mov al,16 |
cmp byte [esi],13h |
jne segment_type_ok |
inc esi |
lods byte [esi] |
segment_type_ok: |
mov [code_type],al |
mov eax,edx |
mov cx,0100h |
xor edx,edx |
xor ebp,ebp |
mov [address_symbol],edx |
jmp make_free_label |
mz_entry: |
lods byte [esi] |
cmp al,'(' |
jne invalid_argument |
call get_word_value |
cmp [value_type],1 |
je initial_cs_ok |
cmp [error_line],0 |
jne initial_cs_ok |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],invalid_address |
initial_cs_ok: |
mov edx,[additional_memory] |
mov [edx+16h],ax |
lods byte [esi] |
cmp al,':' |
jne invalid_argument |
lods byte [esi] |
cmp al,'(' |
jne invalid_argument |
ja invalid_address |
call get_word_value |
cmp [value_type],0 |
jne invalid_use_of_symbol |
mov edx,[additional_memory] |
mov [edx+14h],ax |
jmp instruction_assembled |
mz_stack: |
lods byte [esi] |
cmp al,'(' |
jne invalid_argument |
call get_word_value |
cmp byte [esi],':' |
je stack_pointer |
cmp ax,10h |
jb invalid_value |
cmp [value_type],0 |
jne invalid_use_of_symbol |
mov edx,[additional_memory] |
mov [edx+10h],ax |
jmp instruction_assembled |
stack_pointer: |
cmp [value_type],1 |
je initial_ss_ok |
cmp [error_line],0 |
jne initial_ss_ok |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],invalid_address |
initial_ss_ok: |
mov edx,[additional_memory] |
mov [edx+0Eh],ax |
lods byte [esi] |
cmp al,':' |
jne invalid_argument |
lods byte [esi] |
cmp al,'(' |
jne invalid_argument |
call get_word_value |
cmp [value_type],0 |
jne invalid_use_of_symbol |
mov edx,[additional_memory] |
mov [edx+10h],ax |
bts [format_flags],4 |
jmp instruction_assembled |
mz_heap: |
cmp [output_format],2 |
jne illegal_instruction |
lods byte [esi] |
call get_size_operator |
cmp ah,1 |
je invalid_value |
cmp ah,2 |
ja invalid_value |
cmp al,'(' |
jne invalid_argument |
call get_word_value |
cmp [value_type],0 |
jne invalid_use_of_symbol |
mov edx,[additional_memory] |
mov [edx+0Ch],ax |
jmp instruction_assembled |
write_mz_header: |
mov edx,[additional_memory] |
bt [format_flags],4 |
jc mz_stack_ok |
mov eax,[real_code_size] |
dec eax |
shr eax,4 |
inc eax |
mov [edx+0Eh],ax |
shl eax,4 |
movzx ecx,word [edx+10h] |
add eax,ecx |
mov [real_code_size],eax |
mz_stack_ok: |
mov edi,[free_additional_memory] |
mov eax,[number_of_relocations] |
shl eax,2 |
add eax,1Ch |
sub edi,eax |
xchg edi,[free_additional_memory] |
mov ecx,0Fh |
add eax,0Fh |
and eax,1111b |
sub ecx,eax |
xor al,al |
rep stos byte [edi] |
sub edi,[free_additional_memory] |
mov ecx,edi |
shr edi,4 |
mov word [edx],'MZ' ; signature |
mov [edx+8],di ; header size in paragraphs |
mov eax,[number_of_relocations] |
mov [edx+6],ax ; number of relocation entries |
mov eax,[code_size] |
add eax,ecx |
mov esi,eax |
shr esi,9 |
and eax,1FFh |
inc si |
or ax,ax |
jnz mz_size_ok |
mov ax,200h |
dec si |
mz_size_ok: |
mov [edx+2],ax ; number of bytes in last page |
mov [edx+4],si ; number of pages |
mov eax,[real_code_size] |
dec eax |
shr eax,4 |
inc eax |
mov esi,[code_size] |
dec esi |
shr esi,4 |
inc esi |
sub eax,esi |
mov [edx+0Ah],ax ; minimum memory in addition to code |
add [edx+0Ch],ax ; maximum memory in addition to code |
salc |
mov ah,al |
or [edx+0Ch],ax |
mov word [edx+18h],1Ch ; offset of relocation table |
add [written_size],ecx |
call write |
jc write_failed |
ret |
make_stub: |
mov [stub_file],edx |
or edx,edx |
jnz stub_from_file |
push esi |
mov edx,edi |
xor eax,eax |
mov ecx,20h |
rep stos dword [edi] |
mov eax,40h+default_stub_end-default_stub |
mov cx,100h+default_stub_end-default_stub |
mov word [edx],'MZ' |
mov word [edx+4],1 |
mov word [edx+2],ax |
mov word [edx+8],4 |
mov word [edx+0Ah],10h |
mov word [edx+0Ch],0FFFFh |
mov word [edx+10h],cx |
mov word [edx+3Ch],ax |
mov word [edx+18h],40h |
lea edi,[edx+40h] |
mov esi,default_stub |
mov ecx,default_stub_end-default_stub |
rep movs byte [edi],[esi] |
pop esi |
jmp stub_ok |
default_stub: |
use16 |
push cs |
pop ds |
mov dx,stub_message-default_stub |
mov ah,9 |
int 21h |
mov ax,4C01h |
int 21h |
stub_message db 'This program cannot be run in DOS mode.',0Dh,0Ah,24h |
rq 1 |
default_stub_end: |
use32 |
stub_from_file: |
push esi |
mov esi,edx |
call open_binary_file |
mov edx,edi |
mov ecx,1Ch |
mov esi,edx |
call read |
jc binary_stub |
cmp word [esi],'MZ' |
jne binary_stub |
add edi,1Ch |
movzx ecx,word [esi+6] |
dec ecx |
sar ecx,3 |
inc ecx |
shl ecx,2 |
add ecx,(40h-1Ch) shr 2 |
lea eax,[edi+ecx*4] |
cmp edi,[display_buffer] |
jae out_of_memory |
xor eax,eax |
rep stos dword [edi] |
mov edx,40h |
xchg dx,[esi+18h] |
xor al,al |
call lseek |
movzx ecx,word [esi+6] |
shl ecx,2 |
lea edx,[esi+40h] |
call read |
mov edx,edi |
sub edx,esi |
shr edx,4 |
xchg dx,[esi+8] |
shl edx,4 |
xor al,al |
call lseek |
movzx ecx,word [esi+4] |
dec ecx |
shl ecx,9 |
movzx edx,word [esi+2] |
add ecx,edx |
mov edx,edi |
sub ecx,eax |
je read_stub_code |
jb stub_code_ok |
push ecx |
dec ecx |
shr ecx,3 |
inc ecx |
shl ecx,1 |
lea eax,[edi+ecx*4] |
cmp eax,[display_buffer] |
jae out_of_memory |
xor eax,eax |
rep stos dword [edi] |
pop ecx |
read_stub_code: |
call read |
stub_code_ok: |
call close |
mov edx,edi |
sub edx,esi |
mov ax,dx |
and ax,1FFh |
mov [esi+2],ax |
dec edx |
shr edx,9 |
inc edx |
mov [esi+4],dx |
mov eax,edi |
sub eax,esi |
mov [esi+3Ch],eax |
pop esi |
stub_ok: |
ret |
binary_stub: |
mov esi,edi |
mov ecx,40h shr 2 |
xor eax,eax |
rep stos dword [edi] |
mov al,2 |
xor edx,edx |
call lseek |
push eax |
xor al,al |
xor edx,edx |
call lseek |
mov ecx,[esp] |
add ecx,40h+111b |
and ecx,not 111b |
mov ax,cx |
and ax,1FFh |
mov [esi+2],ax |
lea eax,[ecx+1FFh] |
and eax,not 1FFh |
mov [esi+4],ax |
mov [esi+3Ch],ecx |
sub ecx,40h |
mov eax,10000h |
sub eax,ecx |
jbe binary_heap_ok |
shr eax,4 |
mov [esi+0Ah],ax |
binary_heap_ok: |
mov word [esi],'MZ' |
mov word [esi+8],4 |
mov ax,0FFFFh |
mov [esi+0Ch],ax |
dec ax |
mov [esi+10h],ax |
sub ax,0Eh |
mov [esi+0Eh],ax |
mov [esi+16h],ax |
mov word [esi+14h],100h |
mov word [esi+18h],40h |
mov eax,[display_buffer] |
sub eax,ecx |
cmp edi,eax |
jae out_of_memory |
mov edx,edi |
shr ecx,2 |
xor eax,eax |
rep stos dword [edi] |
pop ecx |
call read |
call close |
pop esi |
ret |
format_pe: |
xor edx,edx |
mov [machine],14Ch |
mov [subsystem],3 |
mov [subsystem_version],3 + 10 shl 16 |
mov [image_base],400000h |
test [format_flags],8 |
jz pe_settings |
mov [machine],8664h |
mov [subsystem_version],5 + 0 shl 16 |
mov [image_base_high],0 |
pe_settings: |
cmp byte [esi],84h |
je get_stub_name |
cmp byte [esi],80h |
je get_pe_base |
cmp byte [esi],1Bh |
jne pe_settings_ok |
lods byte [esi] |
lods byte [esi] |
test al,80h+40h |
jz subsystem_setting |
cmp al,80h |
je dll_flag |
cmp al,81h |
je wdm_flag |
jmp pe_settings |
dll_flag: |
bts [format_flags],8 |
jc setting_already_specified |
jmp pe_settings |
wdm_flag: |
bts [format_flags],9 |
jc setting_already_specified |
jmp pe_settings |
subsystem_setting: |
bts [format_flags],7 |
jc setting_already_specified |
and ax,3Fh |
mov [subsystem],ax |
cmp byte [esi],'(' |
jne pe_settings |
inc esi |
cmp byte [esi],'.' |
jne invalid_value |
inc esi |
push edx |
cmp byte [esi+11],0 |
jne invalid_value |
cmp byte [esi+10],2 |
ja invalid_value |
mov dx,[esi+8] |
cmp dx,8000h |
je zero_version |
mov eax,[esi+4] |
cmp dx,7 |
jg invalid_value |
mov cx,7 |
sub cx,dx |
mov eax,[esi+4] |
shr eax,cl |
mov ebx,eax |
shr ebx,24 |
cmp bl,100 |
jae invalid_value |
and eax,0FFFFFFh |
mov ecx,100 |
mul ecx |
shrd eax,edx,24 |
jnc version_value_ok |
inc eax |
version_value_ok: |
shl eax,16 |
mov ax,bx |
jmp subsystem_version_ok |
zero_version: |
xor eax,eax |
subsystem_version_ok: |
pop edx |
add esi,13 |
mov [subsystem_version],eax |
jmp pe_settings |
get_pe_base: |
bts [format_flags],10 |
jc setting_already_specified |
lods word [esi] |
cmp ah,'(' |
jne invalid_argument |
cmp byte [esi],'.' |
je invalid_value |
push edx edi |
add edi,[stub_size] |
test [format_flags],8 |
jnz get_pe64_base |
call get_dword_value |
mov [image_base],eax |
jmp pe_base_ok |
get_pe64_base: |
call get_qword_value |
mov [image_base],eax |
mov [image_base_high],edx |
pe_base_ok: |
pop edi edx |
cmp [value_type],0 |
jne invalid_use_of_symbol |
cmp byte [esi],84h |
jne pe_settings_ok |
get_stub_name: |
lods byte [esi] |
lods word [esi] |
cmp ax,'(' |
jne invalid_argument |
lods dword [esi] |
mov edx,esi |
add esi,eax |
inc esi |
pe_settings_ok: |
mov ebp,[stub_size] |
or ebp,ebp |
jz make_pe_stub |
cmp edx,[stub_file] |
je pe_stub_ok |
sub edi,[stub_size] |
mov [code_start],edi |
make_pe_stub: |
call make_stub |
mov eax,edi |
sub eax,[code_start] |
mov [stub_size],eax |
mov [code_start],edi |
mov ebp,eax |
pe_stub_ok: |
mov edx,edi |
mov ecx,18h+0E0h |
test [format_flags],8 |
jz zero_pe_header |
add ecx,10h |
zero_pe_header: |
add ebp,ecx |
shr ecx,2 |
xor eax,eax |
rep stos dword [edi] |
mov word [edx],'PE' ; signature |
mov ax,[machine] |
mov word [edx+4],ax |
mov dword [edx+38h],1000h ; section alignment |
mov dword [edx+3Ch],200h ; file alignment |
mov word [edx+40h],1 ; OS version |
mov eax,[subsystem_version] |
mov [edx+48h],eax |
mov ax,[subsystem] |
mov [edx+5Ch],ax |
cmp ax,1 |
jne pe_alignment_ok |
mov eax,20h |
mov dword [edx+38h],eax |
mov dword [edx+3Ch],eax |
pe_alignment_ok: |
mov word [edx+1Ah],VERSION_MAJOR + VERSION_MINOR shl 8 |
test [format_flags],8 |
jnz init_pe64_specific |
mov dword [edx+14h],0E0h ; size of optional header |
mov dword [edx+16h],10B010Eh; flags and magic value |
mov eax,[image_base] |
mov dword [edx+34h],eax |
mov dword [edx+60h],1000h ; stack reserve |
mov dword [edx+64h],1000h ; stack commit |
mov dword [edx+68h],10000h ; heap reserve |
mov dword [edx+6Ch],0 ; heap commit |
mov dword [edx+74h],16 ; number of directories |
jmp pe_header_ok |
init_pe64_specific: |
mov dword [edx+14h],0F0h ; size of optional header |
mov dword [edx+16h],20B002Eh; flags and magic value |
mov eax,[image_base] |
mov dword [edx+30h],eax |
mov eax,[image_base_high] |
mov dword [edx+34h],eax |
mov dword [edx+60h],1000h ; stack reserve |
mov dword [edx+68h],1000h ; stack commit |
mov dword [edx+70h],10000h ; heap reserve |
mov dword [edx+78h],0 ; heap commit |
mov dword [edx+84h],16 ; number of directories |
pe_header_ok: |
bsf ecx,[edx+3Ch] |
imul ebx,[number_of_sections],28h |
or ebx,ebx |
jnz reserve_space_for_section_headers |
mov ebx,28h |
reserve_space_for_section_headers: |
add ebx,ebp |
dec ebx |
shr ebx,cl |
inc ebx |
shl ebx,cl |
sub ebx,ebp |
mov ecx,ebx |
mov eax,[display_buffer] |
sub eax,ecx |
cmp edi,eax |
jae out_of_memory |
shr ecx,2 |
xor eax,eax |
rep stos dword [edi] |
mov eax,edi |
sub eax,[code_start] |
add eax,[stub_size] |
mov [edx+54h],eax ; size of headers |
mov ecx,[edx+38h] |
dec ecx |
add eax,ecx |
not ecx |
and eax,ecx |
bt [format_flags],8 |
jc pe_entry_init_ok |
mov [edx+28h],eax ; entry point rva |
pe_entry_init_ok: |
mov [number_of_sections],0 |
movzx ebx,word [edx+14h] |
lea ebx,[edx+18h+ebx] |
mov [current_section],ebx |
mov dword [ebx],'.fla' |
mov dword [ebx+4],'t' |
mov [ebx+14h],edi |
mov [ebx+0Ch],eax |
mov dword [ebx+24h],0E0000060h |
xor ecx,ecx |
not eax |
not ecx |
add eax,1 |
adc ecx,0 |
add eax,edi |
adc ecx,0 |
test [format_flags],8 |
jnz pe64_org |
sub eax,[edx+34h] |
sbb ecx,0 |
mov [labels_type],2 |
mov [code_type],32 |
jmp pe_org_ok |
pe64_org: |
sub eax,[edx+30h] |
sbb ecx,[edx+34h] |
mov [labels_type],4 |
mov [code_type],64 |
pe_org_ok: |
mov dword [org_origin],eax |
mov dword [org_origin+4],ecx |
mov [org_registers],0 |
mov [org_start],edi |
bt [format_flags],8 |
jnc dll_flag_ok |
or dword [edx+16h],2000h |
dll_flag_ok: |
bt [format_flags],9 |
jnc wdm_flag_ok |
or word [edx+5Eh],2000h |
wdm_flag_ok: |
jmp instruction_assembled |
pe_section: |
call close_pe_section |
bts [format_flags],5 |
lea ecx,[ebx+28h] |
add edx,[edx+54h] |
sub edx,[stub_size] |
cmp ecx,edx |
jbe new_section |
lea ebx,[edx-28h] |
or [next_pass_needed],-1 |
push edi |
mov edi,ebx |
mov ecx,28h shr 4 |
xor eax,eax |
rep stos dword [edi] |
pop edi |
new_section: |
mov [ebx+0Ch],eax |
lods word [esi] |
cmp ax,'(' |
jne invalid_argument |
lea edx,[esi+4] |
mov ecx,[esi] |
lea esi,[esi+4+ecx+1] |
cmp ecx,8 |
ja name_too_long |
xor eax,eax |
mov [ebx],eax |
mov [ebx+4],eax |
push esi edi |
mov edi,ebx |
mov esi,edx |
rep movs byte [edi],[esi] |
pop edi esi |
mov dword [ebx+24h],0 |
mov [ebx+14h],edi |
mov edx,[code_start] |
mov eax,edi |
xor ecx,ecx |
sub eax,[ebx+0Ch] |
sbb ecx,0 |
test [format_flags],8 |
jnz pe64_section_org |
sub eax,[edx+34h] |
sbb ecx,0 |
mov [labels_type],2 |
mov [code_type],32 |
jmp pe_section_org_ok |
pe64_section_org: |
sub eax,[edx+30h] |
sbb ecx,[edx+34h] |
mov [labels_type],4 |
mov [code_type],64 |
pe_section_org_ok: |
mov dword [org_origin],eax |
mov dword [org_origin+4],ecx |
mov [org_registers],0 |
mov [org_start],edi |
get_section_flags: |
lods byte [esi] |
cmp al,1Ah |
je set_directory |
cmp al,19h |
je section_flag |
dec esi |
jmp instruction_assembled |
set_directory: |
movzx eax,byte [esi] |
inc esi |
mov ecx,ebx |
test [format_flags],8 |
jnz pe64_directory |
xchg ecx,[edx+78h+eax*8] |
mov dword [edx+78h+eax*8+4],-1 |
jmp pe_directory_set |
pe64_directory: |
xchg ecx,[edx+88h+eax*8] |
mov dword [edx+88h+eax*8+4],-1 |
pe_directory_set: |
or ecx,ecx |
jnz data_already_defined |
push ebx edx |
call generate_pe_data |
pop edx ebx |
jmp get_section_flags |
section_flag: |
lods byte [esi] |
mov cl,al |
mov eax,1 |
shl eax,cl |
test dword [ebx+24h],eax |
jnz setting_already_specified |
or dword [ebx+24h],eax |
jmp get_section_flags |
close_pe_section: |
mov ebx,[current_section] |
mov edx,[code_start] |
mov eax,edi |
sub eax,[ebx+14h] |
jnz finish_section |
bt [format_flags],5 |
jc finish_section |
mov eax,[ebx+0Ch] |
ret |
finish_section: |
mov [ebx+8],eax |
cmp edi,[undefined_data_end] |
jne align_section |
cmp dword [edx+38h],1000h |
jb align_section |
mov edi,[undefined_data_start] |
align_section: |
mov [undefined_data_end],0 |
mov ebp,edi |
sub ebp,[ebx+14h] |
mov ecx,[edx+3Ch] |
dec ecx |
lea eax,[ebp+ecx] |
not ecx |
and eax,ecx |
mov [ebx+10h],eax |
sub eax,ebp |
mov ecx,eax |
xor al,al |
rep stos byte [edi] |
mov eax,[code_start] |
sub eax,[stub_size] |
sub [ebx+14h],eax |
mov eax,[ebx+8] |
or eax,eax |
jz udata_ok |
cmp dword [ebx+10h],0 |
jne udata_ok |
or byte [ebx+24h],80h |
udata_ok: |
mov ecx,[edx+38h] |
dec ecx |
add eax,ecx |
not ecx |
and eax,ecx |
add eax,[ebx+0Ch] |
add ebx,28h |
mov [current_section],ebx |
inc word [number_of_sections] |
jz format_limitations_exceeded |
ret |
data_directive: |
cmp [output_format],3 |
jne illegal_instruction |
lods byte [esi] |
cmp al,1Ah |
je predefined_data_type |
cmp al,'(' |
jne invalid_argument |
call get_byte_value |
cmp al,16 |
jb data_type_ok |
jmp invalid_value |
predefined_data_type: |
movzx eax,byte [esi] |
inc esi |
data_type_ok: |
mov ebx,[current_section] |
mov ecx,edi |
sub ecx,[ebx+14h] |
add ecx,[ebx+0Ch] |
mov edx,[code_start] |
test [format_flags],8 |
jnz pe64_data |
xchg ecx,[edx+78h+eax*8] |
jmp init_pe_data |
pe64_data: |
xchg ecx,[edx+88h+eax*8] |
init_pe_data: |
or ecx,ecx |
jnz data_already_defined |
call allocate_structure_data |
mov word [ebx],data_directive-assembler |
mov [ebx+2],al |
mov edx,[current_line] |
mov [ebx+4],edx |
call generate_pe_data |
jmp instruction_assembled |
end_data: |
cmp [output_format],3 |
jne illegal_instruction |
call find_structure_data |
jc unexpected_instruction |
movzx eax,byte [ebx+2] |
mov edx,[current_section] |
mov ecx,edi |
sub ecx,[edx+14h] |
add ecx,[edx+0Ch] |
mov edx,[code_start] |
test [format_flags],8 |
jnz end_pe64_data |
sub ecx,[edx+78h+eax*8] |
mov [edx+78h+eax*8+4],ecx |
jmp remove_structure_data |
end_pe64_data: |
sub ecx,[edx+88h+eax*8] |
mov [edx+88h+eax*8+4],ecx |
jmp remove_structure_data |
pe_entry: |
lods byte [esi] |
cmp al,'(' |
jne invalid_argument |
cmp byte [esi],'.' |
je invalid_value |
test [format_flags],8 |
jnz pe64_entry |
call get_dword_value |
cmp [value_type],2 |
je pe_entry_ok |
cmp [error_line],0 |
jne pe_entry_ok |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],invalid_address |
pe_entry_ok: |
mov edx,[code_start] |
sub eax,[edx+34h] |
mov [edx+28h],eax |
jmp instruction_assembled |
pe64_entry: |
call get_qword_value |
cmp [value_type],4 |
je pe64_entry_ok |
cmp [error_line],0 |
jne pe64_entry_ok |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],invalid_address |
pe64_entry_ok: |
mov ecx,[code_start] |
sub eax,[ecx+30h] |
sbb edx,[ecx+34h] |
jnz value_out_of_range |
mov [ecx+28h],eax |
jmp instruction_assembled |
pe_stack: |
lods byte [esi] |
cmp al,'(' |
jne invalid_argument |
cmp byte [esi],'.' |
je invalid_value |
test [format_flags],8 |
jnz pe64_stack |
call get_dword_value |
cmp [value_type],0 |
jne invalid_use_of_symbol |
mov edx,[code_start] |
mov [edx+60h],eax |
cmp byte [esi],',' |
jne default_stack_commit |
lods byte [esi] |
lods byte [esi] |
cmp al,'(' |
jne invalid_argument |
cmp byte [esi],'.' |
je invalid_value |
call get_dword_value |
cmp [value_type],0 |
jne invalid_use_of_symbol |
mov edx,[code_start] |
mov [edx+64h],eax |
cmp eax,[edx+60h] |
ja value_out_of_range |
jmp instruction_assembled |
default_stack_commit: |
mov dword [edx+64h],1000h |
mov eax,[edx+60h] |
cmp eax,1000h |
ja instruction_assembled |
mov dword [edx+64h],eax |
jmp instruction_assembled |
pe64_stack: |
call get_qword_value |
cmp [value_type],0 |
jne invalid_use_of_symbol |
mov ecx,[code_start] |
mov [ecx+60h],eax |
mov [ecx+64h],edx |
cmp byte [esi],',' |
jne default_pe64_stack_commit |
lods byte [esi] |
lods byte [esi] |
cmp al,'(' |
jne invalid_argument |
cmp byte [esi],'.' |
je invalid_value |
call get_qword_value |
cmp [value_type],0 |
jne invalid_use_of_symbol |
mov ecx,[code_start] |
mov [ecx+68h],eax |
mov [ecx+6Ch],edx |
cmp edx,[ecx+64h] |
ja value_out_of_range |
jb instruction_assembled |
cmp eax,[edx+60h] |
ja value_out_of_range |
jmp instruction_assembled |
default_pe64_stack_commit: |
mov dword [edx+68h],1000h |
cmp dword [edx+64h],0 |
jne instruction_assembled |
mov eax,[edx+60h] |
cmp eax,1000h |
ja instruction_assembled |
mov dword [edx+68h],eax |
jmp instruction_assembled |
pe_heap: |
lods byte [esi] |
cmp al,'(' |
jne invalid_argument |
cmp byte [esi],'.' |
je invalid_value |
test [format_flags],8 |
jnz pe64_heap |
call get_dword_value |
cmp [value_type],0 |
jne invalid_use_of_symbol |
mov edx,[code_start] |
mov [edx+68h],eax |
cmp byte [esi],',' |
jne instruction_assembled |
lods byte [esi] |
lods byte [esi] |
cmp al,'(' |
jne invalid_argument |
cmp byte [esi],'.' |
je invalid_value |
call get_dword_value |
cmp [value_type],0 |
jne invalid_use_of_symbol |
mov edx,[code_start] |
mov [edx+6Ch],eax |
cmp eax,[edx+68h] |
ja value_out_of_range |
jmp instruction_assembled |
pe64_heap: |
call get_qword_value |
cmp [value_type],0 |
jne invalid_use_of_symbol |
mov ecx,[code_start] |
mov [ecx+70h],eax |
mov [ecx+74h],edx |
cmp byte [esi],',' |
jne instruction_assembled |
lods byte [esi] |
lods byte [esi] |
cmp al,'(' |
jne invalid_argument |
cmp byte [esi],'.' |
je invalid_value |
call get_qword_value |
cmp [value_type],0 |
jne invalid_use_of_symbol |
mov ecx,[code_start] |
mov [ecx+78h],eax |
mov [ecx+7Ch],edx |
cmp edx,[ecx+74h] |
ja value_out_of_range |
jb instruction_assembled |
cmp eax,[edx+70h] |
ja value_out_of_range |
jmp instruction_assembled |
mark_pe_relocation: |
push eax ebx |
mov ebx,[current_section] |
mov eax,edi |
sub eax,[ebx+14h] |
add eax,[ebx+0Ch] |
mov ebx,[free_additional_memory] |
inc [number_of_relocations] |
jz invalid_use_of_symbol |
mov [ebx],eax |
add ebx,4 |
cmp ebx,[structures_buffer] |
jae out_of_memory |
mov [free_additional_memory],ebx |
pop ebx eax |
ret |
generate_pe_data: |
cmp al,2 |
je make_pe_resource |
cmp al,5 |
je make_pe_fixups |
ret |
make_pe_resource: |
cmp byte [esi],82h |
jne resource_done |
inc esi |
lods word [esi] |
cmp ax,'(' |
jne invalid_argument |
lods dword [esi] |
mov edx,esi |
lea esi,[esi+eax+1] |
cmp [next_pass_needed],0 |
je resource_from_file |
cmp [current_pass],0 |
jne reserve_space_for_resource |
mov [resource_size],0 |
reserve_space_for_resource: |
add edi,[resource_size] |
cmp edi,[display_buffer] |
ja out_of_memory |
jmp resource_done |
resource_from_file: |
push esi |
mov esi,edx |
call open_binary_file |
push ebx |
mov esi,[free_additional_memory] |
lea eax,[esi+20h] |
cmp eax,[structures_buffer] |
ja out_of_memory |
mov edx,esi |
mov ecx,20h |
call read |
jc invalid_file_format |
xor eax,eax |
cmp [esi],eax |
jne invalid_file_format |
mov ax,0FFFFh |
cmp [esi+8],eax |
jne invalid_file_format |
cmp [esi+12],eax |
jne invalid_file_format |
mov eax,20h |
cmp [esi+4],eax |
jne invalid_file_format |
read_resource_headers: |
test eax,11b |
jz resource_file_alignment_ok |
mov edx,4 |
and eax,11b |
sub edx,eax |
mov al,1 |
call lseek |
resource_file_alignment_ok: |
mov [esi],eax |
lea edx,[esi+12] |
mov ecx,8 |
call read |
jc resource_headers_ok |
mov ecx,[esi+16] |
add [esi],ecx |
lea edx,[esi+20] |
sub ecx,8 |
mov [esi+16],ecx |
lea eax,[edx+ecx] |
cmp eax,[structures_buffer] |
ja out_of_memory |
call read |
jc invalid_file_format |
mov edx,[esi] |
add edx,[esi+12] |
mov eax,[esi+16] |
lea ecx,[esi+20] |
lea esi,[ecx+eax] |
add ecx,2 |
cmp word [ecx-2],0FFFFh |
je resource_header_type_ok |
check_resource_header_type: |
cmp ecx,esi |
jae invalid_file_format |
cmp word [ecx],0 |
je resource_header_type_ok |
add ecx,2 |
jmp check_resource_header_type |
resource_header_type_ok: |
add ecx,2 |
cmp word [ecx],0FFFFh |
je resource_header_name_ok |
check_resource_header_name: |
cmp ecx,esi |
jae invalid_file_format |
cmp word [ecx],0 |
je resource_header_name_ok |
add ecx,2 |
jmp check_resource_header_name |
resource_header_name_ok: |
xor al,al |
call lseek |
jmp read_resource_headers |
resource_headers_ok: |
xor eax,eax |
mov [esi],eax |
mov [resource_data],edi |
lea eax,[edi+16] |
cmp eax,[display_buffer] |
jae out_of_memory |
xor eax,eax |
stos dword [edi] |
call make_timestamp |
stos dword [edi] |
xor eax,eax |
stos dword [edi] |
stos dword [edi] |
xor ebx,ebx |
make_type_name_directory: |
mov esi,[free_additional_memory] |
xor edx,edx |
find_type_name: |
cmp dword [esi],0 |
je type_name_ok |
add esi,20 |
cmp word [esi],0FFFFh |
je check_next_type_name |
or ebx,ebx |
jz check_this_type_name |
xor ecx,ecx |
compare_with_previous_type_name: |
mov ax,[esi+ecx] |
cmp ax,[ebx+ecx] |
ja check_this_type_name |
jb check_next_type_name |
add ecx,2 |
mov ax,[esi+ecx] |
or ax,[ebx+ecx] |
jnz compare_with_previous_type_name |
jmp check_next_type_name |
check_this_type_name: |
or edx,edx |
jz type_name_found |
xor ecx,ecx |
compare_with_current_type_name: |
mov ax,[esi+ecx] |
cmp ax,[edx+ecx] |
ja check_next_type_name |
jb type_name_found |
add ecx,2 |
mov ax,[esi+ecx] |
or ax,[edx+ecx] |
jnz compare_with_current_type_name |
jmp same_type_name |
type_name_found: |
mov edx,esi |
same_type_name: |
mov [esi-16],edi |
check_next_type_name: |
mov eax,[esi-4] |
add esi,eax |
jmp find_type_name |
type_name_ok: |
or edx,edx |
jz type_name_directory_done |
mov ebx,edx |
make_type_name_entry: |
mov eax,[resource_data] |
inc word [eax+12] |
lea eax,[edi+8] |
cmp eax,[display_buffer] |
jae out_of_memory |
mov eax,ebx |
stos dword [edi] |
xor eax,eax |
stos dword [edi] |
jmp make_type_name_directory |
type_name_directory_done: |
mov ebx,-1 |
make_type_id_directory: |
mov esi,[free_additional_memory] |
mov edx,10000h |
find_type_id: |
cmp dword [esi],0 |
je type_id_ok |
add esi,20 |
cmp word [esi],0FFFFh |
jne check_next_type_id |
movzx eax,word [esi+2] |
cmp eax,ebx |
jle check_next_type_id |
cmp eax,edx |
jg check_next_type_id |
mov edx,eax |
mov [esi-16],edi |
check_next_type_id: |
mov eax,[esi-4] |
add esi,eax |
jmp find_type_id |
type_id_ok: |
cmp edx,10000h |
je type_id_directory_done |
mov ebx,edx |
make_type_id_entry: |
mov eax,[resource_data] |
inc word [eax+14] |
lea eax,[edi+8] |
cmp eax,[display_buffer] |
jae out_of_memory |
mov eax,ebx |
stos dword [edi] |
xor eax,eax |
stos dword [edi] |
jmp make_type_id_directory |
type_id_directory_done: |
mov esi,[resource_data] |
add esi,10h |
mov ecx,[esi-4] |
or cx,cx |
jz resource_directories_ok |
make_resource_directories: |
push ecx |
push edi |
mov edx,edi |
sub edx,[resource_data] |
bts edx,31 |
mov [esi+4],edx |
lea eax,[edi+16] |
cmp eax,[display_buffer] |
jae out_of_memory |
xor eax,eax |
stos dword [edi] |
call make_timestamp |
stos dword [edi] |
xor eax,eax |
stos dword [edi] |
stos dword [edi] |
mov ebp,esi |
xor ebx,ebx |
make_resource_name_directory: |
mov esi,[free_additional_memory] |
xor edx,edx |
find_resource_name: |
cmp dword [esi],0 |
je resource_name_ok |
push esi |
cmp [esi+4],ebp |
jne check_next_resource_name |
add esi,20 |
call skip_resource_name |
cmp word [esi],0FFFFh |
je check_next_resource_name |
or ebx,ebx |
jz check_this_resource_name |
xor ecx,ecx |
compare_with_previous_resource_name: |
mov ax,[esi+ecx] |
cmp ax,[ebx+ecx] |
ja check_this_resource_name |
jb check_next_resource_name |
add ecx,2 |
mov ax,[esi+ecx] |
or ax,[ebx+ecx] |
jnz compare_with_previous_resource_name |
jmp check_next_resource_name |
skip_resource_name: |
cmp word [esi],0FFFFh |
jne skip_unicode_string |
add esi,4 |
ret |
skip_unicode_string: |
add esi,2 |
cmp word [esi-2],0 |
jne skip_unicode_string |
ret |
check_this_resource_name: |
or edx,edx |
jz resource_name_found |
xor ecx,ecx |
compare_with_current_resource_name: |
mov ax,[esi+ecx] |
cmp ax,[edx+ecx] |
ja check_next_resource_name |
jb resource_name_found |
add ecx,2 |
mov ax,[esi+ecx] |
or ax,[edx+ecx] |
jnz compare_with_current_resource_name |
jmp same_resource_name |
resource_name_found: |
mov edx,esi |
same_resource_name: |
mov eax,[esp] |
mov [eax+8],edi |
check_next_resource_name: |
pop esi |
mov eax,[esi+16] |
lea esi,[esi+20+eax] |
jmp find_resource_name |
resource_name_ok: |
or edx,edx |
jz resource_name_directory_done |
mov ebx,edx |
make_resource_name_entry: |
mov eax,[esp] |
inc word [eax+12] |
lea eax,[edi+8] |
cmp eax,[display_buffer] |
jae out_of_memory |
mov eax,ebx |
stos dword [edi] |
xor eax,eax |
stos dword [edi] |
jmp make_resource_name_directory |
resource_name_directory_done: |
mov ebx,-1 |
make_resource_id_directory: |
mov esi,[free_additional_memory] |
mov edx,10000h |
find_resource_id: |
cmp dword [esi],0 |
je resource_id_ok |
push esi |
cmp [esi+4],ebp |
jne check_next_resource_id |
add esi,20 |
call skip_resource_name |
cmp word [esi],0FFFFh |
jne check_next_resource_id |
movzx eax,word [esi+2] |
cmp eax,ebx |
jle check_next_resource_id |
cmp eax,edx |
jg check_next_resource_id |
mov edx,eax |
mov eax,[esp] |
mov [eax+8],edi |
check_next_resource_id: |
pop esi |
mov eax,[esi+16] |
lea esi,[esi+20+eax] |
jmp find_resource_id |
resource_id_ok: |
cmp edx,10000h |
je resource_id_directory_done |
mov ebx,edx |
make_resource_id_entry: |
mov eax,[esp] |
inc word [eax+14] |
lea eax,[edi+8] |
cmp eax,[display_buffer] |
jae out_of_memory |
mov eax,ebx |
stos dword [edi] |
xor eax,eax |
stos dword [edi] |
jmp make_resource_id_directory |
resource_id_directory_done: |
pop eax |
mov esi,ebp |
pop ecx |
add esi,8 |
dec cx |
jnz make_resource_directories |
resource_directories_ok: |
shr ecx,16 |
jnz make_resource_directories |
mov esi,[resource_data] |
add esi,10h |
movzx eax,word [esi-4] |
movzx edx,word [esi-2] |
add eax,edx |
lea esi,[esi+eax*8] |
push edi ; address of language directories |
update_resource_directories: |
cmp esi,[esp] |
je resource_directories_updated |
add esi,10h |
mov ecx,[esi-4] |
or cx,cx |
jz language_directories_ok |
make_language_directories: |
push ecx |
push edi |
mov edx,edi |
sub edx,[resource_data] |
bts edx,31 |
mov [esi+4],edx |
lea eax,[edi+16] |
cmp eax,[display_buffer] |
jae out_of_memory |
xor eax,eax |
stos dword [edi] |
call make_timestamp |
stos dword [edi] |
xor eax,eax |
stos dword [edi] |
stos dword [edi] |
mov ebp,esi |
mov ebx,-1 |
make_language_id_directory: |
mov esi,[free_additional_memory] |
mov edx,10000h |
find_language_id: |
cmp dword [esi],0 |
je language_id_ok |
push esi |
cmp [esi+8],ebp |
jne check_next_language_id |
add esi,20 |
mov eax,esi |
call skip_resource_name |
call skip_resource_name |
neg eax |
add eax,esi |
and eax,11b |
add esi,eax |
get_language_id: |
movzx eax,word [esi+6] |
cmp eax,ebx |
jle check_next_language_id |
cmp eax,edx |
jge check_next_language_id |
mov edx,eax |
mov eax,[esp] |
mov [current_offset],eax |
check_next_language_id: |
pop esi |
mov eax,[esi+16] |
lea esi,[esi+20+eax] |
jmp find_language_id |
language_id_ok: |
cmp edx,10000h |
je language_id_directory_done |
mov ebx,edx |
make_language_id_entry: |
mov eax,[esp] |
inc word [eax+14] |
lea eax,[edi+8] |
cmp eax,[display_buffer] |
jae out_of_memory |
mov eax,ebx |
stos dword [edi] |
mov eax,[current_offset] |
stos dword [edi] |
jmp make_language_id_directory |
language_id_directory_done: |
pop eax |
mov esi,ebp |
pop ecx |
add esi,8 |
dec cx |
jnz make_language_directories |
language_directories_ok: |
shr ecx,16 |
jnz make_language_directories |
jmp update_resource_directories |
resource_directories_updated: |
mov esi,[resource_data] |
push edi |
make_name_strings: |
add esi,10h |
movzx eax,word [esi-2] |
movzx ecx,word [esi-4] |
add eax,ecx |
lea eax,[esi+eax*8] |
push eax |
or ecx,ecx |
jz string_entries_processed |
process_string_entries: |
push ecx |
mov edx,edi |
sub edx,[resource_data] |
bts edx,31 |
xchg [esi],edx |
mov ebx,edi |
xor ax,ax |
stos word [edi] |
copy_string_data: |
lea eax,[edi+2] |
cmp eax,[display_buffer] |
jae out_of_memory |
mov ax,[edx] |
or ax,ax |
jz string_data_copied |
stos word [edi] |
inc word [ebx] |
add edx,2 |
jmp copy_string_data |
string_data_copied: |
add esi,8 |
pop ecx |
loop process_string_entries |
string_entries_processed: |
pop esi |
cmp esi,[esp] |
jb make_name_strings |
mov eax,edi |
sub eax,[resource_data] |
test al,11b |
jz resource_strings_alignment_ok |
xor ax,ax |
stos word [edi] |
resource_strings_alignment_ok: |
pop edx |
pop ebx ; address of language directories |
mov ebp,edi |
update_language_directories: |
add ebx,10h |
movzx eax,word [ebx-2] |
movzx ecx,word [ebx-4] |
add ecx,eax |
make_data_records: |
push ecx |
mov esi,edi |
sub esi,[resource_data] |
xchg esi,[ebx+4] |
lea eax,[edi+16] |
cmp eax,[display_buffer] |
jae out_of_memory |
mov eax,esi |
stos dword [edi] |
mov eax,[esi+12] |
stos dword [edi] |
xor eax,eax |
stos dword [edi] |
stos dword [edi] |
pop ecx |
add ebx,8 |
loop make_data_records |
cmp ebx,edx |
jb update_language_directories |
pop ebx ; file handle |
mov esi,ebp |
mov ebp,edi |
update_data_records: |
push ebp |
mov ecx,edi |
mov eax,[current_section] |
sub ecx,[eax+14h] |
add ecx,[eax+0Ch] |
xchg ecx,[esi] |
mov edx,[ecx] |
xor al,al |
call lseek |
mov edx,edi |
mov ecx,[esi+4] |
add edi,ecx |
cmp edi,[display_buffer] |
ja out_of_memory |
call read |
mov eax,edi |
sub eax,[resource_data] |
and eax,11b |
jz resource_data_alignment_ok |
mov ecx,4 |
sub ecx,eax |
xor al,al |
rep stos byte [edi] |
resource_data_alignment_ok: |
pop ebp |
add esi,16 |
cmp esi,ebp |
jb update_data_records |
pop esi |
call close |
mov eax,edi |
sub eax,[resource_data] |
mov [resource_size],eax |
resource_done: |
ret |
make_pe_fixups: |
push esi |
mov ecx,[number_of_relocations] |
jecxz fixups_done |
mov esi,[free_additional_memory] |
mov eax,ecx |
shl eax,2 |
sub esi,eax |
mov [free_additional_memory],esi |
or [number_of_relocations],-1 |
xor edx,edx |
mov ebp,edi |
make_fixups: |
cmp [esi],edx |
jb store_fixup |
mov eax,edi |
sub eax,ebp |
test eax,11b |
jz fixups_block |
xor ax,ax |
stos word [edi] |
add dword [ebx],2 |
fixups_block: |
mov eax,edx |
add edx,1000h |
cmp [esi],edx |
jae fixups_block |
stos dword [edi] |
mov ebx,edi |
mov eax,8 |
stos dword [edi] |
store_fixup: |
add dword [ebx],2 |
mov eax,[esi] |
and ax,0FFFh |
test [format_flags],8 |
jnz fixup_64bit |
or ax,3000h |
jmp fixup_ok |
fixup_64bit: |
or ax,0A000h |
fixup_ok: |
stos word [edi] |
add esi,4 |
loop make_fixups |
fixups_done: |
pop esi |
ret |
close_pe: |
call close_pe_section |
mov edx,[code_start] |
mov [edx+50h],eax |
call make_timestamp |
mov edx,[code_start] |
mov [edx+8],eax |
mov eax,[number_of_relocations] |
cmp eax,0 |
jle pe_flags_ok |
or word [edx+16h],1 |
shl eax,2 |
sub [free_additional_memory],eax |
pe_flags_ok: |
mov eax,[number_of_sections] |
mov [edx+6],ax |
imul eax,28h |
movzx ecx,word [edx+14h] |
lea eax,[eax+18h+ecx] |
add eax,[stub_size] |
mov ecx,[edx+3Ch] |
dec ecx |
add eax,ecx |
not ecx |
and eax,ecx |
cmp eax,[edx+54h] |
je pe_sections_ok |
or [next_pass_needed],-1 |
pe_sections_ok: |
xor ecx,ecx |
add edx,78h |
test [format_flags],8 |
jz process_directories |
add edx,10h |
process_directories: |
mov eax,[edx+ecx*8] |
or eax,eax |
jz directory_ok |
cmp dword [edx+ecx*8+4],-1 |
jne directory_ok |
section_data: |
mov ebx,[edx+ecx*8] |
mov eax,[ebx+0Ch] |
mov [edx+ecx*8],eax ; directory rva |
mov eax,[ebx+8] |
mov [edx+ecx*8+4],eax ; directory size |
directory_ok: |
inc cl |
cmp cl,10h |
jb process_directories |
mov ebx,[code_start] |
sub ebx,[stub_size] |
mov ecx,edi |
sub ecx,ebx |
mov ebp,ecx |
shr ecx,1 |
xor eax,eax |
cdq |
calculate_checksum: |
mov dx,[ebx] |
add eax,edx |
mov dx,ax |
shr eax,16 |
add eax,edx |
add ebx,2 |
loop calculate_checksum |
add eax,ebp |
mov ebx,[code_start] |
mov [ebx+58h],eax |
ret |
format_coff: |
mov eax,[additional_memory] |
mov [symbols_stream],eax |
mov ebx,eax |
add eax,18h |
cmp eax,[structures_buffer] |
jae out_of_memory |
mov [free_additional_memory],eax |
xor eax,eax |
mov [ebx],al |
mov [ebx+4],eax |
mov [ebx+8],edi |
mov al,4 |
mov [ebx+10h],eax |
mov al,60h |
bt [format_flags],0 |
jnc flat_section_flags_ok |
or eax,0E0000000h |
flat_section_flags_ok: |
mov dword [ebx+14h],eax |
mov [current_section],ebx |
mov [number_of_sections],0 |
mov dword [org_origin],edi |
mov dword [org_origin+4],0 |
mov [org_registers],0 |
mov [org_start],edi |
mov [org_symbol],ebx |
mov [labels_type],2 |
mov [code_type],32 |
test [format_flags],8 |
jz instruction_assembled |
mov [labels_type],4 |
mov [code_type],64 |
jmp instruction_assembled |
coff_section: |
call close_coff_section |
mov ebx,[free_additional_memory] |
lea eax,[ebx+18h] |
cmp eax,[structures_buffer] |
jae out_of_memory |
mov [free_additional_memory],eax |
mov [current_section],ebx |
inc [number_of_sections] |
xor eax,eax |
mov [ebx],al |
mov [ebx+8],edi |
mov dword [org_origin],edi |
mov dword [org_origin+4],0 |
mov [org_registers],0 |
mov [org_start],edi |
mov [org_symbol],ebx |
mov [labels_type],2 |
test [format_flags],8 |
jz coff_labels_type_ok |
mov [labels_type],4 |
coff_labels_type_ok: |
mov [ebx+10h],eax |
mov [ebx+14h],eax |
lods word [esi] |
cmp ax,'(' |
jne invalid_argument |
mov [ebx+4],esi |
mov ecx,[esi] |
lea esi,[esi+4+ecx+1] |
cmp ecx,8 |
ja name_too_long |
coff_section_flags: |
cmp byte [esi],1Ch |
je coff_section_alignment |
cmp byte [esi],19h |
jne coff_section_settings_ok |
inc esi |
lods byte [esi] |
bt [format_flags],0 |
jc coff_section_flag_ok |
cmp al,7 |
ja invalid_argument |
coff_section_flag_ok: |
mov cl,al |
mov eax,1 |
shl eax,cl |
test dword [ebx+14h],eax |
jnz setting_already_specified |
or dword [ebx+14h],eax |
jmp coff_section_flags |
coff_section_alignment: |
bt [format_flags],0 |
jnc invalid_argument |
inc esi |
lods byte [esi] |
or al,al |
jnz invalid_argument |
lods byte [esi] |
cmp al,'(' |
jne invalid_argument |
cmp byte [esi],'.' |
je invalid_value |
push ebx |
call get_dword_value |
pop ebx |
cmp [value_type],0 |
jne invalid_use_of_symbol |
mov edx,eax |
dec edx |
test eax,edx |
jnz invalid_value |
or eax,eax |
jz invalid_value |
cmp eax,2000h |
ja invalid_value |
bsf edx,eax |
inc edx |
shl edx,20 |
or [ebx+14h],edx |
xchg [ebx+10h],eax |
or eax,eax |
jnz setting_already_specified |
jmp coff_section_flags |
coff_section_settings_ok: |
cmp dword [ebx+10h],0 |
jne instruction_assembled |
mov dword [ebx+10h],4 |
bt [format_flags],0 |
jnc instruction_assembled |
or dword [ebx+14h],300000h |
jmp instruction_assembled |
close_coff_section: |
mov ebx,[current_section] |
mov eax,edi |
mov edx,[ebx+8] |
sub eax,edx |
mov [ebx+0Ch],eax |
xor eax,eax |
xchg [undefined_data_end],eax |
cmp eax,edi |
jne coff_section_ok |
cmp edx,[undefined_data_start] |
jne coff_section_ok |
mov edi,edx |
or byte [ebx+14h],80h |
coff_section_ok: |
ret |
mark_coff_relocation: |
cmp [value_type],3 |
je coff_relocation_relative |
push ebx eax |
test [format_flags],8 |
jnz coff_64bit_relocation |
mov al,6 |
jmp coff_relocation |
coff_64bit_relocation: |
mov al,1 |
jmp coff_relocation |
coff_relocation_relative: |
push ebx |
bt [format_flags],0 |
jnc relative_ok |
mov ebx,[current_section] |
mov ebx,[ebx+8] |
sub ebx,edi |
sub eax,ebx |
add eax,4 |
relative_ok: |
push eax |
mov al,20 |
test [format_flags],8 |
jnz relative_coff_64bit_relocation |
cmp [labels_type],2 |
jne invalid_use_of_symbol |
jmp coff_relocation |
relative_coff_64bit_relocation: |
mov al,4 |
cmp [labels_type],4 |
jne invalid_use_of_symbol |
coff_relocation: |
mov ebx,[free_additional_memory] |
add ebx,0Ch |
cmp ebx,[structures_buffer] |
jae out_of_memory |
mov [free_additional_memory],ebx |
mov byte [ebx-0Ch],al |
mov eax,[current_section] |
mov eax,[eax+8] |
neg eax |
add eax,edi |
mov [ebx-0Ch+4],eax |
mov eax,[symbol_identifier] |
mov [ebx-0Ch+8],eax |
pop eax ebx |
ret |
close_coff: |
call close_coff_section |
cmp [next_pass_needed],0 |
je coff_closed |
mov eax,[symbols_stream] |
mov [free_additional_memory],eax |
coff_closed: |
ret |
coff_formatter: |
sub edi,[code_start] |
mov [code_size],edi |
call prepare_default_section |
mov edi,[free_additional_memory] |
mov ebx,edi |
mov ecx,28h shr 2 |
imul ecx,[number_of_sections] |
add ecx,14h shr 2 |
lea eax,[edi+ecx*4] |
cmp eax,[structures_buffer] |
jae out_of_memory |
xor eax,eax |
rep stos dword [edi] |
mov word [ebx],14Ch |
test [format_flags],8 |
jz coff_magic_ok |
mov word [ebx],8664h |
coff_magic_ok: |
mov word [ebx+12h],104h |
bt [format_flags],0 |
jnc coff_flags_ok |
or byte [ebx+12h],80h |
coff_flags_ok: |
push ebx |
call make_timestamp |
pop ebx |
mov [ebx+4],eax |
mov eax,[number_of_sections] |
mov [ebx+2],ax |
mov esi,[symbols_stream] |
xor ecx,ecx |
enumerate_symbols: |
cmp esi,[free_additional_memory] |
je symbols_enumerated |
mov dl,[esi] |
or dl,dl |
jz enumerate_section |
cmp dl,80h |
je enumerate_public |
ja enumerate_extrn |
add esi,0Ch |
jmp enumerate_symbols |
enumerate_section: |
mov edx,ecx |
shl edx,8 |
mov [esi],edx |
inc ecx |
add esi,18h |
jmp enumerate_symbols |
enumerate_public: |
mov edx,eax |
shl edx,8 |
mov dl,80h |
mov [esi],edx |
mov edx,[esi+8] |
add esi,10h |
inc eax |
cmp byte [edx+11],2 |
jne enumerate_symbols |
mov edx,[edx+20] |
cmp byte [edx],81h |
jne enumerate_symbols |
inc eax |
jmp enumerate_symbols |
enumerate_extrn: |
mov edx,eax |
shl edx,8 |
mov dl,81h |
mov [esi],edx |
add esi,0Ch |
inc eax |
jmp enumerate_symbols |
prepare_default_section: |
mov ebx,[symbols_stream] |
cmp dword [ebx+0Ch],0 |
jne default_section_ok |
cmp [number_of_sections],0 |
je default_section_ok |
mov edx,ebx |
find_references_to_default_section: |
cmp ebx,[free_additional_memory] |
jne check_reference |
add [symbols_stream],18h |
ret |
check_reference: |
mov al,[ebx] |
or al,al |
jz skip_other_section |
cmp al,80h |
je check_public_reference |
ja next_reference |
cmp edx,[ebx+8] |
je default_section_ok |
next_reference: |
add ebx,0Ch |
jmp find_references_to_default_section |
check_public_reference: |
mov eax,[ebx+8] |
add ebx,10h |
test byte [eax+8],1 |
jz find_references_to_default_section |
mov cx,[current_pass] |
cmp cx,[eax+16] |
jne find_references_to_default_section |
cmp edx,[eax+20] |
je default_section_ok |
jmp find_references_to_default_section |
skip_other_section: |
add ebx,18h |
jmp find_references_to_default_section |
default_section_ok: |
inc [number_of_sections] |
ret |
symbols_enumerated: |
mov [ebx+0Ch],eax |
mov ebp,edi |
sub ebp,ebx |
push ebp |
lea edi,[ebx+14h] |
mov esi,[symbols_stream] |
find_section: |
cmp esi,[free_additional_memory] |
je sections_finished |
mov al,[esi] |
or al,al |
jz section_found |
add esi,0Ch |
cmp al,80h |
jne find_section |
add esi,4 |
jmp find_section |
section_found: |
push esi edi |
mov esi,[esi+4] |
or esi,esi |
jz default_section |
mov ecx,[esi] |
add esi,4 |
rep movs byte [edi],[esi] |
jmp section_name_ok |
default_section: |
mov al,'.' |
stos byte [edi] |
mov eax,'flat' |
stos dword [edi] |
section_name_ok: |
pop edi esi |
mov eax,[esi+0Ch] |
mov [edi+10h],eax |
mov eax,[esi+14h] |
mov [edi+24h],eax |
test al,80h |
jnz section_ptr_ok |
mov eax,[esi+8] |
sub eax,[code_start] |
add eax,ebp |
mov [edi+14h],eax |
section_ptr_ok: |
mov ebx,[code_start] |
mov edx,[code_size] |
add ebx,edx |
add edx,ebp |
xor ecx,ecx |
add esi,18h |
find_relocations: |
cmp esi,[free_additional_memory] |
je section_relocations_done |
mov al,[esi] |
or al,al |
jz section_relocations_done |
cmp al,80h |
jb add_relocation |
ja next_relocation |
add esi,10h |
jmp find_relocations |
add_relocation: |
lea eax,[ebx+0Ah] |
cmp eax,[display_buffer] |
ja out_of_memory |
mov eax,[esi+4] |
mov [ebx],eax |
mov eax,[esi+8] |
mov eax,[eax] |
shr eax,8 |
mov [ebx+4],eax |
movzx ax,byte [esi] |
mov [ebx+8],ax |
add ebx,0Ah |
inc ecx |
next_relocation: |
add esi,0Ch |
jmp find_relocations |
section_relocations_done: |
cmp ecx,10000h |
jb section_relocations_count_16bit |
bt [format_flags],0 |
jnc format_limitations_exceeded |
mov word [edi+20h],0FFFFh |
or dword [edi+24h],1000000h |
mov [edi+18h],edx |
push esi edi |
push ecx |
lea esi,[ebx-1] |
add ebx,0Ah |
lea edi,[ebx-1] |
imul ecx,0Ah |
std |
rep movs byte [edi],[esi] |
cld |
pop ecx |
inc esi |
inc ecx |
mov [esi],ecx |
xor eax,eax |
mov [esi+4],eax |
mov [esi+8],ax |
pop edi esi |
jmp section_relocations_ok |
section_relocations_count_16bit: |
mov [edi+20h],cx |
jcxz section_relocations_ok |
mov [edi+18h],edx |
section_relocations_ok: |
sub ebx,[code_start] |
mov [code_size],ebx |
add edi,28h |
jmp find_section |
sections_finished: |
mov edx,[free_additional_memory] |
mov ebx,[code_size] |
add ebp,ebx |
mov [edx+8],ebp |
add ebx,[code_start] |
mov edi,ebx |
mov ecx,[edx+0Ch] |
imul ecx,12h shr 1 |
xor eax,eax |
shr ecx,1 |
jnc zero_symbols_table |
stos word [edi] |
zero_symbols_table: |
rep stos dword [edi] |
mov edx,edi |
stos dword [edi] |
mov esi,[symbols_stream] |
make_section_symbols: |
cmp esi,[free_additional_memory] |
je section_symbols_ok |
mov al,[esi] |
or al,al |
jz add_section_symbol |
add esi,0Ch |
cmp al,80h |
jne make_section_symbols |
add esi,4 |
jmp make_section_symbols |
add_section_symbol: |
call store_symbol_name |
mov eax,[esi] |
shr eax,8 |
inc eax |
mov [ebx+0Ch],ax |
mov byte [ebx+10h],3 |
add esi,18h |
add ebx,12h |
jmp make_section_symbols |
section_symbols_ok: |
mov esi,[symbols_stream] |
make_symbols_table: |
cmp esi,[free_additional_memory] |
je symbols_table_ok |
mov al,[esi] |
cmp al,80h |
je add_public_symbol |
ja add_extrn_symbol |
add esi,0Ch |
or al,al |
jnz make_symbols_table |
add esi,0Ch |
jmp make_symbols_table |
add_extrn_symbol: |
call store_symbol_name |
mov byte [ebx+10h],2 |
add esi,0Ch |
add ebx,12h |
jmp make_symbols_table |
add_public_symbol: |
call store_symbol_name |
mov eax,[esi+0Ch] |
mov [current_line],eax |
mov eax,[esi+8] |
test byte [eax+8],1 |
jz undefined_symbol |
mov cx,[current_pass] |
cmp cx,[eax+16] |
jne undefined_symbol |
mov cl,[eax+11] |
or cl,cl |
jz public_constant |
test [format_flags],8 |
jnz check_64bit_public_symbol |
cmp cl,2 |
je public_symbol_type_ok |
jmp invalid_use_of_symbol |
check_64bit_public_symbol: |
cmp cl,4 |
jne invalid_use_of_symbol |
public_symbol_type_ok: |
mov ecx,[eax+20] |
mov ecx,[ecx] |
cmp cl,81h |
je alias_symbol |
or cl,cl |
jnz invalid_use_of_symbol |
shr ecx,8 |
inc cx |
mov [ebx+0Ch],cx |
public_symbol_section_ok: |
cmp dword [eax+4],0 |
je store_public_symbol |
cmp dword [eax+4],-1 |
jne value_out_of_range |
bt dword [eax],31 |
jnc value_out_of_range |
store_public_symbol: |
mov eax,[eax] |
mov [ebx+8],eax |
mov byte [ebx+10h],2 |
add esi,10h |
add ebx,12h |
jmp make_symbols_table |
alias_symbol: |
bt [format_flags],0 |
jnc invalid_use_of_symbol |
mov ecx,[eax] |
or ecx,[eax+4] |
jnz invalid_use_of_symbol |
mov byte [ebx+10h],69h |
mov byte [ebx+11h],1 |
add ebx,12h |
mov ecx,[eax+20] |
mov ecx,[ecx] |
shr ecx,8 |
mov [ebx],ecx |
mov byte [ebx+4],3 |
add esi,10h |
add ebx,12h |
jmp make_symbols_table |
public_constant: |
mov word [ebx+0Ch],0FFFFh |
jmp public_symbol_section_ok |
symbols_table_ok: |
mov eax,edi |
sub eax,edx |
mov [edx],eax |
sub edi,[code_start] |
mov [code_size],edi |
mov [written_size],0 |
mov edx,[output_file] |
call create |
jc write_failed |
mov edx,[free_additional_memory] |
pop ecx |
add [written_size],ecx |
call write |
jc write_failed |
jmp write_output |
store_symbol_name: |
push esi |
mov esi,[esi+4] |
or esi,esi |
jz default_name |
lods dword [esi] |
mov ecx,eax |
cmp ecx,8 |
ja add_string |
push edi |
mov edi,ebx |
rep movs byte [edi],[esi] |
pop edi esi |
ret |
default_name: |
mov dword [ebx],'.fla' |
mov dword [ebx+4],'t' |
pop esi |
ret |
add_string: |
mov eax,edi |
sub eax,edx |
mov [ebx+4],eax |
inc ecx |
rep movs byte [edi],[esi] |
pop esi |
ret |
format_elf: |
test [format_flags],8 |
jnz format_elf64 |
mov edx,edi |
mov ecx,34h shr 2 |
lea eax,[edi+ecx*4] |
cmp eax,[display_buffer] |
jae out_of_memory |
xor eax,eax |
rep stos dword [edi] |
mov dword [edx],7Fh + 'ELF' shl 8 |
mov al,1 |
mov [edx+4],al |
mov [edx+5],al |
mov [edx+6],al |
mov [edx+14h],al |
mov byte [edx+12h],3 |
mov byte [edx+28h],34h |
mov byte [edx+2Eh],28h |
mov [code_type],32 |
cmp word [esi],1D19h |
je format_elf_exe |
mov [labels_type],2 |
elf_header_ok: |
mov byte [edx+10h],1 |
mov eax,[additional_memory] |
mov [symbols_stream],eax |
mov ebx,eax |
add eax,18h |
cmp eax,[structures_buffer] |
jae out_of_memory |
mov [free_additional_memory],eax |
xor eax,eax |
mov [current_section],ebx |
mov [number_of_sections],eax |
mov dword [org_origin],edi |
mov dword [org_origin+4],eax |
mov [org_registers],eax |
mov [org_start],edi |
mov [org_symbol],ebx |
mov [ebx],al |
mov [ebx+4],eax |
mov [ebx+8],edi |
mov al,111b |
mov [ebx+14h],eax |
mov al,4 |
mov [ebx+10h],eax |
test [format_flags],8 |
jz instruction_assembled |
mov byte [ebx+10h],8 |
jmp instruction_assembled |
format_elf64: |
mov edx,edi |
mov ecx,40h shr 2 |
lea eax,[edi+ecx*4] |
cmp eax,[display_buffer] |
jae out_of_memory |
xor eax,eax |
rep stos dword [edi] |
mov dword [edx],7Fh + 'ELF' shl 8 |
mov al,1 |
mov [edx+5],al |
mov [edx+6],al |
mov [edx+14h],al |
mov byte [edx+4],2 |
mov byte [edx+12h],62 |
mov byte [edx+34h],40h |
mov byte [edx+3Ah],40h |
mov [code_type],64 |
cmp word [esi],1D19h |
je format_elf64_exe |
mov [labels_type],4 |
jmp elf_header_ok |
elf_section: |
bt [format_flags],0 |
jc elf_exe_section |
call close_coff_section |
mov ebx,[free_additional_memory] |
lea eax,[ebx+18h] |
cmp eax,[structures_buffer] |
jae out_of_memory |
mov [free_additional_memory],eax |
mov [current_section],ebx |
inc word [number_of_sections] |
jz format_limitations_exceeded |
xor eax,eax |
mov [ebx],al |
mov [ebx+8],edi |
mov dword [org_origin],edi |
mov dword [org_origin+4],0 |
mov [org_registers],0 |
mov [org_start],edi |
mov [org_symbol],ebx |
test [format_flags],8 |
jnz elf64_labels_type |
mov [labels_type],2 |
jmp elf_labels_type_ok |
elf64_labels_type: |
mov [labels_type],4 |
elf_labels_type_ok: |
mov [ebx+10h],eax |
mov al,10b |
mov [ebx+14h],eax |
lods word [esi] |
cmp ax,'(' |
jne invalid_argument |
mov [ebx+4],esi |
mov ecx,[esi] |
lea esi,[esi+4+ecx+1] |
elf_section_flags: |
cmp byte [esi],1Ch |
je elf_section_alignment |
cmp byte [esi],19h |
jne elf_section_settings_ok |
inc esi |
lods byte [esi] |
sub al,28 |
xor al,11b |
test al,not 10b |
jnz invalid_argument |
mov cl,al |
mov al,1 |
shl al,cl |
test byte [ebx+14h],al |
jnz setting_already_specified |
or byte [ebx+14h],al |
jmp elf_section_flags |
elf_section_alignment: |
inc esi |
lods byte [esi] |
or al,al |
jnz invalid_argument |
lods byte [esi] |
cmp al,'(' |
jne invalid_argument |
cmp byte [esi],'.' |
je invalid_value |
push ebx |
call get_dword_value |
pop ebx |
cmp [value_type],0 |
jne invalid_use_of_symbol |
mov edx,eax |
dec edx |
test eax,edx |
jnz invalid_value |
or eax,eax |
jz invalid_value |
xchg [ebx+10h],eax |
or eax,eax |
jnz setting_already_specified |
jmp elf_section_flags |
elf_section_settings_ok: |
cmp dword [ebx+10h],0 |
jne instruction_assembled |
mov dword [ebx+10h],4 |
test [format_flags],8 |
jz instruction_assembled |
mov byte [ebx+10h],8 |
jmp instruction_assembled |
mark_elf_relocation: |
cmp [value_type],3 |
je elf_relocation_relative |
push ebx eax |
mov al,1 |
jmp coff_relocation |
elf_relocation_relative: |
cmp [labels_type],0 |
je invalid_use_of_symbol |
push ebx |
mov ebx,[current_section] |
mov ebx,[ebx+8] |
sub ebx,edi |
sub eax,ebx |
push eax |
mov al,2 |
jmp coff_relocation |
close_elf: |
bt [format_flags],0 |
jc close_elf_exe |
call close_coff_section |
cmp [next_pass_needed],0 |
je elf_closed |
mov eax,[symbols_stream] |
mov [free_additional_memory],eax |
elf_closed: |
ret |
elf_formatter: |
push edi |
call prepare_default_section |
mov esi,[symbols_stream] |
mov edi,[free_additional_memory] |
xor eax,eax |
mov ecx,4 |
rep stos dword [edi] |
test [format_flags],8 |
jz find_first_section |
mov ecx,2 |
rep stos dword [edi] |
find_first_section: |
mov al,[esi] |
or al,al |
jz first_section_found |
cmp al,80h |
jne skip_other_symbol |
add esi,4 |
skip_other_symbol: |
add esi,0Ch |
jmp find_first_section |
first_section_found: |
mov ebx,esi |
mov ebp,esi |
add esi,18h |
xor ecx,ecx |
xor edx,edx |
find_next_section: |
cmp esi,[free_additional_memory] |
je make_section_symbol |
mov al,[esi] |
or al,al |
jz make_section_symbol |
cmp al,80h |
je skip_public |
ja skip_extrn |
or byte [ebx+14h],40h |
skip_extrn: |
add esi,0Ch |
jmp find_next_section |
skip_public: |
add esi,10h |
jmp find_next_section |
make_section_symbol: |
mov eax,edi |
xchg eax,[ebx+4] |
stos dword [edi] |
test [format_flags],8 |
jnz elf64_section_symbol |
xor eax,eax |
stos dword [edi] |
stos dword [edi] |
call store_section_index |
jmp section_symbol_ok |
store_section_index: |
inc ecx |
mov eax,ecx |
shl eax,8 |
mov [ebx],eax |
inc dx |
jz format_limitations_exceeded |
mov eax,edx |
shl eax,16 |
mov al,3 |
test byte [ebx+14h],40h |
jz section_index_ok |
or ah,-1 |
inc dx |
jz format_limitations_exceeded |
section_index_ok: |
stos dword [edi] |
ret |
elf64_section_symbol: |
call store_section_index |
xor eax,eax |
stos dword [edi] |
stos dword [edi] |
stos dword [edi] |
stos dword [edi] |
section_symbol_ok: |
mov ebx,esi |
add esi,18h |
cmp ebx,[free_additional_memory] |
jne find_next_section |
inc dx |
jz format_limitations_exceeded |
mov [current_section],edx |
mov esi,[symbols_stream] |
find_other_symbols: |
cmp esi,[free_additional_memory] |
je elf_symbol_table_ok |
mov al,[esi] |
or al,al |
jz skip_section |
cmp al,80h |
je make_public_symbol |
ja make_extrn_symbol |
add esi,0Ch |
jmp find_other_symbols |
skip_section: |
add esi,18h |
jmp find_other_symbols |
make_public_symbol: |
mov eax,[esi+0Ch] |
mov [current_line],eax |
mov ebx,[esi+8] |
test byte [ebx+8],1 |
jz undefined_symbol |
mov ax,[current_pass] |
cmp ax,[ebx+16] |
jne undefined_symbol |
mov dl,[ebx+11] |
or dl,dl |
jz public_absolute |
mov eax,[ebx+20] |
cmp byte [eax],0 |
jne invalid_use_of_symbol |
mov eax,[eax+4] |
test [format_flags],8 |
jnz elf64_public |
cmp dl,2 |
jne invalid_use_of_symbol |
mov dx,[eax+0Eh] |
jmp section_for_public_ok |
elf64_public: |
cmp dl,4 |
jne invalid_use_of_symbol |
mov dx,[eax+6] |
jmp section_for_public_ok |
public_absolute: |
mov dx,0FFF1h |
section_for_public_ok: |
mov eax,[esi+4] |
stos dword [edi] |
test [format_flags],8 |
jnz elf64_public_symbol |
call get_public_value |
stos dword [edi] |
xor eax,eax |
mov al,[ebx+10] |
stos dword [edi] |
mov eax,edx |
shl eax,16 |
mov al,10h |
stos dword [edi] |
jmp public_symbol_ok |
elf64_public_symbol: |
mov eax,edx |
shl eax,16 |
mov al,10h |
stos dword [edi] |
call get_public_value |
stos dword [edi] |
xor eax,eax |
stos dword [edi] |
mov al,[ebx+10] |
stos dword [edi] |
xor al,al |
stos dword [edi] |
public_symbol_ok: |
inc ecx |
mov eax,ecx |
shl eax,8 |
mov al,80h |
mov [esi],eax |
add esi,10h |
jmp find_other_symbols |
get_public_value: |
mov eax,[ebx] |
cmp dword [ebx+4],0 |
je public_value_ok |
cmp dword [ebx+4],-1 |
jne value_out_of_range |
bt eax,31 |
jnc value_out_of_range |
public_value_ok: |
ret |
make_extrn_symbol: |
mov eax,[esi+4] |
stos dword [edi] |
test [format_flags],8 |
jnz elf64_extrn_symbol |
xor eax,eax |
stos dword [edi] |
mov eax,[esi+8] |
stos dword [edi] |
mov eax,10h |
stos dword [edi] |
jmp extrn_symbol_ok |
elf64_extrn_symbol: |
mov eax,10h |
stos dword [edi] |
xor al,al |
stos dword [edi] |
stos dword [edi] |
mov eax,[esi+8] |
stos dword [edi] |
xor eax,eax |
stos dword [edi] |
extrn_symbol_ok: |
inc ecx |
mov eax,ecx |
shl eax,8 |
mov al,81h |
mov [esi],eax |
add esi,0Ch |
jmp find_other_symbols |
elf_symbol_table_ok: |
mov edx,edi |
mov ebx,[free_additional_memory] |
xor al,al |
stos byte [edi] |
add edi,16 |
mov [edx+1],edx |
add ebx,10h |
test [format_flags],8 |
jz make_string_table |
add ebx,8 |
make_string_table: |
cmp ebx,edx |
je elf_string_table_ok |
test [format_flags],8 |
jnz make_elf64_string |
cmp byte [ebx+0Dh],0 |
je rel_prefix_ok |
mov byte [ebx+0Dh],0 |
mov eax,'.rel' |
stos dword [edi] |
rel_prefix_ok: |
mov esi,edi |
sub esi,edx |
xchg esi,[ebx] |
add ebx,10h |
make_elf_string: |
or esi,esi |
jz default_string |
lods dword [esi] |
mov ecx,eax |
rep movs byte [edi],[esi] |
xor al,al |
stos byte [edi] |
jmp make_string_table |
make_elf64_string: |
cmp byte [ebx+5],0 |
je elf64_rel_prefix_ok |
mov byte [ebx+5],0 |
mov eax,'.rel' |
stos dword [edi] |
mov al,'a' |
stos byte [edi] |
elf64_rel_prefix_ok: |
mov esi,edi |
sub esi,edx |
xchg esi,[ebx] |
add ebx,18h |
jmp make_elf_string |
default_string: |
mov eax,'.fla' |
stos dword [edi] |
mov ax,'t' |
stos word [edi] |
jmp make_string_table |
elf_string_table_ok: |
mov [edx+1+8],edi |
mov ebx,[code_start] |
mov eax,edi |
sub eax,[free_additional_memory] |
test [format_flags],8 |
jnz finish_elf64_header |
mov [ebx+20h],eax |
mov eax,[current_section] |
inc ax |
jz format_limitations_exceeded |
mov [ebx+32h],ax |
inc ax |
jz format_limitations_exceeded |
mov [ebx+30h],ax |
jmp elf_header_finished |
finish_elf64_header: |
mov [ebx+28h],eax |
mov eax,[current_section] |
inc ax |
jz format_limitations_exceeded |
mov [ebx+3Eh],ax |
inc ax |
jz format_limitations_exceeded |
mov [ebx+3Ch],ax |
elf_header_finished: |
xor eax,eax |
mov ecx,10 |
rep stos dword [edi] |
test [format_flags],8 |
jz elf_null_section_ok |
mov ecx,6 |
rep stos dword [edi] |
elf_null_section_ok: |
mov esi,ebp |
xor ecx,ecx |
make_section_entry: |
mov ebx,edi |
mov eax,[esi+4] |
mov eax,[eax] |
stos dword [edi] |
mov eax,1 |
cmp dword [esi+0Ch],0 |
je bss_section |
test byte [esi+14h],80h |
jz section_type_ok |
bss_section: |
mov al,8 |
section_type_ok: |
stos dword [edi] |
mov eax,[esi+14h] |
and al,3Fh |
call store_elf_machine_word |
xor eax,eax |
call store_elf_machine_word |
mov eax,[esi+8] |
mov [image_base],eax |
sub eax,[code_start] |
call store_elf_machine_word |
mov eax,[esi+0Ch] |
call store_elf_machine_word |
xor eax,eax |
stos dword [edi] |
stos dword [edi] |
mov eax,[esi+10h] |
call store_elf_machine_word |
xor eax,eax |
call store_elf_machine_word |
inc ecx |
add esi,18h |
xchg edi,[esp] |
mov ebp,edi |
convert_relocations: |
cmp esi,[free_additional_memory] |
je relocations_converted |
mov al,[esi] |
or al,al |
jz relocations_converted |
cmp al,80h |
jb make_relocation_entry |
ja relocation_entry_ok |
add esi,10h |
jmp convert_relocations |
make_relocation_entry: |
test [format_flags],8 |
jnz make_elf64_relocation_entry |
mov eax,[esi+4] |
stos dword [edi] |
mov eax,[esi+8] |
mov eax,[eax] |
mov al,[esi] |
stos dword [edi] |
jmp relocation_entry_ok |
make_elf64_relocation_entry: |
mov eax,[esi+4] |
stos dword [edi] |
xor eax,eax |
stos dword [edi] |
movzx eax,byte [esi] |
stos dword [edi] |
mov eax,[esi+8] |
mov eax,[eax] |
shr eax,8 |
stos dword [edi] |
xor eax,eax |
stos dword [edi] |
stos dword [edi] |
relocation_entry_ok: |
add esi,0Ch |
jmp convert_relocations |
store_elf_machine_word: |
stos dword [edi] |
test [format_flags],8 |
jz elf_machine_word_ok |
mov dword [edi],0 |
add edi,4 |
elf_machine_word_ok: |
ret |
relocations_converted: |
cmp edi,ebp |
xchg edi,[esp] |
je rel_section_ok |
mov eax,[ebx] |
sub eax,4 |
test [format_flags],8 |
jz store_relocations_name_offset |
dec eax |
store_relocations_name_offset: |
stos dword [edi] |
test [format_flags],8 |
jnz rela_section |
mov eax,9 |
jmp store_relocations_type |
rela_section: |
mov eax,4 |
store_relocations_type: |
stos dword [edi] |
xor al,al |
call store_elf_machine_word |
call store_elf_machine_word |
mov eax,ebp |
sub eax,[code_start] |
call store_elf_machine_word |
mov eax,[esp] |
sub eax,ebp |
call store_elf_machine_word |
mov eax,[current_section] |
stos dword [edi] |
mov eax,ecx |
stos dword [edi] |
inc ecx |
test [format_flags],8 |
jnz finish_elf64_rela_section |
mov eax,4 |
stos dword [edi] |
mov al,8 |
stos dword [edi] |
jmp rel_section_ok |
finish_elf64_rela_section: |
mov eax,8 |
stos dword [edi] |
xor al,al |
stos dword [edi] |
mov al,24 |
stos dword [edi] |
xor al,al |
stos dword [edi] |
rel_section_ok: |
cmp esi,[free_additional_memory] |
jne make_section_entry |
pop eax |
mov ebx,[code_start] |
sub eax,ebx |
mov [code_size],eax |
mov ecx,20h |
test [format_flags],8 |
jz adjust_elf_section_headers_offset |
mov ecx,28h |
adjust_elf_section_headers_offset: |
add [ebx+ecx],eax |
mov eax,1 |
stos dword [edi] |
mov al,2 |
stos dword [edi] |
xor al,al |
call store_elf_machine_word |
call store_elf_machine_word |
mov eax,[code_size] |
call store_elf_machine_word |
mov eax,[edx+1] |
sub eax,[free_additional_memory] |
call store_elf_machine_word |
mov eax,[current_section] |
inc eax |
stos dword [edi] |
mov eax,[number_of_sections] |
inc eax |
stos dword [edi] |
test [format_flags],8 |
jnz finish_elf64_sym_section |
mov eax,4 |
stos dword [edi] |
mov al,10h |
stos dword [edi] |
jmp sym_section_ok |
finish_elf64_sym_section: |
mov eax,8 |
stos dword [edi] |
xor al,al |
stos dword [edi] |
mov al,18h |
stos dword [edi] |
xor al,al |
stos dword [edi] |
sym_section_ok: |
mov al,1+8 |
stos dword [edi] |
mov al,3 |
stos dword [edi] |
xor al,al |
call store_elf_machine_word |
call store_elf_machine_word |
mov eax,[edx+1] |
sub eax,[free_additional_memory] |
add eax,[code_size] |
call store_elf_machine_word |
mov eax,[edx+1+8] |
sub eax,[edx+1] |
call store_elf_machine_word |
xor eax,eax |
stos dword [edi] |
stos dword [edi] |
mov al,1 |
call store_elf_machine_word |
xor eax,eax |
call store_elf_machine_word |
mov eax,'tab' |
mov dword [edx+1],'.sym' |
mov [edx+1+4],eax |
mov dword [edx+1+8],'.str' |
mov [edx+1+8+4],eax |
mov [written_size],0 |
mov edx,[output_file] |
call create |
jc write_failed |
call write_code |
mov ecx,edi |
mov edx,[free_additional_memory] |
sub ecx,edx |
add [written_size],ecx |
call write |
jc write_failed |
jmp output_written |
format_elf_exe: |
add esi,2 |
or [format_flags],1 |
mov [image_base],8048000h |
cmp byte [esi],80h |
jne elf_exe_base_ok |
lods word [esi] |
cmp ah,'(' |
jne invalid_argument |
cmp byte [esi],'.' |
je invalid_value |
push edx |
call get_dword_value |
cmp [value_type],0 |
jne invalid_use_of_symbol |
mov [image_base],eax |
pop edx |
elf_exe_base_ok: |
mov byte [edx+10h],2 |
mov byte [edx+2Ah],20h |
mov ebx,edi |
mov ecx,20h shr 2 |
cmp [current_pass],0 |
je init_elf_exe_sections |
imul ecx,[number_of_sections] |
init_elf_exe_sections: |
xor eax,eax |
rep stos dword [edi] |
mov [number_of_sections],0 |
mov byte [ebx],1 |
mov word [ebx+1Ch],1000h |
mov byte [ebx+18h],111b |
mov eax,edi |
sub eax,[code_start] |
mov [ebx+4],eax |
add eax,[image_base] |
mov [ebx+8],eax |
mov [ebx+0Ch],eax |
mov [edx+18h],eax |
xor edx,edx |
not eax |
not edx |
add eax,1 |
adc edx,0 |
add eax,edi |
adc edx,0 |
mov dword [org_origin],eax |
mov dword [org_origin+4],edx |
mov [org_registers],0 |
mov [org_start],edi |
mov [symbols_stream],edi |
jmp instruction_assembled |
format_elf64_exe: |
add esi,2 |
or [format_flags],1 |
mov [image_base],400000h |
mov [image_base_high],0 |
cmp byte [esi],80h |
jne elf64_exe_base_ok |
lods word [esi] |
cmp ah,'(' |
jne invalid_argument |
cmp byte [esi],'.' |
je invalid_value |
push edx |
call get_qword_value |
cmp [value_type],0 |
jne invalid_use_of_symbol |
mov [image_base],eax |
mov [image_base_high],edx |
pop edx |
elf64_exe_base_ok: |
mov byte [edx+10h],2 |
mov byte [edx+36h],38h |
mov ebx,edi |
mov ecx,38h shr 2 |
cmp [current_pass],0 |
je init_elf64_exe_sections |
imul ecx,[number_of_sections] |
init_elf64_exe_sections: |
xor eax,eax |
rep stos dword [edi] |
mov [number_of_sections],0 |
mov byte [ebx],1 |
mov word [ebx+30h],1000h |
mov byte [ebx+4],111b |
push edx |
mov eax,edi |
sub eax,[code_start] |
mov [ebx+8],eax |
xor edx,edx |
add eax,[image_base] |
adc edx,[image_base_high] |
mov [ebx+10h],eax |
mov [ebx+10h+4],edx |
mov [ebx+18h],eax |
mov [ebx+18h+4],edx |
pop ebx |
mov [ebx+18h],eax |
mov [ebx+18h+4],edx |
not eax |
not edx |
add eax,1 |
adc edx,0 |
add eax,edi |
adc edx,0 |
mov dword [org_origin],eax |
mov dword [org_origin+4],edx |
mov [org_registers],0 |
mov [org_start],edi |
mov [symbols_stream],edi |
jmp instruction_assembled |
elf_entry: |
lods byte [esi] |
cmp al,'(' |
jne invalid_argument |
cmp byte [esi],'.' |
je invalid_value |
test [format_flags],8 |
jnz elf64_entry |
call get_dword_value |
cmp [value_type],0 |
jne invalid_use_of_symbol |
mov edx,[code_start] |
mov [edx+18h],eax |
jmp instruction_assembled |
elf64_entry: |
call get_qword_value |
cmp [value_type],0 |
jne invalid_use_of_symbol |
mov ebx,[code_start] |
mov [ebx+18h],eax |
mov [ebx+1Ch],edx |
jmp instruction_assembled |
elf_exe_section: |
test [format_flags],8 |
jnz elf64_exe_section |
call close_elf_exe_section |
push eax |
mov ebx,[number_of_sections] |
shl ebx,5 |
add ebx,[code_start] |
add ebx,34h |
cmp ebx,[symbols_stream] |
jb new_elf_exe_section |
mov ebx,[symbols_stream] |
sub ebx,20h |
push edi |
mov edi,ebx |
mov ecx,20h shr 2 |
xor eax,eax |
rep stos dword [edi] |
pop edi |
or [next_pass_needed],-1 |
new_elf_exe_section: |
mov byte [ebx],1 |
mov word [ebx+1Ch],1000h |
elf_exe_section_flags: |
cmp byte [esi],19h |
jne elf_exe_section_flags_ok |
lods word [esi] |
sub ah,28 |
jbe invalid_argument |
cmp ah,1 |
je mark_elf_exe_section_flag |
cmp ah,3 |
ja invalid_argument |
xor ah,1 |
cmp ah,2 |
je mark_elf_exe_section_flag |
inc ah |
mark_elf_exe_section_flag: |
test [ebx+18h],ah |
jnz setting_already_specified |
or [ebx+18h],ah |
jmp elf_exe_section_flags |
elf_exe_section_flags_ok: |
mov eax,edi |
sub eax,[code_start] |
mov [ebx+4],eax |
pop edx |
and eax,0FFFh |
add edx,eax |
mov [ebx+8],edx |
mov [ebx+0Ch],edx |
mov eax,edx |
xor edx,edx |
not eax |
not edx |
add eax,1 |
adc edx,0 |
add eax,edi |
adc edx,0 |
mov dword [org_origin],eax |
mov dword [org_origin+4],edx |
mov [org_registers],0 |
mov [org_start],edi |
inc [number_of_sections] |
jmp instruction_assembled |
close_elf_exe_section: |
cmp [number_of_sections],0 |
jne finish_elf_exe_section |
cmp edi,[symbols_stream] |
jne first_elf_exe_section_ok |
push edi |
mov edi,[code_start] |
add edi,34h |
mov ecx,20h shr 2 |
xor eax,eax |
rep stos dword [edi] |
pop edi |
mov eax,[image_base] |
ret |
first_elf_exe_section_ok: |
inc [number_of_sections] |
finish_elf_exe_section: |
mov ebx,[number_of_sections] |
dec ebx |
shl ebx,5 |
add ebx,[code_start] |
add ebx,34h |
mov eax,edi |
sub eax,[code_start] |
sub eax,[ebx+4] |
mov edx,edi |
cmp edi,[undefined_data_end] |
jne elf_exe_section_size_ok |
mov edi,[undefined_data_start] |
elf_exe_section_size_ok: |
mov [ebx+14h],eax |
add eax,edi |
sub eax,edx |
mov [ebx+10h],eax |
mov eax,[ebx+8] |
add eax,[ebx+14h] |
add eax,0FFFh |
and eax,not 0FFFh |
ret |
elf64_exe_section: |
call close_elf64_exe_section |
push eax edx |
mov ebx,[number_of_sections] |
imul ebx,38h |
add ebx,[code_start] |
add ebx,40h |
cmp ebx,[symbols_stream] |
jb new_elf64_exe_section |
mov ebx,[symbols_stream] |
sub ebx,38h |
push edi |
mov edi,ebx |
mov ecx,38h shr 2 |
xor eax,eax |
rep stos dword [edi] |
pop edi |
or [next_pass_needed],-1 |
new_elf64_exe_section: |
mov byte [ebx],1 |
mov word [ebx+30h],1000h |
elf64_exe_section_flags: |
cmp byte [esi],19h |
jne elf64_exe_section_flags_ok |
lods word [esi] |
sub ah,28 |
jbe invalid_argument |
cmp ah,1 |
je mark_elf64_exe_section_flag |
cmp ah,3 |
ja invalid_argument |
xor ah,1 |
cmp ah,2 |
je mark_elf64_exe_section_flag |
inc ah |
mark_elf64_exe_section_flag: |
test [ebx+4],ah |
jnz setting_already_specified |
or [ebx+4],ah |
jmp elf64_exe_section_flags |
elf64_exe_section_flags_ok: |
mov ecx,edi |
sub ecx,[code_start] |
mov [ebx+8],ecx |
pop edx eax |
and ecx,0FFFh |
add eax,ecx |
adc edx,0 |
mov [ebx+10h],eax |
mov [ebx+10h+4],edx |
mov [ebx+18h],eax |
mov [ebx+18h+4],edx |
not eax |
not edx |
add eax,1 |
adc edx,0 |
add eax,edi |
adc edx,0 |
mov dword [org_origin],eax |
mov dword [org_origin+4],edx |
mov [org_registers],0 |
mov [org_start],edi |
inc [number_of_sections] |
jmp instruction_assembled |
close_elf64_exe_section: |
cmp [number_of_sections],0 |
jne finish_elf64_exe_section |
cmp edi,[symbols_stream] |
jne first_elf64_exe_section_ok |
push edi |
mov edi,[code_start] |
add edi,40h |
mov ecx,38h shr 2 |
xor eax,eax |
rep stos dword [edi] |
pop edi |
mov eax,[image_base] |
mov edx,[image_base_high] |
ret |
first_elf64_exe_section_ok: |
inc [number_of_sections] |
finish_elf64_exe_section: |
mov ebx,[number_of_sections] |
dec ebx |
imul ebx,38h |
add ebx,[code_start] |
add ebx,40h |
mov eax,edi |
sub eax,[code_start] |
sub eax,[ebx+8] |
mov edx,edi |
cmp edi,[undefined_data_end] |
jne elf64_exe_section_size_ok |
mov edi,[undefined_data_start] |
elf64_exe_section_size_ok: |
mov [ebx+28h],eax |
add eax,edi |
sub eax,edx |
mov [ebx+20h],eax |
mov eax,[ebx+10h] |
mov edx,[ebx+10h+4] |
add eax,[ebx+28h] |
adc edx,0 |
sub eax,1 |
sbb edx,0 |
shrd eax,edx,12 |
shr edx,12 |
add eax,1 |
adc edx,0 |
shld edx,eax,12 |
shl eax,12 |
ret |
close_elf_exe: |
test [format_flags],8 |
jnz close_elf64_exe |
call close_elf_exe_section |
mov edx,[code_start] |
mov eax,[number_of_sections] |
mov byte [edx+1Ch],34h |
mov [edx+2Ch],ax |
shl eax,5 |
add eax,edx |
add eax,34h |
cmp eax,[symbols_stream] |
je elf_exe_ok |
or [next_pass_needed],-1 |
elf_exe_ok: |
ret |
close_elf64_exe: |
call close_elf64_exe_section |
mov edx,[code_start] |
mov eax,[number_of_sections] |
mov byte [edx+20h],40h |
mov [edx+38h],ax |
imul eax,38h |
add eax,edx |
add eax,40h |
cmp eax,[symbols_stream] |
je elf64_exe_ok |
or [next_pass_needed],-1 |
elf64_exe_ok: |
ret |
formatter_symbols: |
db 5,'align',1Ch,0 |
db 6,'binary',18h,10h |
db 4,'code',19h,5 |
db 4,'coff',18h,40h |
db 7,'console',1Bh,3 |
db 4,'data',19h,6 |
db 11,'discardable',19h,25 |
db 3,'dll',1Bh,80h |
db 3,'elf',18h,50h |
db 5,'elf64',18h,58h |
db 10,'executable',19h,29 |
db 6,'export',1Ah,0 |
db 6,'fixups',1Ah,5 |
db 3,'gui',1Bh,2 |
db 6,'import',1Ah,1 |
db 2,'ms',17h,41h |
db 4,'ms64',17h,49h |
db 2,'mz',18h,20h |
db 6,'native',1Bh,1 |
db 11,'notpageable',19h,27 |
db 2,'pe',18h,30h |
db 4,'pe64',18h,38h |
db 8,'readable',19h,30 |
db 8,'resource',1Ah,2 |
db 9,'shareable',19h,28 |
db 3,'wdm',1Bh,81h |
db 8,'writable',19h,31 |
db 9,'writeable',19h,31 |
db 0 |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/programs/fasm/trunk/parser.inc |
---|
0,0 → 1,1022 |
; flat assembler core |
; Copyright (c) 1999-2005, 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 |
push [memory_end] |
mov esi,[memory_start] |
mov edi,[source_start] |
parser_loop: |
mov [current_line],esi |
lea eax,[edi+100h] |
cmp eax,[memory_end] |
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 |
call parse_line |
parse_next_line: |
cmp esi,[source_start] |
jb parser_loop |
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 |
pop [memory_end] |
ret |
empty_line: |
add esi,17 |
jmp parse_next_line |
parse_line: |
mov [parenthesis_stack],0 |
instruction_start: |
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 |
cmp byte [esi+ecx],1Ah |
jne get_main_instruction |
push esi ecx |
lea esi,[esi+ecx+2] |
movzx ecx,byte [esi-1] |
mov edi,data_directives |
call get_symbol |
jnc data_label |
pop ecx esi |
get_main_instruction: |
call get_instruction |
jnc parse_instruction |
mov edi,data_directives |
call get_symbol |
jnc data_instruction |
mov edi,symbols |
call get_symbol |
pop edi |
jc unknown_instruction |
stos word [edi] |
jmp parse_arguments |
data_instruction: |
movzx ebx,ah |
mov bx,[data_handlers+ebx*2] |
jmp parse_instruction |
unknown_instruction: |
sub esi,2 |
jmp parse_arguments |
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 |
jmp parse_arguments |
data_label: |
pop ecx ebx |
pop edi |
push eax esi |
mov esi,ebx |
movzx ecx,byte [esi-1] |
call identify_label |
mov byte [edi],2 |
inc edi |
stos dword [edi] |
pop esi eax |
stos byte [edi] |
push edi |
jmp data_instruction |
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 instruction_start |
identify_label: |
cmp byte [esi],'.' |
je local_label_name |
call get_label_id |
cmp eax,10h |
jb label_identified |
or ebx,ebx |
jz anonymous_label_name |
dec ebx |
mov [current_locals_prefix],ebx |
label_identified: |
ret |
anonymous_label_name: |
cmp byte [esi-1],'@' |
je anonymous_label_name_ok |
mov eax,0Fh |
anonymous_label_name_ok: |
ret |
local_label_name: |
call get_label_id |
ret |
parse_label_directive: |
cmp byte [esi],1Ah |
jne argument_parsed |
inc esi |
movzx ecx,byte [esi] |
inc esi |
mov al,2 |
stos byte [edi] |
call identify_label |
stos dword [edi] |
xor al,al |
stos byte [edi] |
jmp argument_parsed |
parse_load_directive: |
cmp byte [esi],1Ah |
jne argument_parsed |
inc esi |
movzx ecx,byte [esi] |
inc esi |
mov al,2 |
stos byte [edi] |
call get_label_id |
stos dword [edi] |
xor al,al |
stos byte [edi] |
jmp argument_parsed |
parse_prefix_instruction: |
cmp byte [esi],1Ah |
jne parse_arguments |
push edi |
inc esi |
movzx ecx,byte [esi] |
inc esi |
jmp get_main_instruction |
parse_instruction: |
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,prefix_instruction-assembler |
je parse_prefix_instruction |
cmp bx,end_directive-assembler |
je parse_prefix_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_arguments: |
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 line_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 |
mov edi,symbols |
call get_symbol |
jnc symbol_argument |
mov edi,formatter_symbols |
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 |
parse_public_directive: |
cmp byte [esi],1Ah |
jne parse_arguments |
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: |
cmp byte [esi],22h |
je parse_quoted_extrn |
cmp byte [esi],1Ah |
jne parse_arguments |
push esi |
movzx ecx,byte [esi+1] |
add esi,2 |
mov ax,'(' |
stos word [edi] |
mov eax,ecx |
stos dword [edi] |
rep movs byte [edi],[esi] |
mov ax,8600h |
stos word [edi] |
pop esi |
parse_label_operator: |
cmp byte [esi],1Ah |
jne argument_parsed |
inc esi |
movzx ecx,byte [esi] |
inc esi |
mov al,2 |
stos byte [edi] |
call get_label_id |
stos dword [edi] |
xor al,al |
stos byte [edi] |
jmp argument_parsed |
parse_from_operator: |
cmp byte [esi],22h |
jne forced_expression |
jmp argument_parsed |
parse_quoted_extrn: |
inc esi |
mov ax,'(' |
stos word [edi] |
lods dword [esi] |
mov ecx,eax |
stos dword [edi] |
rep movs byte [edi],[esi] |
xor al,al |
stos byte [edi] |
push esi edi |
mov edi,directive_operators |
call get_operator |
mov edx,esi |
pop edi esi |
cmp al,86h |
jne argument_parsed |
stos byte [edi] |
mov esi,edx |
jmp parse_label_operator |
ptr_argument: |
call parse_address |
jmp address_parsed |
check_argument: |
push esi ecx |
sub esi,2 |
mov edi,single_operand_operators |
call get_operator |
pop ecx esi |
or al,al |
jnz not_instruction |
call get_instruction |
jnc parse_instruction |
mov edi,data_directives |
call get_symbol |
jnc data_instruction |
not_instruction: |
pop edi |
sub esi,2 |
expression_argument: |
cmp byte [esi],22h |
jne not_string |
mov eax,[esi+1] |
lea ebx,[esi+5+eax] |
push ebx ecx esi edi |
mov al,'(' |
stos byte [edi] |
call convert_expression |
mov al,')' |
stos byte [edi] |
pop eax edx ecx ebx |
cmp esi,ebx |
jne expression_parsed |
mov edi,eax |
mov esi,edx |
string_argument: |
inc esi |
mov ax,'(' |
stos word [edi] |
lods dword [esi] |
mov ecx,eax |
stos dword [edi] |
shr ecx,1 |
jnc string_movsb_ok |
movs byte [edi],[esi] |
string_movsb_ok: |
shr ecx,1 |
jnc string_movsw_ok |
movs word [edi],[esi] |
string_movsw_ok: |
rep movs dword [edi],[esi] |
xor al,al |
stos byte [edi] |
jmp expression_parsed |
not_string: |
cmp byte [esi],'(' |
jne expression |
mov eax,esp |
sub eax,100h |
jc stack_overflow |
cmp eax,[stack_limit] |
jb stack_overflow |
push esi edi |
inc esi |
mov al,'{' |
stos byte [edi] |
inc [parenthesis_stack] |
jmp parse_arguments |
expression: |
mov al,'(' |
stos byte [edi] |
call convert_expression |
mov al,')' |
stos byte [edi] |
jmp expression_parsed |
forced_expression: |
mov al,'(' |
stos byte [edi] |
call convert_expression |
mov al,')' |
stos byte [edi] |
jmp argument_parsed |
address_argument: |
call parse_address |
lods byte [esi] |
cmp al,']' |
jne invalid_address |
address_parsed: |
mov al,']' |
stos byte [edi] |
jmp argument_parsed |
parse_address: |
mov al,'[' |
stos byte [edi] |
cmp word [esi],021Ah |
jne convert_address |
push esi |
add esi,4 |
lea ebx,[esi+1] |
cmp byte [esi],':' |
pop esi |
jne convert_address |
add esi,2 |
mov ecx,2 |
push ebx edi |
mov edi,symbols |
call get_symbol |
pop edi esi |
jc invalid_address |
cmp al,10h |
jne invalid_address |
mov al,ah |
and ah,11110000b |
cmp ah,60h |
jne invalid_address |
stos byte [edi] |
convert_address: |
cmp byte [esi],1Ah |
jne convert_expression |
push esi |
lods word [esi] |
movzx ecx,ah |
push edi |
mov edi,address_sizes |
call get_symbol |
pop edi |
jc no_size_prefix |
mov al,ah |
add al,70h |
stos byte [edi] |
add esp,4 |
jmp convert_expression |
no_size_prefix: |
pop esi |
jmp convert_expression |
forced_parenthesis: |
cmp byte [esi],'(' |
jne argument_parsed |
inc esi |
mov al,'{' |
jmp separator |
unallowed_character: |
mov al,0FFh |
jmp separator |
close_parenthesis: |
mov al,'}' |
separator: |
stos byte [edi] |
jmp argument_parsed |
instruction_separator: |
stos byte [edi] |
jmp instruction_start |
greater: |
cmp byte [esi],'=' |
jne separator |
inc esi |
mov al,0F2h |
jmp separator |
less: |
cmp byte [edi-1],0F6h |
je separator |
cmp byte [esi],'>' |
je not_equal |
cmp byte [esi],'=' |
jne separator |
inc esi |
mov al,0F3h |
jmp separator |
not_equal: |
inc esi |
mov al,0F1h |
jmp separator |
argument_parsed: |
cmp [parenthesis_stack],0 |
je parse_arguments |
dec [parenthesis_stack] |
add esp,8 |
jmp argument_parsed |
expression_parsed: |
cmp [parenthesis_stack],0 |
je parse_arguments |
cmp byte [esi],')' |
jne argument_parsed |
dec [parenthesis_stack] |
pop edi esi |
jmp expression |
empty_instruction: |
lods byte [esi] |
or al,al |
jz line_parsed |
cmp al,':' |
je invalid_name |
cmp al,3Bh |
je skip_preprocessed_symbol |
dec esi |
jmp parse_arguments |
skip_preprocessed_symbol: |
lods byte [esi] |
movzx eax,al |
add esi,eax |
skip_next: |
lods byte [esi] |
or al,al |
jz line_parsed |
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 |
line_parsed: |
cmp [parenthesis_stack],0 |
jne invalid_expression |
ret |
get_operator: |
cmp byte [esi],1Ah |
jne get_simple_operator |
mov edx,esi |
push ebp |
inc esi |
lods byte [esi] |
movzx ebp,al |
push edi |
mov ecx,ebp |
call lower_case |
pop edi |
check_operator: |
mov esi,converted |
movzx ecx,byte [edi] |
jecxz no_operator |
inc edi |
mov ebx,edi |
add ebx,ecx |
cmp ecx,ebp |
jne next_operator |
repe cmps byte [esi],[edi] |
je operator_found |
next_operator: |
mov edi,ebx |
inc edi |
jmp check_operator |
no_operator: |
mov esi,edx |
mov ecx,ebp |
pop ebp |
no_simple_operator: |
xor al,al |
ret |
operator_found: |
lea esi,[edx+2+ebp] |
mov ecx,ebp |
pop ebp |
mov al,[edi] |
ret |
get_simple_operator: |
mov al,[esi] |
cmp al,22h |
je no_simple_operator |
simple_operator: |
cmp byte [edi],1 |
jb no_simple_operator |
ja simple_next_operator |
cmp al,[edi+1] |
je simple_operator_found |
simple_next_operator: |
movzx ecx,byte [edi] |
lea edi,[edi+1+ecx+1] |
jmp simple_operator |
simple_operator_found: |
inc esi |
mov al,[edi+2] |
ret |
get_symbol: |
mov edx,esi |
mov ebp,ecx |
push edi |
call lower_case |
pop edi |
scan_symbols: |
mov esi,converted |
movzx eax,byte [edi] |
or al,al |
jz no_symbol |
mov ecx,ebp |
inc edi |
mov ebx,edi |
add ebx,eax |
mov ah,[esi] |
cmp ah,[edi] |
jb no_symbol |
ja next_symbol |
cmp cl,al |
jne next_symbol |
repe cmps byte [esi],[edi] |
jb no_symbol |
je symbol_ok |
next_symbol: |
mov edi,ebx |
add edi,2 |
jmp scan_symbols |
no_symbol: |
mov esi,edx |
mov ecx,ebp |
stc |
ret |
symbol_ok: |
lea esi,[edx+ebp] |
mov ax,[ebx] |
clc |
ret |
get_instruction: |
mov edx,esi |
mov ebp,ecx |
call lower_case |
mov ecx,ebp |
cmp cl,11 |
ja no_instruction |
sub cl,2 |
jc no_instruction |
movzx edi,word [instructions+ecx*2] |
add edi,instructions |
scan_instructions: |
mov esi,converted |
mov al,[edi] |
or al,al |
jz no_instruction |
mov ecx,ebp |
mov ebx,edi |
add ebx,ecx |
repe cmps byte [esi],[edi] |
jb no_instruction |
je instruction_ok |
next_instruction: |
mov edi,ebx |
add edi,3 |
jmp scan_instructions |
no_instruction: |
mov esi,edx |
mov ecx,ebp |
stc |
ret |
lower_case: |
mov edi,converted |
mov ebx,characters |
convert_case: |
lods byte [esi] |
xlat byte [ebx] |
stos byte [edi] |
loop convert_case |
case_ok: |
ret |
instruction_ok: |
lea esi,[edx+ebp] |
mov al,[ebx] |
mov bx,[ebx+1] |
clc |
ret |
get_label_id: |
cmp ecx,100h |
jae name_too_long |
cmp byte [esi],'@' |
je anonymous_label |
cmp byte [esi],'.' |
jne standard_label |
cmp byte [esi+1],'.' |
je standard_label |
cmp [current_locals_prefix],0 |
je standard_label |
push edi |
mov edi,[memory_end] |
sub edi,2 |
sub edi,ecx |
push ecx esi |
mov esi,[current_locals_prefix] |
lods byte [esi] |
movzx ecx,al |
sub edi,ecx |
cmp edi,[esp+8] |
jb out_of_memory |
mov [memory_end],edi |
mov word [edi],0 |
add edi,2 |
mov ebx,edi |
rep movs byte [edi],[esi] |
pop esi ecx |
add al,cl |
jc name_too_long |
rep movs byte [edi],[esi] |
pop edi |
push esi |
movzx ecx,al |
mov byte [ebx-1],al |
mov esi,ebx |
call get_label_id |
pop esi |
ret |
anonymous_label: |
cmp ecx,2 |
jne standard_label |
mov al,[esi+1] |
mov ebx,characters |
xlat byte [ebx] |
cmp al,'@' |
je new_anonymous |
cmp al,'b' |
je anonymous_back |
cmp al,'r' |
je anonymous_back |
cmp al,'f' |
jne standard_label |
add esi,2 |
mov eax,[anonymous_forward] |
or eax,eax |
jnz anonymous_ok |
mov eax,[current_line] |
mov [error_line],eax |
mov eax,[labels_list] |
sub eax,24 |
mov [labels_list],eax |
mov [anonymous_forward],eax |
anonymous_ok: |
xor ebx,ebx |
ret |
anonymous_back: |
add esi,2 |
mov eax,[anonymous_reverse] |
or eax,eax |
jz invalid_value |
jmp anonymous_ok |
new_anonymous: |
add esi,2 |
mov eax,[anonymous_forward] |
or eax,eax |
jnz new_anonymous_ok |
mov eax,[labels_list] |
sub eax,24 |
mov [labels_list],eax |
new_anonymous_ok: |
mov [anonymous_reverse],eax |
mov [anonymous_forward],0 |
jmp anonymous_ok |
standard_label: |
cmp byte [esi],'%' |
je get_predefined_id |
cmp byte [esi],'$' |
jne find_label |
cmp ecx,2 |
ja find_label |
inc esi |
jb get_current_offset_id |
inc esi |
cmp byte [esi-1],'$' |
je get_org_origin_id |
sub esi,ecx |
jmp find_label |
get_current_offset_id: |
xor eax,eax |
ret |
get_counter_id: |
mov eax,1 |
ret |
get_timestamp_id: |
mov eax,2 |
ret |
get_org_origin_id: |
mov eax,3 |
ret |
get_predefined_id: |
cmp ecx,2 |
ja find_label |
inc esi |
cmp cl,1 |
je get_counter_id |
lods byte [esi] |
mov ebx,characters |
xlat [ebx] |
cmp al,'t' |
je get_timestamp_id |
sub esi,2 |
find_label: |
xor ebx,ebx |
mov eax,2166136261 |
mov ebp,16777619 |
hash_label: |
xor al,[esi+ebx] |
mul ebp |
inc bl |
cmp bl,cl |
jb hash_label |
mov ebp,eax |
shl eax,8 |
and ebp,0FFh shl 24 |
xor ebp,eax |
or ebp,ebx |
mov [label_hash],ebp |
push edi esi |
push ecx |
mov ecx,32 |
mov ebx,hash_tree |
follow_tree: |
mov edx,[ebx] |
or edx,edx |
jz extend_tree |
xor eax,eax |
shl ebp,1 |
adc eax,0 |
lea ebx,[edx+eax*4] |
dec ecx |
jnz follow_tree |
mov [label_leaf],ebx |
pop edx |
mov eax,[ebx] |
or eax,eax |
jz add_label |
mov ebx,esi |
mov ebp,[label_hash] |
compare_labels: |
mov esi,ebx |
mov ecx,edx |
mov edi,[eax+4] |
repe cmps byte [esi],[edi] |
je label_found |
mov eax,[eax] |
or eax,eax |
jnz compare_labels |
jmp add_label |
label_found: |
add esp,4 |
pop edi |
mov ebx,[eax+4] |
mov eax,[eax+8] |
ret |
extend_tree: |
mov edx,[free_additional_memory] |
lea eax,[edx+8] |
cmp eax,[additional_memory_end] |
ja out_of_memory |
mov [free_additional_memory],eax |
xor eax,eax |
mov [edx],eax |
mov [edx+4],eax |
shl ebp,1 |
adc eax,0 |
mov [ebx],edx |
lea ebx,[edx+eax*4] |
dec ecx |
jnz extend_tree |
mov [label_leaf],ebx |
pop edx |
add_label: |
mov ecx,edx |
pop esi |
cmp byte [esi-2],0 |
je label_name_ok |
mov al,[esi] |
cmp al,30h |
jb name_first_char_ok |
cmp al,39h |
jbe invalid_name |
name_first_char_ok: |
cmp ecx,1 |
jne check_for_reserved_word |
cmp al,'$' |
je reserved_word |
check_for_reserved_word: |
call get_instruction |
jnc reserved_word |
mov edi,data_directives |
call get_symbol |
jnc reserved_word |
mov edi,symbols |
call get_symbol |
jnc reserved_word |
mov edi,formatter_symbols |
call get_symbol |
jnc reserved_word |
sub esi,2 |
mov edi,operators |
call get_operator |
or al,al |
jnz reserved_word |
mov edi,single_operand_operators |
call get_operator |
or al,al |
jnz reserved_word |
mov edi,directive_operators |
call get_operator |
or al,al |
jnz reserved_word |
inc esi |
movzx ecx,byte [esi] |
inc esi |
label_name_ok: |
mov edx,[free_additional_memory] |
lea eax,[edx+12] |
cmp eax,[additional_memory_end] |
ja out_of_memory |
mov [free_additional_memory],eax |
mov [edx+4],esi |
mov ebx,esi |
add esi,ecx |
mov eax,[label_leaf] |
mov edi,[eax] |
mov [edx],edi |
mov [eax],edx |
mov eax,[labels_list] |
sub eax,24 |
mov [labels_list],eax |
mov [edx+8],eax |
pop edi |
ret |
reserved_word: |
mov eax,0Fh |
pop edi |
ret |
operators: |
db 1,'+',80h |
db 1,'-',81h |
db 1,'*',90h |
db 1,'/',91h |
db 3,'mod',0A0h |
db 3,'and',0B0h |
db 2,'or',0B1h |
db 3,'xor',0B2h |
db 3,'shl',0C0h |
db 3,'shr',0C1h |
db 0 |
single_operand_operators: |
db 1,'+',0 |
db 1,'-',0D1h |
db 3,'not',0D0h |
db 3,'rva',0E0h |
db 0 |
directive_operators: |
db 2,'as',86h |
db 2,'at',80h |
db 7,'defined',88h |
db 3,'dup',81h |
db 2,'eq',0F0h |
db 6,'eqtype',0F7h |
db 4,'from',82h |
db 2,'in',0F6h |
db 2,'on',84h |
db 3,'ptr',85h |
db 4,'used',89h |
db 0 |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/programs/fasm/trunk/preproce.inc |
---|
0,0 → 1,2422 |
; flat assembler core |
; Copyright (c) 1999-2005, Tomasz Grysztar. |
; All rights reserved. |
preprocessor: |
mov edi,characters |
mov ecx,100h |
xor al,al |
make_characters_table: |
stosb |
inc al |
loop make_characters_table |
mov esi,characters+'a' |
mov edi,characters+'A' |
mov ecx,26 |
rep movsb |
mov edi,characters |
mov esi,symbol_characters+1 |
movzx ecx,byte [esi-1] |
xor eax,eax |
mark_symbol_characters: |
lodsb |
mov byte [edi+eax],0 |
loop mark_symbol_characters |
mov edi,locals_counter |
mov al,7 |
stos byte [edi] |
movzx ecx,al |
mov al,'0' |
rep stos byte [edi] |
mov edi,[memory_start] |
mov [include_paths],edi |
mov esi,include_variable |
call get_environment_variable |
xor al,al |
stosb |
mov [memory_start],edi |
mov eax,[additional_memory] |
mov [free_additional_memory],eax |
mov eax,[additional_memory_end] |
mov [labels_list],eax |
xor eax,eax |
mov [display_buffer],eax |
mov [hash_tree],eax |
mov [macro_status],al |
mov esi,[input_file] |
mov edx,esi |
call open |
jc main_file_not_found |
mov edi,[memory_start] |
call preprocess_file |
mov eax,[error_line] |
mov [current_line],eax |
cmp [macro_status],0 |
jne incomplete_macro |
mov [source_start],edi |
ret |
preprocess_file: |
push [memory_end] |
push esi |
mov al,2 |
xor edx,edx |
call lseek |
push eax |
xor al,al |
xor edx,edx |
call lseek |
pop ecx |
mov edx,[memory_end] |
dec edx |
mov byte [edx],1Ah |
sub edx,ecx |
jc out_of_memory |
mov esi,edx |
cmp edx,edi |
jbe out_of_memory |
mov [memory_end],edx |
call read |
call close |
pop edx |
xor ecx,ecx |
mov ebx,esi |
preprocess_source: |
inc ecx |
mov [current_line],edi |
mov eax,edx |
stos dword [edi] |
mov eax,ecx |
stos dword [edi] |
mov eax,esi |
sub eax,ebx |
stos dword [edi] |
xor eax,eax |
stos dword [edi] |
push ebx edx |
call convert_line |
call preprocess_line |
pop edx ebx |
next_line: |
cmp byte [esi-1],1Ah |
jne preprocess_source |
file_end: |
pop [memory_end] |
clc |
ret |
convert_line: |
push ecx |
test [macro_status],0Fh |
jz convert_line_data |
mov ax,3Bh |
stos word [edi] |
convert_line_data: |
cmp edi,[memory_end] |
jae out_of_memory |
lods byte [esi] |
cmp al,20h |
je convert_line_data |
cmp al,9 |
je convert_line_data |
mov ah,al |
mov ebx,characters |
xlat byte [ebx] |
or al,al |
jz convert_separator |
cmp ah,27h |
je convert_string |
cmp ah,22h |
je convert_string |
mov byte [edi],1Ah |
scas word [edi] |
xchg al,ah |
stos byte [edi] |
mov ebx,characters |
xor ecx,ecx |
convert_symbol: |
lods byte [esi] |
stos byte [edi] |
xlat byte [ebx] |
or al,al |
loopnzd convert_symbol |
neg ecx |
cmp ecx,255 |
ja name_too_long |
mov ebx,edi |
sub ebx,ecx |
mov byte [ebx-2],cl |
found_separator: |
dec edi |
mov ah,[esi-1] |
convert_separator: |
xchg al,ah |
cmp al,20h |
jb control_character |
je convert_line_data |
symbol_character: |
cmp al,3Bh |
je ignore_comment |
cmp al,5Ch |
je backslash_character |
stos byte [edi] |
jmp convert_line_data |
control_character: |
cmp al,1Ah |
je line_end |
cmp al,0Dh |
je cr_character |
cmp al,0Ah |
je lf_character |
cmp al,9 |
je convert_line_data |
or al,al |
jnz symbol_character |
jmp line_end |
lf_character: |
lods byte [esi] |
cmp al,0Dh |
je line_end |
dec esi |
jmp line_end |
cr_character: |
lods byte [esi] |
cmp al,0Ah |
je line_end |
dec esi |
jmp line_end |
convert_string: |
mov al,22h |
stos byte [edi] |
scas dword [edi] |
mov ebx,edi |
copy_string: |
lods byte [esi] |
stos byte [edi] |
cmp al,0Ah |
je missing_end_quote |
cmp al,0Dh |
je missing_end_quote |
or al,al |
jz missing_end_quote |
cmp al,1Ah |
je missing_end_quote |
cmp al,ah |
jne copy_string |
lods byte [esi] |
cmp al,ah |
je copy_string |
dec esi |
dec edi |
mov eax,edi |
sub eax,ebx |
mov [ebx-4],eax |
jmp convert_line_data |
backslash_character: |
mov byte [edi],0 |
lods byte [esi] |
cmp al,20h |
je concatenate_lines |
cmp al,9 |
je concatenate_lines |
cmp al,1Ah |
je unexpected_end_of_file |
cmp al,0Ah |
je concatenate_lf |
cmp al,0Dh |
je concatenate_cr |
cmp al,3Bh |
je find_concatenated_line |
mov al,1Ah |
stos byte [edi] |
mov ecx,edi |
mov ax,5C01h |
stos word [edi] |
dec esi |
group_backslashes: |
lods byte [esi] |
cmp al,5Ch |
jne backslashed_symbol |
stos byte [edi] |
inc byte [ecx] |
jmp group_backslashes |
backslashed_symbol: |
cmp al,1Ah |
je unexpected_end_of_file |
cmp al,0Ah |
je extra_characters_on_line |
cmp al,0Dh |
je extra_characters_on_line |
cmp al,20h |
je extra_characters_on_line |
cmp al,9 |
je extra_characters_on_line |
cmp al,22h |
je extra_characters_on_line |
cmp al,27h |
je extra_characters_on_line |
cmp al,3Bh |
je extra_characters_on_line |
mov ah,al |
mov ebx,characters |
xlat byte [ebx] |
or al,al |
jz backslashed_symbol_character |
mov al,ah |
convert_backslashed_symbol: |
stos byte [edi] |
xlat byte [ebx] |
or al,al |
jz found_separator |
inc byte [ecx] |
jz name_too_long |
lods byte [esi] |
jmp convert_backslashed_symbol |
backslashed_symbol_character: |
mov al,ah |
stos byte [edi] |
inc byte [ecx] |
jmp convert_line_data |
concatenate_lines: |
lods byte [esi] |
cmp al,20h |
je concatenate_lines |
cmp al,9 |
je concatenate_lines |
cmp al,1Ah |
je unexpected_end_of_file |
cmp al,0Ah |
je concatenate_lf |
cmp al,0Dh |
je concatenate_cr |
cmp al,3Bh |
jne extra_characters_on_line |
find_concatenated_line: |
lods byte [esi] |
cmp al,0Ah |
je concatenate_lf |
cmp al,0Dh |
je concatenate_cr |
or al,al |
jz concatenate_ok |
cmp al,1Ah |
jne find_concatenated_line |
jmp unexpected_end_of_file |
concatenate_lf: |
lods byte [esi] |
cmp al,0Dh |
je concatenate_ok |
dec esi |
jmp concatenate_ok |
concatenate_cr: |
lods byte [esi] |
cmp al,0Ah |
je concatenate_ok |
dec esi |
concatenate_ok: |
inc dword [esp] |
jmp convert_line_data |
ignore_comment: |
lods byte [esi] |
cmp al,0Ah |
je lf_character |
cmp al,0Dh |
je cr_character |
or al,al |
jz line_end |
cmp al,1Ah |
jne ignore_comment |
line_end: |
xor al,al |
stos byte [edi] |
pop ecx |
ret |
preprocess_line: |
mov eax,esp |
sub eax,100h |
jc stack_overflow |
cmp eax,[stack_limit] |
jb stack_overflow |
push ecx esi |
preprocess_current_line: |
mov esi,[current_line] |
add esi,16 |
cmp word [esi],3Bh |
jne line_start_ok |
add esi,2 |
line_start_ok: |
test [macro_status],0F0h |
jnz macro_preprocessing |
cmp byte [esi],1Ah |
jne not_fix_constant |
movzx edx,byte [esi+1] |
lea edx,[esi+2+edx] |
cmp word [edx],031Ah |
jne not_fix_constant |
mov ebx,characters |
movzx eax,byte [edx+2] |
xlat byte [ebx] |
ror eax,8 |
mov al,[edx+3] |
xlat byte [ebx] |
ror eax,8 |
mov al,[edx+4] |
xlat byte [ebx] |
ror eax,16 |
cmp eax,'fix' |
je define_fix_constant |
not_fix_constant: |
call process_fix_constants |
jmp initial_preprocessing_ok |
macro_preprocessing: |
call process_macro_operators |
initial_preprocessing_ok: |
mov esi,[current_line] |
add esi,16 |
mov al,[macro_status] |
test al,2 |
jnz skip_macro_block |
test al,1 |
jnz find_macro_block |
preprocess_instruction: |
mov [current_offset],esi |
lods byte [esi] |
movzx ecx,byte [esi] |
inc esi |
cmp al,1Ah |
jne not_preprocessor_symbol |
cmp cl,3 |
jb not_preprocessor_directive |
push edi |
mov edi,preprocessor_directives |
call get_symbol |
pop edi |
jc not_preprocessor_directive |
mov byte [edx-2],3Bh |
movzx ebx,ax |
add ebx,preprocessor |
jmp near ebx |
not_preprocessor_directive: |
xor ch,ch |
call get_preprocessor_symbol |
jc not_macro |
mov byte [ebx-2],3Bh |
mov [struc_name],0 |
jmp use_macro |
not_macro: |
mov [struc_name],esi |
add esi,ecx |
lods byte [esi] |
cmp al,':' |
je preprocess_label |
cmp al,1Ah |
jne not_preprocessor_symbol |
lods byte [esi] |
cmp al,3 |
jne not_symbolic_constant |
mov ebx,characters |
movzx eax,byte [esi] |
xlat byte [ebx] |
ror eax,8 |
mov al,[esi+1] |
xlat byte [ebx] |
ror eax,8 |
mov al,[esi+2] |
xlat byte [ebx] |
ror eax,16 |
cmp eax,'equ' |
je define_equ_constant |
mov al,3 |
not_symbolic_constant: |
mov ch,1 |
mov cl,al |
call get_preprocessor_symbol |
jc not_preprocessor_symbol |
push edx esi |
mov esi,[struc_name] |
mov [struc_label],esi |
sub [struc_label],2 |
mov cl,[esi-1] |
mov ch,10b |
call get_preprocessor_symbol |
jc struc_name_ok |
mov ecx,[edx+12] |
add ecx,3 |
lea ebx,[edi+ecx] |
mov ecx,edi |
sub ecx,[struc_label] |
lea esi,[edi-1] |
lea edi,[ebx-1] |
std |
rep movs byte [edi],[esi] |
cld |
mov edi,[struc_label] |
mov esi,[edx+8] |
mov ecx,[edx+12] |
add [struc_name],ecx |
add [struc_name],3 |
call move_data |
mov al,3Ah |
stos byte [edi] |
mov ax,3Bh |
stos word [edi] |
mov edi,ebx |
pop esi |
add esi,[edx+12] |
add esi,3 |
pop edx |
jmp use_macro |
struc_name_ok: |
mov edx,[struc_name] |
movzx eax,byte [edx-1] |
add edx,eax |
mov al,3Ah |
mov [edx],al |
inc al |
xchg al,[edx+1] |
dec al |
mov [edx+2],al |
pop esi edx |
jmp use_macro |
preprocess_label: |
dec esi |
sub esi,ecx |
lea ebp,[esi-2] |
mov ch,10b |
call get_preprocessor_symbol |
jnc symbolic_constant_in_label |
lea esi,[esi+ecx+1] |
jmp preprocess_instruction |
symbolic_constant_in_label: |
mov ebx,[edx+8] |
mov ecx,[edx+12] |
add ecx,ebx |
check_for_broken_label: |
cmp ebx,ecx |
je label_broken |
cmp byte [ebx],1Ah |
jne label_broken |
movzx eax,byte [ebx+1] |
lea ebx,[ebx+2+eax] |
cmp ebx,ecx |
je label_constant_ok |
cmp byte [ebx],':' |
jne label_broken |
inc ebx |
jmp check_for_broken_label |
label_broken: |
push line_preprocessed |
jmp replace_symbolic_constant |
label_constant_ok: |
mov ecx,edi |
sub ecx,esi |
mov edi,[edx+12] |
add edi,ebp |
push edi |
lea eax,[edi+ecx] |
push eax |
cmp esi,edi |
je replace_label |
jb move_rest_of_line_up |
rep movs byte [edi],[esi] |
jmp replace_label |
move_rest_of_line_up: |
lea esi,[esi+ecx-1] |
lea edi,[edi+ecx-1] |
std |
rep movs byte [edi],[esi] |
cld |
replace_label: |
mov ecx,[edx+12] |
mov edi,[esp+4] |
sub edi,ecx |
mov esi,[edx+8] |
rep movs byte [edi],[esi] |
pop edi esi |
inc esi |
jmp preprocess_instruction |
not_preprocessor_symbol: |
mov esi,[current_offset] |
call process_equ_constants |
line_preprocessed: |
pop esi ecx |
ret |
get_preprocessor_symbol: |
push ebp edi esi |
mov ebp,ecx |
shl ebp,22 |
movzx ecx,cl |
mov ebx,hash_tree |
mov edi,10 |
follow_hashes_roots: |
mov edx,[ebx] |
or edx,edx |
jz preprocessor_symbol_not_found |
xor eax,eax |
shl ebp,1 |
adc eax,0 |
lea ebx,[edx+eax*4] |
dec edi |
jnz follow_hashes_roots |
mov edi,ebx |
call calculate_hash |
mov ebp,eax |
and ebp,3FFh |
shl ebp,10 |
xor ebp,eax |
mov ebx,edi |
mov edi,22 |
follow_hashes_tree: |
mov edx,[ebx] |
or edx,edx |
jz preprocessor_symbol_not_found |
xor eax,eax |
shl ebp,1 |
adc eax,0 |
lea ebx,[edx+eax*4] |
dec edi |
jnz follow_hashes_tree |
mov al,cl |
mov edx,[ebx] |
or edx,edx |
jz preprocessor_symbol_not_found |
compare_with_preprocessor_symbol: |
mov edi,[edx+4] |
cmp edi,1 |
jbe next_equal_hash |
repe cmps byte [esi],[edi] |
je preprocessor_symbol_found |
mov cl,al |
mov esi,[esp] |
next_equal_hash: |
mov edx,[edx] |
or edx,edx |
jnz compare_with_preprocessor_symbol |
preprocessor_symbol_not_found: |
pop esi edi ebp |
stc |
ret |
preprocessor_symbol_found: |
pop ebx edi ebp |
clc |
ret |
calculate_hash: |
xor ebx,ebx |
mov eax,2166136261 |
mov ebp,16777619 |
fnv1a_hash: |
xor al,[esi+ebx] |
mul ebp |
inc bl |
cmp bl,cl |
jb fnv1a_hash |
ret |
add_preprocessor_symbol: |
push edi esi |
call calculate_hash |
mov ebp,eax |
and ebp,3FFh |
shr eax,10 |
xor ebp,eax |
shl ecx,22 |
or ebp,ecx |
mov ebx,hash_tree |
mov ecx,32 |
find_leave_for_symbol: |
mov edx,[ebx] |
or edx,edx |
jz extend_hashes_tree |
xor eax,eax |
rol ebp,1 |
adc eax,0 |
lea ebx,[edx+eax*4] |
dec ecx |
jnz find_leave_for_symbol |
mov edx,[ebx] |
or edx,edx |
jz add_symbol_entry |
shr ebp,30 |
cmp ebp,11b |
je reuse_symbol_entry |
cmp dword [edx+4],0 |
jne add_symbol_entry |
find_entry_to_reuse: |
mov edi,[edx] |
or edi,edi |
jz reuse_symbol_entry |
cmp dword [edi+4],0 |
jne reuse_symbol_entry |
mov edx,edi |
jmp find_entry_to_reuse |
add_symbol_entry: |
mov eax,edx |
mov edx,[labels_list] |
sub edx,16 |
cmp edx,[free_additional_memory] |
jb out_of_memory |
mov [labels_list],edx |
mov [edx],eax |
mov [ebx],edx |
reuse_symbol_entry: |
pop esi edi |
mov [edx+4],esi |
ret |
extend_hashes_tree: |
mov edx,[labels_list] |
sub edx,8 |
cmp edx,[free_additional_memory] |
jb out_of_memory |
mov [labels_list],edx |
xor eax,eax |
mov [edx],eax |
mov [edx+4],eax |
shl ebp,1 |
adc eax,0 |
mov [ebx],edx |
lea ebx,[edx+eax*4] |
dec ecx |
jnz extend_hashes_tree |
mov edx,[labels_list] |
sub edx,16 |
cmp edx,[free_additional_memory] |
jb out_of_memory |
mov [labels_list],edx |
mov dword [edx],0 |
mov [ebx],edx |
pop esi edi |
mov [edx+4],esi |
ret |
define_fix_constant: |
add edx,5 |
add esi,2 |
push edx esi |
mov esi,edx |
call process_fix_constants |
xchg esi,[esp] |
mov ch,11b |
jmp define_symbolic_constant |
define_equ_constant: |
add esi,3 |
push esi |
call process_equ_constants |
push esi |
mov esi,[struc_name] |
mov ch,10b |
define_symbolic_constant: |
mov byte [esi-2],3Bh |
mov cl,[esi-1] |
call add_preprocessor_symbol |
pop esi ebx |
mov ecx,edi |
dec ecx |
sub ecx,ebx |
mov [edx+8],ebx |
mov [edx+12],ecx |
jmp line_preprocessed |
define_struc: |
mov ch,1 |
jmp make_macro |
define_macro: |
xor ch,ch |
make_macro: |
lods byte [esi] |
cmp al,1Ah |
jne invalid_name |
lods byte [esi] |
mov cl,al |
call add_preprocessor_symbol |
mov eax,[current_line] |
mov [edx+12],eax |
movzx eax,byte [esi-1] |
add esi,eax |
mov [edx+8],esi |
mov al,[macro_status] |
and al,0F0h |
or al,1 |
mov [macro_status],al |
mov eax,[current_line] |
mov [error_line],eax |
xor bl,bl |
lods byte [esi] |
or al,al |
jz line_preprocessed |
cmp al,'{' |
je found_macro_block |
dec esi |
skip_macro_arguments: |
lods byte [esi] |
cmp al,1Ah |
je skip_macro_argument |
cmp al,'[' |
jne invalid_macro_arguments |
xor bl,-1 |
jz invalid_macro_arguments |
lods byte [esi] |
cmp al,1Ah |
jne invalid_macro_arguments |
skip_macro_argument: |
movzx eax,byte [esi] |
inc esi |
add esi,eax |
lods byte [esi] |
cmp al,'*' |
jne macro_argument_end |
lods byte [esi] |
macro_argument_end: |
cmp al,',' |
je skip_macro_arguments |
cmp al,']' |
jne end_macro_arguments |
lods byte [esi] |
not bl |
end_macro_arguments: |
or bl,bl |
jnz invalid_macro_arguments |
or al,al |
jz line_preprocessed |
cmp al,'{' |
je found_macro_block |
jmp invalid_macro_arguments |
find_macro_block: |
add esi,2 |
lods byte [esi] |
or al,al |
jz line_preprocessed |
cmp al,'{' |
jne unexpected_characters |
found_macro_block: |
or [macro_status],2 |
skip_macro_block: |
lods byte [esi] |
cmp al,1Ah |
je skip_macro_symbol |
cmp al,3Bh |
je skip_macro_symbol |
cmp al,22h |
je skip_macro_string |
or al,al |
jz line_preprocessed |
cmp al,'}' |
jne skip_macro_block |
mov al,[macro_status] |
and [macro_status],0F0h |
test al,8 |
jnz use_instant_macro |
cmp byte [esi],0 |
je line_preprocessed |
mov ecx,edi |
sub ecx,esi |
mov edx,esi |
lea esi,[esi+ecx-1] |
lea edi,[edi+1+16] |
mov ebx,edi |
dec edi |
std |
rep movs byte [edi],[esi] |
cld |
mov edi,edx |
xor al,al |
stos byte [edi] |
mov esi,[current_line] |
mov [current_line],edi |
mov ecx,4 |
rep movs dword [edi],[esi] |
mov edi,ebx |
jmp preprocess_current_line |
skip_macro_symbol: |
movzx eax,byte [esi] |
inc esi |
add esi,eax |
jmp skip_macro_block |
skip_macro_string: |
lods dword [esi] |
add esi,eax |
jmp skip_macro_block |
rept_directive: |
mov [base_code],0 |
jmp define_instant_macro |
irp_directive: |
mov [base_code],1 |
jmp define_instant_macro |
irps_directive: |
mov [base_code],2 |
jmp define_instant_macro |
match_directive: |
mov [base_code],10h |
define_instant_macro: |
mov al,[macro_status] |
and al,0F0h |
or al,8+1 |
mov [macro_status],al |
mov eax,[current_line] |
mov [error_line],eax |
mov [instant_macro_start],esi |
cmp [base_code],10h |
je prepare_match |
skip_parameters: |
lods byte [esi] |
or al,al |
jz instant_macro_parameters_end |
cmp al,'{' |
je instant_macro_parameters_end |
cmp al,22h |
je skip_quoted_parameter |
cmp al,1Ah |
jne skip_parameters |
lods byte [esi] |
movzx eax,al |
add esi,eax |
jmp skip_parameters |
skip_quoted_parameter: |
lods dword [esi] |
add esi,eax |
jmp skip_parameters |
instant_macro_parameters_end: |
dec esi |
mov [parameters_end],esi |
lods byte [esi] |
cmp al,'{' |
je found_macro_block |
or al,al |
jnz invalid_macro_arguments |
jmp line_preprocessed |
prepare_match: |
call skip_pattern |
mov [value_type],80h+10b |
call process_symbolic_constants |
jmp instant_macro_parameters_end |
skip_pattern: |
lods byte [esi] |
or al,al |
jz invalid_macro_arguments |
cmp al,',' |
je pattern_skipped |
cmp al,22h |
je skip_quoted_string_in_pattern |
cmp al,1Ah |
je skip_symbol_in_pattern |
cmp al,'=' |
jne skip_pattern |
mov al,[esi] |
cmp al,1Ah |
je skip_pattern |
cmp al,22h |
je skip_pattern |
inc esi |
jmp skip_pattern |
skip_symbol_in_pattern: |
lods byte [esi] |
movzx eax,al |
add esi,eax |
jmp skip_pattern |
skip_quoted_string_in_pattern: |
lods dword [esi] |
add esi,eax |
jmp skip_pattern |
pattern_skipped: |
ret |
purge_macro: |
xor ch,ch |
jmp restore_preprocessor_symbol |
purge_struc: |
mov ch,1 |
jmp restore_preprocessor_symbol |
restore_equ_constant: |
mov ch,10b |
restore_preprocessor_symbol: |
push ecx |
lods byte [esi] |
cmp al,1Ah |
jne invalid_name |
lods byte [esi] |
mov cl,al |
call get_preprocessor_symbol |
jc no_symbol_to_restore |
mov dword [edx+4],0 |
jmp symbol_restored |
no_symbol_to_restore: |
add esi,ecx |
symbol_restored: |
pop ecx |
lods byte [esi] |
cmp al,',' |
je restore_preprocessor_symbol |
or al,al |
jnz extra_characters_on_line |
jmp line_preprocessed |
process_fix_constants: |
mov [value_type],11b |
jmp process_symbolic_constants |
process_equ_constants: |
mov [value_type],10b |
process_symbolic_constants: |
mov ebp,esi |
lods byte [esi] |
cmp al,1Ah |
je check_symbol |
cmp al,22h |
je ignore_string |
cmp al,'{' |
je check_brace |
or al,al |
jnz process_symbolic_constants |
ret |
ignore_string: |
lods dword [esi] |
add esi,eax |
jmp process_symbolic_constants |
check_brace: |
test [value_type],80h |
jz process_symbolic_constants |
ret |
no_replacing: |
movzx ecx,byte [esi-1] |
add esi,ecx |
jmp process_symbolic_constants |
check_symbol: |
mov cl,[esi] |
inc esi |
mov ch,[value_type] |
call get_preprocessor_symbol |
jc no_replacing |
mov [current_section],edi |
replace_symbolic_constant: |
mov ecx,[edx+12] |
mov edx,[edx+8] |
xchg esi,edx |
call move_data |
mov esi,edx |
process_after_replaced: |
lods byte [esi] |
cmp al,1Ah |
je symbol_after_replaced |
stos byte [edi] |
cmp al,22h |
je string_after_replaced |
cmp al,'{' |
je brace_after_replaced |
or al,al |
jnz process_after_replaced |
mov ecx,edi |
sub ecx,esi |
mov edi,ebp |
call move_data |
mov esi,edi |
ret |
move_data: |
shr ecx,1 |
jnc movsb_ok |
movs byte [edi],[esi] |
movsb_ok: |
shr ecx,1 |
jnc movsw_ok |
movs word [edi],[esi] |
movsw_ok: |
rep movs dword [edi],[esi] |
ret |
string_after_replaced: |
lods dword [esi] |
stos dword [edi] |
mov ecx,eax |
call move_data |
jmp process_after_replaced |
brace_after_replaced: |
test [value_type],80h |
jz process_after_replaced |
mov edx,edi |
mov ecx,[current_section] |
sub edx,ecx |
sub ecx,esi |
rep movs byte [edi],[esi] |
mov ecx,edi |
sub ecx,esi |
mov edi,ebp |
call move_data |
lea esi,[ebp+edx] |
ret |
symbol_after_replaced: |
mov cl,[esi] |
inc esi |
mov ch,[value_type] |
call get_preprocessor_symbol |
jnc replace_symbolic_constant |
movzx ecx,byte [esi-1] |
mov al,1Ah |
mov ah,cl |
stos word [edi] |
call move_data |
jmp process_after_replaced |
process_macro_operators: |
xor dl,dl |
mov ebp,edi |
before_macro_operators: |
mov edi,esi |
lods byte [esi] |
cmp al,'`' |
je symbol_conversion |
cmp al,'#' |
je concatenation |
cmp al,1Ah |
je symbol_before_macro_operators |
cmp al,3Bh |
je no_more_macro_operators |
cmp al,22h |
je string_before_macro_operators |
xor dl,dl |
or al,al |
jnz before_macro_operators |
mov edi,esi |
ret |
no_more_macro_operators: |
mov edi,ebp |
ret |
symbol_before_macro_operators: |
mov dl,1Ah |
mov ebx,esi |
lods byte [esi] |
movzx ecx,al |
jecxz symbol_before_macro_operators_ok |
mov edi,esi |
cmp byte [esi],'\' |
je escaped_symbol |
symbol_before_macro_operators_ok: |
add esi,ecx |
jmp before_macro_operators |
string_before_macro_operators: |
mov dl,22h |
mov ebx,esi |
lods dword [esi] |
add esi,eax |
jmp before_macro_operators |
escaped_symbol: |
dec byte [edi-1] |
dec ecx |
inc esi |
cmp ecx,1 |
rep movs byte [edi],[esi] |
jne after_macro_operators |
mov al,[esi-1] |
mov ecx,ebx |
mov ebx,characters |
xlat byte [ebx] |
mov ebx,ecx |
or al,al |
jnz after_macro_operators |
sub edi,3 |
mov al,[esi-1] |
stos byte [edi] |
xor dl,dl |
jmp after_macro_operators |
symbol_conversion: |
cmp byte [esi],1Ah |
jne unexpected_characters |
lea eax,[edi+3] |
sub eax,esi |
ja shift_line_data |
mov al,22h |
mov dl,al |
stos byte [edi] |
lods word [esi] |
movzx eax,ah |
mov ecx,eax |
mov ebx,edi |
stos dword [edi] |
rep movs byte [edi],[esi] |
cmp edi,esi |
je before_macro_operators |
jmp after_macro_operators |
shift_line_data: |
lea edx,[esi+2] |
lea esi,[ebp-1] |
add ebp,eax |
lea edi,[ebp-1] |
lea ecx,[esi+1] |
sub ecx,edx |
std |
rep movs byte [edi],[esi] |
cld |
movzx eax,byte [edx-1] |
sub edi,3 |
mov dl,22h |
mov [edi-1],dl |
mov ebx,edi |
mov [edi],eax |
lea esi,[edi+4+eax] |
jmp before_macro_operators |
concatenation: |
cmp byte [esi],'#' |
je reduce_concatenation_symbol |
cmp dl,1Ah |
je symbol_concatenation |
cmp dl,22h |
je string_concatenation |
no_concatenation: |
cmp esi,edi |
je before_macro_operators |
jmp after_macro_operators |
reduce_concatenation_symbol: |
movs byte [edi],[esi] |
cmp byte [esi],'#' |
je reduce_concatenation_symbol |
jmp no_concatenation |
symbol_concatenation: |
cmp byte [esi],1Ah |
jne no_concatenation |
inc esi |
lods byte [esi] |
movzx ecx,al |
jecxz do_symbol_concatenation |
cmp byte [esi],'\' |
jne do_symbol_concatenation |
sub esi,2 |
jmp no_concatenation |
do_symbol_concatenation: |
add [ebx],al |
jc name_too_long |
rep movs byte [edi],[esi] |
jmp after_macro_operators |
string_concatenation: |
cmp byte [esi],22h |
je do_string_concatenation |
cmp byte [esi],'`' |
jne no_concatenation |
inc esi |
cmp byte [esi],1Ah |
jne unexpected_characters |
inc esi |
lods byte [esi] |
movzx ecx,al |
add [ebx],ecx |
rep movs byte [edi],[esi] |
jmp after_macro_operators |
do_string_concatenation: |
inc esi |
lods dword [esi] |
mov ecx,eax |
add [ebx],eax |
rep movs byte [edi],[esi] |
after_macro_operators: |
lods byte [esi] |
cmp al,'`' |
je symbol_conversion |
cmp al,'#' |
je concatenation |
stos byte [edi] |
cmp al,1Ah |
je symbol_after_macro_operators |
cmp al,3Bh |
je no_more_macro_operators |
cmp al,22h |
je string_after_macro_operators |
xor dl,dl |
or al,al |
jnz after_macro_operators |
ret |
symbol_after_macro_operators: |
mov dl,1Ah |
mov ebx,edi |
lods byte [esi] |
stos byte [edi] |
movzx ecx,al |
jecxz symbol_after_macro_operatorss_ok |
cmp byte [esi],'\' |
je escaped_symbol |
symbol_after_macro_operatorss_ok: |
rep movs byte [edi],[esi] |
jmp after_macro_operators |
string_after_macro_operators: |
mov dl,22h |
mov ebx,edi |
lods dword [esi] |
stos dword [edi] |
mov ecx,eax |
rep movs byte [edi],[esi] |
jmp after_macro_operators |
use_macro: |
push [free_additional_memory] |
push [macro_symbols] |
mov [macro_symbols],0 |
push [counter_limit] |
push dword [edx+4] |
mov dword [edx+4],1 |
push edx |
mov ebx,esi |
mov esi,[edx+8] |
mov eax,[edx+12] |
mov [macro_line],eax |
mov [counter_limit],0 |
process_macro_arguments: |
mov al,[esi] |
or al,al |
jz arguments_end |
cmp al,'{' |
je arguments_end |
inc esi |
cmp al,'[' |
jne get_macro_arguments |
mov ebp,esi |
inc esi |
inc [counter_limit] |
get_macro_arguments: |
call get_macro_argument |
lods byte [esi] |
cmp al,',' |
je next_argument |
cmp al,']' |
je next_arguments_group |
dec esi |
jmp arguments_end |
next_argument: |
cmp byte [ebx],',' |
jne process_macro_arguments |
inc ebx |
jmp process_macro_arguments |
next_arguments_group: |
cmp byte [ebx],',' |
jne arguments_end |
inc ebx |
inc [counter_limit] |
mov esi,ebp |
jmp process_macro_arguments |
get_macro_argument: |
lods byte [esi] |
movzx ecx,al |
mov eax,[counter_limit] |
call add_macro_symbol |
add esi,ecx |
xchg esi,ebx |
mov [edx+12],esi |
cmp byte [esi],'<' |
jne simple_argument |
inc esi |
mov [edx+12],esi |
mov ecx,1 |
enclosed_argument: |
lods byte [esi] |
or al,al |
jz invalid_macro_arguments |
cmp al,1Ah |
je enclosed_symbol |
cmp al,22h |
je enclosed_string |
cmp al,'>' |
je enclosed_argument_end |
cmp al,'<' |
jne enclosed_argument |
inc ecx |
jmp enclosed_argument |
enclosed_symbol: |
movzx eax,byte [esi] |
inc esi |
add esi,eax |
jmp enclosed_argument |
enclosed_string: |
lods dword [esi] |
add esi,eax |
jmp enclosed_argument |
enclosed_argument_end: |
loop enclosed_argument |
mov al,[esi] |
or al,al |
jz enclosed_argument_ok |
cmp al,',' |
jne invalid_macro_arguments |
enclosed_argument_ok: |
mov eax,esi |
sub eax,[edx+12] |
dec eax |
or eax,80000000h |
mov [edx+8],eax |
jmp argument_value_ok |
simple_argument: |
lods byte [esi] |
or al,al |
jz argument_value_end |
cmp al,',' |
je argument_value_end |
cmp al,22h |
je argument_string |
cmp al,1Ah |
jne simple_argument |
movzx eax,byte [esi] |
inc esi |
add esi,eax |
jmp simple_argument |
argument_string: |
lods dword [esi] |
add esi,eax |
jmp simple_argument |
argument_value_end: |
dec esi |
mov eax,esi |
sub eax,[edx+12] |
mov [edx+8],eax |
argument_value_ok: |
xchg esi,ebx |
cmp byte [esi],'*' |
jne macro_argument_ok |
cmp dword [edx+8],0 |
je invalid_macro_arguments |
inc esi |
macro_argument_ok: |
ret |
arguments_end: |
cmp byte [ebx],0 |
jne invalid_macro_arguments |
mov eax,[esp+4] |
dec eax |
call process_macro |
pop edx |
pop dword [edx+4] |
pop [counter_limit] |
pop [macro_symbols] |
pop [free_additional_memory] |
jmp line_preprocessed |
use_instant_macro: |
push edi [current_line] esi |
mov eax,[error_line] |
mov [current_line],eax |
mov [macro_line],eax |
mov esi,[instant_macro_start] |
cmp [base_code],10h |
jae do_match |
cmp [base_code],0 |
jne do_irp |
call get_number |
jc invalid_value |
or ebp,ebp |
jnz invalid_value |
cmp dword [edi+4],0 |
jne value_out_of_range |
mov eax,[edi] |
or eax,eax |
jz instant_macro_done |
cmp eax,80000000h |
jae value_out_of_range |
push [free_additional_memory] |
push [macro_symbols] |
mov [macro_symbols],0 |
push [counter_limit] |
mov [struc_name],0 |
mov [counter_limit],eax |
lods byte [esi] |
or al,al |
jz rept_counters_ok |
cmp al,'{' |
je rept_counters_ok |
cmp al,1Ah |
jne invalid_macro_arguments |
add_rept_counter: |
lods byte [esi] |
movzx ecx,al |
xor eax,eax |
call add_macro_symbol |
add esi,ecx |
xor eax,eax |
mov dword [edx+12],eax |
inc eax |
mov dword [edx+8],eax |
lods byte [esi] |
cmp al,':' |
jne rept_counter_added |
push edx |
call get_number |
jc invalid_value |
or ebp,ebp |
jnz invalid_value |
cmp dword [edi+4],0 |
jne value_out_of_range |
mov eax,[edi] |
mov edx,eax |
add edx,[counter_limit] |
jc value_out_of_range |
pop edx |
mov dword [edx+8],eax |
lods byte [esi] |
rept_counter_added: |
cmp al,',' |
jne rept_counters_ok |
lods byte [esi] |
cmp al,1Ah |
jne invalid_macro_arguments |
jmp add_rept_counter |
rept_counters_ok: |
dec esi |
instant_macro_parameters_ok: |
xor eax,eax |
call process_macro |
pop [counter_limit] |
pop [macro_symbols] |
pop [free_additional_memory] |
instant_macro_done: |
pop ebx esi edx |
cmp byte [ebx],0 |
je line_preprocessed |
mov [current_line],edi |
mov ecx,4 |
rep movs dword [edi],[esi] |
test [macro_status],0Fh |
jz instant_macro_attached_line |
mov ax,3Bh |
stos word [edi] |
instant_macro_attached_line: |
mov esi,ebx |
sub edx,ebx |
mov ecx,edx |
call move_data |
jmp preprocess_current_line |
do_irp: |
cmp byte [esi],1Ah |
jne invalid_macro_arguments |
movzx eax,byte [esi+1] |
lea esi,[esi+2+eax] |
lods byte [esi] |
cmp [base_code],1 |
ja irps_name_ok |
cmp al,'*' |
jne irp_name_ok |
lods byte [esi] |
irp_name_ok: |
cmp al,',' |
jne invalid_macro_arguments |
jmp irp_parameters_start |
irps_name_ok: |
cmp al,',' |
jne invalid_macro_arguments |
mov al,[esi] |
or al,al |
jz instant_macro_done |
cmp al,'{' |
je instant_macro_done |
irp_parameters_start: |
xor eax,eax |
push [free_additional_memory] |
push [macro_symbols] |
mov [macro_symbols],eax |
push [counter_limit] |
mov [counter_limit],eax |
mov [struc_name],eax |
mov ebx,esi |
cmp [base_code],1 |
ja get_irps_parameter |
mov edx,[parameters_end] |
mov al,[edx] |
push eax |
mov byte [edx],0 |
get_irp_parameter: |
inc [counter_limit] |
mov esi,[instant_macro_start] |
inc esi |
call get_macro_argument |
cmp byte [ebx],',' |
jne irp_parameters_end |
inc ebx |
jmp get_irp_parameter |
irp_parameters_end: |
mov esi,ebx |
pop eax |
mov [esi],al |
jmp instant_macro_parameters_ok |
get_irps_parameter: |
mov esi,[instant_macro_start] |
inc esi |
lods byte [esi] |
movzx ecx,al |
inc [counter_limit] |
mov eax,[counter_limit] |
call add_macro_symbol |
mov [edx+12],ebx |
cmp byte [ebx],1Ah |
je irps_symbol |
cmp byte [ebx],22h |
je irps_quoted_string |
mov eax,1 |
jmp irps_parameter_ok |
irps_quoted_string: |
mov eax,[ebx+1] |
add eax,1+4 |
irps_symbol: |
movzx eax,byte [ebx+1] |
add eax,1+1 |
irps_parameter_ok: |
mov [edx+8],eax |
add ebx,eax |
cmp byte [ebx],0 |
je irps_parameters_end |
cmp byte [ebx],'{' |
jne get_irps_parameter |
irps_parameters_end: |
mov esi,ebx |
jmp instant_macro_parameters_ok |
do_match: |
mov ebx,esi |
call skip_pattern |
call exact_match |
mov edx,edi |
mov al,[ebx] |
cmp al,1Ah |
je free_match |
cmp al,',' |
jne instant_macro_done |
cmp esi,[parameters_end] |
je matched_pattern |
jmp instant_macro_done |
free_match: |
add edx,12 |
cmp edx,[memory_end] |
ja out_of_memory |
mov [edx-12],ebx |
mov [edx-8],esi |
call skip_match_element |
jc try_different_matching |
mov [edx-4],esi |
movzx eax,byte [ebx+1] |
lea ebx,[ebx+2+eax] |
cmp byte [ebx],1Ah |
je free_match |
find_exact_match: |
call exact_match |
cmp esi,[parameters_end] |
je end_matching |
cmp byte [ebx],1Ah |
je free_match |
mov ebx,[edx-12] |
movzx eax,byte [ebx+1] |
lea ebx,[ebx+2+eax] |
mov esi,[edx-4] |
jmp match_more_elements |
try_different_matching: |
sub edx,12 |
cmp edx,edi |
je instant_macro_done |
mov ebx,[edx-12] |
movzx eax,byte [ebx+1] |
lea ebx,[ebx+2+eax] |
cmp byte [ebx],1Ah |
je try_different_matching |
mov esi,[edx-4] |
match_more_elements: |
call skip_match_element |
jc try_different_matching |
mov [edx-4],esi |
jmp find_exact_match |
skip_match_element: |
cmp esi,[parameters_end] |
je cannot_match |
mov al,[esi] |
cmp al,1Ah |
je skip_match_symbol |
cmp al,22h |
je skip_match_quoted_string |
add esi,1 |
ret |
skip_match_quoted_string: |
mov eax,[esi+1] |
add esi,5 |
jmp skip_match_ok |
skip_match_symbol: |
movzx eax,byte [esi+1] |
add esi,2 |
skip_match_ok: |
add esi,eax |
ret |
cannot_match: |
stc |
ret |
exact_match: |
cmp esi,[parameters_end] |
je exact_match_complete |
mov ah,[esi] |
mov al,[ebx] |
cmp al,',' |
je exact_match_complete |
cmp al,1Ah |
je exact_match_complete |
cmp al,'=' |
je match_verbatim |
call match_elements |
je exact_match |
exact_match_complete: |
ret |
match_verbatim: |
inc ebx |
call match_elements |
je exact_match |
dec ebx |
ret |
match_elements: |
mov al,[ebx] |
cmp al,1Ah |
je match_symbols |
cmp al,22h |
je match_quoted_strings |
cmp al,ah |
je symbol_characters_matched |
ret |
symbol_characters_matched: |
lea ebx,[ebx+1] |
lea esi,[esi+1] |
ret |
match_quoted_strings: |
mov ecx,[ebx+1] |
add ecx,5 |
jmp compare_elements |
match_symbols: |
movzx ecx,byte [ebx+1] |
add ecx,2 |
compare_elements: |
mov eax,esi |
mov ebp,edi |
mov edi,ebx |
repe cmps byte [esi],[edi] |
jne elements_mismatch |
mov ebx,edi |
mov edi,ebp |
ret |
elements_mismatch: |
mov esi,eax |
mov edi,ebp |
ret |
end_matching: |
cmp byte [ebx],',' |
jne instant_macro_done |
matched_pattern: |
xor eax,eax |
push [free_additional_memory] |
push [macro_symbols] |
mov [macro_symbols],eax |
push [counter_limit] |
mov [counter_limit],eax |
mov [struc_name],eax |
push esi edi edx |
add_matched_symbol: |
cmp edi,[esp] |
je matched_symbols_ok |
mov esi,[edi] |
inc esi |
lods byte [esi] |
movzx ecx,al |
xor eax,eax |
call add_macro_symbol |
mov eax,[edi+4] |
mov dword [edx+12],eax |
mov ecx,[edi+8] |
sub ecx,eax |
mov dword [edx+8],ecx |
add edi,12 |
jmp add_matched_symbol |
matched_symbols_ok: |
pop edx edi esi |
jmp instant_macro_parameters_ok |
process_macro: |
push dword [macro_status] |
or [macro_status],10h |
push [counter] |
push [macro_block] |
push [macro_block_line] |
push [macro_block_line_number] |
push [struc_label] |
push [struc_name] |
push eax |
push [current_line] |
lods byte [esi] |
cmp al,'{' |
je macro_instructions_start |
or al,al |
jnz unexpected_characters |
find_macro_instructions: |
mov [macro_line],esi |
add esi,16+2 |
lods byte [esi] |
or al,al |
jz find_macro_instructions |
cmp al,'{' |
je macro_instructions_start |
cmp al,3Bh |
jne unexpected_characters |
call skip_foreign_symbol |
jmp find_macro_instructions |
macro_instructions_start: |
mov ecx,80000000h |
mov [macro_block],esi |
mov eax,[macro_line] |
mov [macro_block_line],eax |
mov [macro_block_line_number],ecx |
xor eax,eax |
mov [counter],eax |
cmp [counter_limit],eax |
je process_macro_line |
inc [counter] |
process_macro_line: |
mov [current_line],edi |
cmp edi,[memory_end] |
jae out_of_memory |
mov eax,[esp+4] |
or eax,eax |
jz instant_macro_line_header |
stos dword [edi] |
mov eax,ecx |
stos dword [edi] |
mov eax,[esp] |
stos dword [edi] |
mov eax,[macro_line] |
stos dword [edi] |
jmp macro_line_header_ok |
instant_macro_line_header: |
mov edx,[macro_line] |
mov eax,[edx] |
stos dword [edi] |
mov eax,[edx+4] |
stos dword [edi] |
mov eax,[edx+8] |
stos dword [edi] |
mov eax,[edx+12] |
stos dword [edi] |
macro_line_header_ok: |
or [macro_status],20h |
push ebx ecx |
test [macro_status],0Fh |
jz process_macro_line_element |
mov ax,3Bh |
stos word [edi] |
process_macro_line_element: |
lods byte [esi] |
cmp al,'}' |
je macro_line_processed |
or al,al |
jz macro_line_processed |
cmp al,1Ah |
je process_macro_symbol |
cmp al,3Bh |
je macro_foreign_line |
and [macro_status],not 20h |
stos byte [edi] |
cmp al,22h |
jne process_macro_line_element |
copy_macro_string: |
mov ecx,[esi] |
add ecx,4 |
rep movs byte [edi],[esi] |
jmp process_macro_line_element |
process_macro_symbol: |
push esi edi |
test [macro_status],20h |
jz not_macro_directive |
movzx ecx,byte [esi] |
inc esi |
mov edi,macro_directives |
call get_symbol |
jnc process_macro_directive |
dec esi |
jmp not_macro_directive |
process_macro_directive: |
movzx edx,ax |
add edx,preprocessor |
pop edi eax |
mov byte [edi],0 |
inc edi |
pop ecx ebx |
jmp near edx |
not_macro_directive: |
and [macro_status],not 20h |
movzx ecx,byte [esi] |
inc esi |
mov eax,[counter] |
call get_macro_symbol |
jnc group_macro_symbol |
xor eax,eax |
cmp [counter],eax |
je multiple_macro_symbol_values |
call get_macro_symbol |
jc not_macro_symbol |
replace_macro_symbol: |
pop edi eax |
mov ecx,[edx+8] |
and ecx,not 80000000h |
mov edx,[edx+12] |
or edx,edx |
jz replace_macro_counter |
xchg esi,edx |
rep movs byte [edi],[esi] |
mov esi,edx |
jmp process_macro_line_element |
group_macro_symbol: |
xor eax,eax |
cmp [counter],eax |
je replace_macro_symbol |
push esi edx |
sub esi,ecx |
call get_macro_symbol |
mov ebx,edx |
pop edx esi |
jc replace_macro_symbol |
cmp edx,ebx |
ja replace_macro_symbol |
mov edx,ebx |
jmp replace_macro_symbol |
multiple_macro_symbol_values: |
inc eax |
push eax |
call get_macro_symbol |
pop eax |
jc not_macro_symbol |
pop edi |
push ecx |
mov ecx,[edx+8] |
mov edx,[edx+12] |
xchg esi,edx |
btr ecx,31 |
jc enclose_macro_symbol_value |
rep movs byte [edi],[esi] |
jmp macro_symbol_value_ok |
enclose_macro_symbol_value: |
mov byte [edi],'<' |
inc edi |
rep movs byte [edi],[esi] |
mov byte [edi],'>' |
inc edi |
macro_symbol_value_ok: |
cmp eax,[counter_limit] |
je multiple_macro_symbol_values_ok |
mov byte [edi],',' |
inc edi |
mov esi,edx |
pop ecx |
push edi |
sub esi,ecx |
jmp multiple_macro_symbol_values |
multiple_macro_symbol_values_ok: |
pop ecx eax |
mov esi,edx |
jmp process_macro_line_element |
replace_macro_counter: |
mov eax,[counter] |
and eax,not 80000000h |
jz group_macro_counter |
add ecx,eax |
dec ecx |
call store_number_symbol |
jmp process_macro_line_element |
group_macro_counter: |
mov edx,ecx |
xor ecx,ecx |
multiple_macro_counter_values: |
push ecx edx |
add ecx,edx |
call store_number_symbol |
pop edx ecx |
inc ecx |
cmp ecx,[counter_limit] |
je process_macro_line_element |
mov byte [edi],',' |
inc edi |
jmp multiple_macro_counter_values |
store_number_symbol: |
mov ax,1Ah |
stos word [edi] |
push edi |
mov eax,ecx |
mov ecx,1000000000 |
xor edx,edx |
xor bl,bl |
store_number_digits: |
div ecx |
push edx |
or bl,bl |
jnz store_number_digit |
cmp ecx,1 |
je store_number_digit |
or al,al |
jz number_digit_ok |
not bl |
store_number_digit: |
add al,30h |
stos byte [edi] |
number_digit_ok: |
mov eax,ecx |
xor edx,edx |
mov ecx,10 |
div ecx |
mov ecx,eax |
pop eax |
or ecx,ecx |
jnz store_number_digits |
pop ebx |
mov eax,edi |
sub eax,ebx |
mov [ebx-1],al |
ret |
not_macro_symbol: |
pop edi esi |
mov al,1Ah |
stos byte [edi] |
mov al,[esi] |
inc esi |
stos byte [edi] |
cmp byte [esi],'.' |
jne copy_raw_symbol |
mov ebx,[esp+8+8] |
or ebx,ebx |
jz copy_raw_symbol |
cmp al,1 |
je copy_struc_name |
xchg esi,ebx |
movzx ecx,byte [esi-1] |
add [edi-1],cl |
jc name_too_long |
rep movs byte [edi],[esi] |
xchg esi,ebx |
copy_raw_symbol: |
movzx ecx,al |
rep movs byte [edi],[esi] |
jmp process_macro_line_element |
copy_struc_name: |
inc esi |
xchg esi,ebx |
movzx ecx,byte [esi-1] |
mov [edi-1],cl |
rep movs byte [edi],[esi] |
xchg esi,ebx |
mov eax,[esp+8+12] |
cmp byte [eax],3Bh |
je process_macro_line_element |
cmp byte [eax],1Ah |
jne disable_replaced_struc_name |
mov byte [eax],3Bh |
jmp process_macro_line_element |
disable_replaced_struc_name: |
mov ebx,[esp+8+8] |
push esi edi |
lea edi,[ebx-3] |
lea esi,[edi-2] |
lea ecx,[esi+1] |
sub ecx,eax |
std |
rep movs byte [edi],[esi] |
cld |
mov word [eax],3Bh |
pop edi esi |
jmp process_macro_line_element |
skip_foreign_symbol: |
lods byte [esi] |
movzx eax,al |
add esi,eax |
skip_foreign_line: |
lods byte [esi] |
cmp al,1Ah |
je skip_foreign_symbol |
cmp al,3Bh |
je skip_foreign_symbol |
cmp al,22h |
je skip_foreign_string |
or al,al |
jnz skip_foreign_line |
ret |
skip_foreign_string: |
lods dword [esi] |
add esi,eax |
jmp skip_foreign_line |
macro_foreign_line: |
call skip_foreign_symbol |
macro_line_processed: |
mov byte [edi],0 |
inc edi |
push eax |
call preprocess_line |
pop eax |
pop ecx ebx |
cmp al,'}' |
je macro_block_processed |
process_next_line: |
inc ecx |
mov [macro_line],esi |
add esi,16+2 |
jmp process_macro_line |
macro_block_processed: |
call close_macro_block |
jc process_macro_line |
pop [current_line] |
add esp,12 |
pop [macro_block_line_number] |
pop [macro_block_line] |
pop [macro_block] |
pop [counter] |
pop eax |
and al,0F0h |
and [macro_status],0Fh |
or [macro_status],al |
ret |
local_symbols: |
lods byte [esi] |
cmp al,1Ah |
jne invalid_argument |
mov byte [edi-1],3Bh |
xor al,al |
stos byte [edi] |
make_local_symbol: |
push ecx |
lods byte [esi] |
movzx ecx,al |
mov eax,[counter] |
call add_macro_symbol |
mov [edx+12],edi |
movzx eax,[locals_counter] |
add eax,ecx |
inc eax |
cmp eax,100h |
jae name_too_long |
lea ebp,[edi+2+eax] |
cmp ebp,[memory_end] |
jae out_of_memory |
mov ah,al |
mov al,1Ah |
stos word [edi] |
rep movs byte [edi],[esi] |
mov al,'?' |
stos byte [edi] |
push esi |
mov esi,locals_counter+1 |
movzx ecx,[locals_counter] |
rep movs byte [edi],[esi] |
pop esi |
mov eax,edi |
sub eax,[edx+12] |
mov [edx+8],eax |
xor al,al |
stos byte [edi] |
mov eax,locals_counter |
movzx ecx,byte [eax] |
counter_loop: |
inc byte [eax+ecx] |
cmp byte [eax+ecx],':' |
jb counter_ok |
jne letter_digit |
mov byte [eax+ecx],'A' |
jmp counter_ok |
letter_digit: |
cmp byte [eax+ecx],'F' |
jbe counter_ok |
mov byte [eax+ecx],'0' |
loop counter_loop |
counter_ok: |
pop ecx |
lods byte [esi] |
cmp al,'}' |
je macro_block_processed |
or al,al |
jz process_next_line |
cmp al,',' |
jne extra_characters_on_line |
dec edi |
lods byte [esi] |
cmp al,1Ah |
je make_local_symbol |
jmp invalid_argument |
common_block: |
call close_macro_block |
jc process_macro_line |
mov [counter],0 |
jmp new_macro_block |
forward_block: |
cmp [counter_limit],0 |
je common_block |
call close_macro_block |
jc process_macro_line |
mov [counter],1 |
jmp new_macro_block |
reverse_block: |
cmp [counter_limit],0 |
je common_block |
call close_macro_block |
jc process_macro_line |
mov eax,[counter_limit] |
or eax,80000000h |
mov [counter],eax |
new_macro_block: |
mov [macro_block],esi |
mov eax,[macro_line] |
mov [macro_block_line],eax |
mov [macro_block_line_number],ecx |
jmp process_macro_line |
close_macro_block: |
cmp [counter],0 |
je block_closed |
jl reverse_counter |
mov eax,[counter] |
cmp eax,[counter_limit] |
je block_closed |
inc [counter] |
jmp continue_block |
reverse_counter: |
mov eax,[counter] |
dec eax |
cmp eax,80000000h |
je block_closed |
mov [counter],eax |
continue_block: |
mov esi,[macro_block] |
mov eax,[macro_block_line] |
mov [macro_line],eax |
mov ecx,[macro_block_line_number] |
stc |
ret |
block_closed: |
clc |
ret |
get_macro_symbol: |
push ecx |
call find_macro_symbol_leaf |
jc macro_symbol_not_found |
mov edx,[ebx] |
mov ebx,esi |
try_macro_symbol: |
or edx,edx |
jz macro_symbol_not_found |
mov ecx,[esp] |
mov edi,[edx+4] |
repe cmps byte [esi],[edi] |
je macro_symbol_found |
mov esi,ebx |
mov edx,[edx] |
jmp try_macro_symbol |
macro_symbol_found: |
pop ecx |
clc |
ret |
macro_symbol_not_found: |
pop ecx |
stc |
ret |
find_macro_symbol_leaf: |
shl eax,8 |
mov al,cl |
mov ebp,eax |
mov ebx,macro_symbols |
follow_macro_symbols_tree: |
mov edx,[ebx] |
or edx,edx |
jz no_such_macro_symbol |
xor eax,eax |
shr ebp,1 |
adc eax,0 |
lea ebx,[edx+eax*4] |
or ebp,ebp |
jnz follow_macro_symbols_tree |
add ebx,8 |
clc |
ret |
no_such_macro_symbol: |
stc |
ret |
add_macro_symbol: |
push ebx ebp |
call find_macro_symbol_leaf |
jc extend_macro_symbol_tree |
mov eax,[ebx] |
make_macro_symbol: |
mov edx,[free_additional_memory] |
add edx,16 |
cmp edx,[labels_list] |
ja out_of_memory |
xchg edx,[free_additional_memory] |
mov [ebx],edx |
mov [edx],eax |
mov [edx+4],esi |
pop ebp ebx |
ret |
extend_macro_symbol_tree: |
mov edx,[free_additional_memory] |
add edx,16 |
cmp edx,[labels_list] |
ja out_of_memory |
xchg edx,[free_additional_memory] |
xor eax,eax |
mov [edx],eax |
mov [edx+4],eax |
mov [edx+8],eax |
mov [edx+12],eax |
shr ebp,1 |
adc eax,0 |
mov [ebx],edx |
lea ebx,[edx+eax*4] |
or ebp,ebp |
jnz extend_macro_symbol_tree |
add ebx,8 |
xor eax,eax |
jmp make_macro_symbol |
include_file: |
lods byte [esi] |
cmp al,22h |
jne invalid_argument |
lods dword [esi] |
cmp byte [esi+eax],0 |
jne extra_characters_on_line |
push esi |
push edi |
mov ebx,[current_line] |
find_current_file_path: |
mov esi,[ebx] |
test byte [ebx+7],80h |
jz copy_current_file_path |
mov ebx,[ebx+8] |
jmp find_current_file_path |
copy_current_file_path: |
lods byte [esi] |
stos byte [edi] |
or al,al |
jnz copy_current_file_path |
cut_current_file_name: |
cmp edi,[esp] |
je current_file_path_ok |
cmp byte [edi-1],'\' |
je current_file_path_ok |
cmp byte [edi-1],'/' |
je current_file_path_ok |
dec edi |
jmp cut_current_file_name |
current_file_path_ok: |
mov esi,[esp+4] |
call preprocess_path |
pop edx |
mov esi,edx |
call open |
jnc include_path_ok |
mov ebp,[include_paths] |
try_include_directories: |
mov edi,esi |
mov esi,ebp |
cmp byte [esi],0 |
je try_in_current_directory |
push ebp |
push edi |
copy_include_directory: |
lods byte [esi] |
cmp al,';' |
je include_directory_ok |
stos byte [edi] |
or al,al |
jnz copy_include_directory |
dec esi |
dec edi |
include_directory_ok: |
cmp byte [edi-1],'/' |
je path_separator_ok |
cmp byte [edi-1],'\' |
je path_separator_ok |
mov al,'/' |
stos byte [edi] |
path_separator_ok: |
mov [esp+4],esi |
mov esi,[esp+8] |
call preprocess_path |
pop edx |
mov esi,edx |
call open |
pop ebp |
jnc include_path_ok |
jmp try_include_directories |
mov edi,esi |
try_in_current_directory: |
mov esi,[esp] |
push edi |
call preprocess_path |
pop edx |
mov esi,edx |
call open |
jc file_not_found |
include_path_ok: |
mov edi,[esp] |
copy_preprocessed_path: |
lods byte [esi] |
stos byte [edi] |
or al,al |
jnz copy_preprocessed_path |
pop esi |
lea ecx,[edi-1] |
sub ecx,esi |
mov [esi-4],ecx |
push dword [macro_status] |
and [macro_status],0Fh |
call preprocess_file |
pop eax |
mov [macro_status],al |
jmp line_preprocessed |
preprocess_path: |
lods byte [esi] |
cmp al,'%' |
je environment_variable |
stos byte [edi] |
or al,al |
jnz preprocess_path |
cmp edi,[memory_end] |
ja out_of_memory |
ret |
environment_variable: |
mov ebx,esi |
find_variable_end: |
lods byte [esi] |
or al,al |
jz not_environment_variable |
cmp al,'%' |
jne find_variable_end |
mov byte [esi-1],0 |
push esi |
mov esi,ebx |
call get_environment_variable |
pop esi |
mov byte [esi-1],'%' |
jmp preprocess_path |
not_environment_variable: |
mov al,'%' |
stos byte [edi] |
mov esi,ebx |
jmp preprocess_path |
include_variable db 'INCLUDE',0 |
symbol_characters db 27 |
db 9,0Ah,0Dh,1Ah,20h,'+-/*=<>()[]{}:,|&~#`;\' |
preprocessor_directives: |
db 7,'include' |
dw include_file-preprocessor |
db 3,'irp' |
dw irp_directive-preprocessor |
db 4,'irps' |
dw irps_directive-preprocessor |
db 5,'macro' |
dw define_macro-preprocessor |
db 5,'match' |
dw match_directive-preprocessor |
db 5,'purge' |
dw purge_macro-preprocessor |
db 4,'rept' |
dw rept_directive-preprocessor |
db 7,'restore' |
dw restore_equ_constant-preprocessor |
db 7,'restruc' |
dw purge_struc-preprocessor |
db 5,'struc' |
dw define_struc-preprocessor |
db 0 |
macro_directives: |
db 6,'common' |
dw common_block-preprocessor |
db 7,'forward' |
dw forward_block-preprocessor |
db 5,'local' |
dw local_symbols-preprocessor |
db 7,'reverse' |
dw reverse_block-preprocessor |
db 0 |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/programs/fasm/trunk/struct.inc |
---|
0,0 → 1,180 |
; Macroinstructions for defining data structures |
macro struct name |
{ fields@struct equ name |
match child parent, name \{ fields@struct equ child,fields@\#parent \} |
sub@struct equ |
struc db [val] \{ \common fields@struct equ fields@struct,.,db,<val> \} |
struc dw [val] \{ \common fields@struct equ fields@struct,.,dw,<val> \} |
struc du [val] \{ \common fields@struct equ fields@struct,.,du,<val> \} |
struc dd [val] \{ \common fields@struct equ fields@struct,.,dd,<val> \} |
struc dp [val] \{ \common fields@struct equ fields@struct,.,dp,<val> \} |
struc dq [val] \{ \common fields@struct equ fields@struct,.,dq,<val> \} |
struc dt [val] \{ \common fields@struct equ fields@struct,.,dt,<val> \} |
struc rb count \{ fields@struct equ fields@struct,.,db,count dup (?) \} |
struc rw count \{ fields@struct equ fields@struct,.,dw,count dup (?) \} |
struc rd count \{ fields@struct equ fields@struct,.,dd,count dup (?) \} |
struc rp count \{ fields@struct equ fields@struct,.,dp,count dup (?) \} |
struc rq count \{ fields@struct equ fields@struct,.,dq,count dup (?) \} |
struc rt count \{ fields@struct equ fields@struct,.,dt,count dup (?) \} |
macro db [val] \{ \common \local anonymous |
fields@struct equ fields@struct,anonymous,db,<val> \} |
macro dw [val] \{ \common \local anonymous |
fields@struct equ fields@struct,anonymous,dw,<val> \} |
macro du [val] \{ \common \local anonymous |
fields@struct equ fields@struct,anonymous,du,<val> \} |
macro dd [val] \{ \common \local anonymous |
fields@struct equ fields@struct,anonymous,dd,<val> \} |
macro dp [val] \{ \common \local anonymous |
fields@struct equ fields@struct,anonymous,dp,<val> \} |
macro dq [val] \{ \common \local anonymous |
fields@struct equ fields@struct,anonymous,dq,<val> \} |
macro dt [val] \{ \common \local anonymous |
fields@struct equ fields@struct,anonymous,dt,<val> \} |
macro rb count \{ \local anonymous |
fields@struct equ fields@struct,anonymous,db,count dup (?) \} |
macro rw count \{ \local anonymous |
fields@struct equ fields@struct,anonymous,dw,count dup (?) \} |
macro rd count \{ \local anonymous |
fields@struct equ fields@struct,anonymous,dd,count dup (?) \} |
macro rp count \{ \local anonymous |
fields@struct equ fields@struct,anonymous,dp,count dup (?) \} |
macro rq count \{ \local anonymous |
fields@struct equ fields@struct,anonymous,dq,count dup (?) \} |
macro rt count \{ \local anonymous |
fields@struct equ fields@struct,anonymous,dt,count dup (?) \} |
macro union \{ fields@struct equ fields@struct,,union,< |
sub@struct equ union \} |
macro struct \{ fields@struct equ fields@struct,,substruct,< |
sub@struct equ substruct \} |
virtual at 0 } |
macro ends |
{ match , sub@struct \{ restruc db,dw,du,dd,dp,dq,dt |
restruc rb,rw,rd,rp,rq,rt |
purge db,dw,du,dd,dp,dq,dt |
purge rb,rw,rd,rp,rq,rt |
purge union,struct |
match name=,fields,fields@struct \\{ fields@struct equ |
make@struct name,fields |
fields@\\#name equ fields \\} |
end virtual \} |
match any, sub@struct \{ fields@struct equ fields@struct> \} |
restore sub@struct } |
macro make@struct name,[field,type,def] |
{ common |
if $ |
display 'Error: definition of ',`name,' contains illegal instructions.',0Dh,0Ah |
err |
end if |
local define |
define equ name |
forward |
local sub |
match , field \{ make@substruct type,name,sub def |
define equ define,.,sub, \} |
match any, field \{ define equ define,.#field,type,<def> \} |
common |
match fields, define \{ define@struct fields \} } |
macro define@struct name,[field,type,def] |
{ common |
local list |
list equ |
forward |
if ~ field eq . |
name#field type def |
sizeof.#name#field = $ - name#field |
else |
rb sizeof.#type |
end if |
local value |
match any, list \{ list equ list, \} |
list equ list <value> |
common |
sizeof.#name = $ |
restruc name |
match values, list \{ |
struc name value \\{ |
match any, fields@struct \\\{ fields@struct equ fields@struct,.,name,<values> \\\} |
match , fields@struct \\\{ label . |
forward |
match , value \\\\{ field type def \\\\} |
match any, value \\\\{ field type value |
if ~ field eq . |
rb sizeof.#name#field - ($-field) |
end if \\\\} |
common \\\} \\} \} } |
macro enable@substruct |
{ macro make@substruct substruct,parent,name,[field,type,def] |
\{ \common |
\local define |
define equ parent,name |
\forward |
\local sub |
match , field \\{ match any, type \\\{ enable@substruct |
make@substruct type,name,sub def |
purge make@substruct |
define equ define,.,sub, \\\} \\} |
match any, field \\{ define equ define,.\#field,type,<def> \\} |
\common |
match fields, define \\{ define@\#substruct fields \\} \} } |
enable@substruct |
macro define@union parent,name,[field,type,def] |
{ common |
virtual at 0 |
forward |
if ~ field eq . |
virtual at 0 |
parent#field type def |
sizeof.#parent#field = $ - parent#field |
end virtual |
if sizeof.#parent#field > $ |
rb sizeof.#parent#field - $ |
end if |
else if sizeof.#type > $ |
rb sizeof.#type - $ |
end if |
common |
sizeof.#name = $ |
end virtual |
struc name [value] \{ \common |
label .\#name |
last@union equ |
forward |
match any, last@union \\{ virtual at .\#name |
field type def |
end virtual \\} |
match , last@union \\{ match , value \\\{ field type def \\\} |
match any, value \\\{ field type value \\\} \\} |
last@union equ field |
common rb sizeof.#name - ($ - .\#name) \} } |
macro define@substruct parent,name,[field,type,def] |
{ common |
virtual at 0 |
forward |
if ~ field eq . |
parent#field type def |
sizeof.#parent#field = $ - parent#field |
else |
rb sizeof.#type |
end if |
local value |
common |
sizeof.#name = $ |
end virtual |
struc name value \{ |
label .\#name |
forward |
match , value \\{ field type def \\} |
match any, value \\{ field type value |
if ~ field eq . |
rb sizeof.#parent#field - ($-field) |
end if \\} |
common \} } |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/programs/fasm/trunk/system.inc |
---|
0,0 → 1,462 |
; flat assembler version 1.60 |
; Copyright (c) 1999-2005, Tomasz Grysztar |
; All rights reserved. |
; |
; MenuetOS system.inc by VT |
file_info_open: dd 0,0,0xffffff,0x20000,0xf0000 |
fullpath_open:; db '/HD/1/EXAMPLE.ASM' |
times MAX_PATH db 0 |
file_info_write: dd 1,0,0,0,0xf0000 |
fullpath_write:; db '/HD/1/EXAMPLE' |
times MAX_PATH db 0 |
file_info_start: dd 16,0,0,0,0xf0000 |
fullpath_start:; db '/HD/1/EXAMPLE' |
times MAX_PATH db 0 |
_ramdisk db '/RD/1/' |
filepos dd 0x0 |
; info by Privalov: starting from FASM 1.51 |
; ~3/8 - additional memory |
; ~5/8 - main memory |
init_memory: |
mov [memory_start],0x100000 |
mov [memory_end],0x100000+(APP_MEMORY-0x100000)/8*5 |
mov [additional_memory],0x100000+(APP_MEMORY-0x100000)/8*5 |
mov [additional_memory_end],APP_MEMORY |
ret |
exit_program: |
cmp [_mode],NORMAL_MODE |
je still |
or eax,-1 |
int 0x40 |
make_timestamp: |
push ebx |
mcall 26,9 |
imul eax,10 |
pop ebx |
ret |
get_environment_variable: |
mov ecx,[memory_end] |
sub ecx,edi |
cmp ecx,7 |
jb out_of_memory |
cmp dword[esi],'INCL' |
jne .finish |
mov esi,_ramdisk |
mov ecx,6 |
cld |
rep movsb |
.finish: |
; stc |
ret |
open: |
call make_fullpaths |
; mov eax,fullpath_open |
; DEBUGF '"%s"\n',eax |
mov dword[file_info_open+8],-1 |
mcall 58,file_info_open |
or eax,eax ; found |
jz @f |
cmp eax,6 |
jne file_error |
@@: mov [filesize],ebx |
clc |
ret |
file_error: |
stc |
ret |
create: |
call make_fullpaths |
ret |
; ebx file handle |
; ecx count of bytes to write |
; edx pointer to buffer |
write: |
pusha |
mov [file_info_write+8],ecx |
mov [file_info_write+12],edx |
mov [filesize],edx |
mov eax,58 |
mov ebx,file_info_write |
int 0x40 |
popa |
ret |
make_fullpaths: |
pusha |
push edx |
mov esi,path ; open |
; DEBUGF " '%s'",esi |
mov edi,fullpath_open |
cld |
newc1: |
movsb |
cmp byte[esi],0;' ' |
jne newc1 |
mov esi,[esp] |
cmp byte[esi],'/' |
jne @f |
mov edi,fullpath_open |
@@: |
lodsb |
stosb |
cmp al,0 |
jne @b |
; mov ecx,12 |
; cld |
; rep movsb |
; mov byte[edi],0 |
mov esi,path ; write |
mov edi,fullpath_write |
cld |
newc2: |
movsb |
cmp byte[esi],0;' ' |
jne newc2 |
mov esi,[esp] |
cmp byte[esi],'/' |
jne @f |
mov edi,fullpath_write |
@@: |
lodsb |
stosb |
cmp al,0 |
jne @b |
; mov ecx,12 |
; cld |
; rep movsb |
; mov byte[edi],0 |
mov esi,path ; start |
mov edi,fullpath_start |
cld |
newc3: |
movsb |
cmp byte[esi],0;' ' |
jne newc3 |
; mov esi,[esp] |
pop esi |
cmp byte[esi],'/' |
jne @f |
mov edi,fullpath_start |
@@: |
lodsb |
stosb |
cmp al,0 |
jne @b |
; mov ecx,12 |
; cld |
; rep movsb |
; mov byte[edi],0 |
; add esp,4 |
popa |
ret |
read: |
pusha |
mov edi,edx |
mov esi,[filepos] |
add esi,0x20000 |
cld |
rep movsb |
popa |
; ret |
close: ret |
lseek: |
cmp al,0 |
jnz @f |
mov [filepos],0 |
@@: cmp al,1 |
jnz @f |
@@: cmp al,2 |
jnz @f |
mov eax,[filesize] |
mov [filepos],eax |
@@: mov eax,[filepos] |
add eax,edx |
mov [filepos],eax |
ret |
display_character: |
pusha |
cmp [_mode],NORMAL_MODE |
jne @f |
cmp dl,13 |
jz dc2 |
cmp dl,0xa |
jnz dc1 |
and [textxy],0x0000FFFF |
add [textxy],OUTPUTXY and 0xFFFF0000 + 10 |
dc2: popa |
ret |
dc1: mov eax,[textxy] |
cmp ax,word[bottom_right] |
ja dc2 |
shr eax,16 |
cmp ax,word[bottom_right+2] |
ja dc2 |
mov [dc],dl |
mcall 4,[textxy],[sc.work_text],dc,1 |
add [textxy],0x00060000 |
popa |
ret |
@@: mov eax,63 |
mov ebx,1 |
mov cl,dl |
int 0x40 |
popa |
ret |
display_string: |
pusha |
@@: cmp byte[esi],0 |
je @f |
mov dl,[esi] |
call display_character |
add esi,1 |
jmp @b |
@@: popa |
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: |
; push [skinh] |
; pop [textxy] |
; add [textxy],OUTPUTXY |
mov [displayed_count],0 |
call flush_display_buffer |
cmp [displayed_count],1 |
jb line_break_ok |
je make_line_break |
mov ax,word[last_displayed] |
cmp ax,0A0Dh |
je line_break_ok |
cmp ax,0D0Ah |
je line_break_ok |
make_line_break: |
mov esi,lf |
call display_string |
line_break_ok: |
ret |
display_block: |
pusha |
@@: mov dl,[esi] |
call display_character |
inc esi |
loop @b |
popa |
ret |
fatal_error: |
mov esi,error_prefix |
call display_string |
pop esi |
call display_string |
mov esi,error_suffix |
call display_string |
mov esi,lf |
call display_string |
mov al,0FFh |
jmp exit_program |
assembler_error: |
call display_user_messages |
push dword 0 |
mov ebx,[current_line] |
get_error_lines: |
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 |
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 |
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 |
mov esi,cr_lf |
call display_string |
pop ebx |
or ebx,ebx |
jnz display_error_line |
mov esi,error_prefix |
call display_string |
pop esi |
call display_string |
mov esi,error_suffix |
call display_string |
jmp exit_program |
__draw_caption: |
; mcall 48,4 |
; mov [skinh],eax |
; mov ebx,eax |
; shr ebx,1 |
; adc ebx,1+0x000A0000-4 |
; mcall 4,,[sc.grab_text],s_title,[s_title.size] |
mcall 48,4 |
mov [skinh],eax |
shr eax,1 |
adc eax,0 |
add eax,1-4 |
push ax |
if center eq true |
mcall 9,PROCESSINFO,-1 |
mov ebx,[PROCESSINFO+process_information.x_size] |
shr ebx,1 |
sub ebx,header.size*6/2 + 8 |
else |
mov ebx,8 |
end if |
shl ebx,16 |
pop bx |
mcall 4,,[SYSTEMCOLORS+system_colors.grab_text] |
ret |
character db ?,0 |
bytes_count dd ? |
textxy dd 0x000500A0 |
dc db 0x0 |
filesize dd 0x0 |
displayed_count dd ? |
last_displayed rb 2 |
error_prefix db 'error: ',0 |
error_suffix db '.',0 |
line_data_start db ':' |
cr_lf db 0Dh,0Ah,0 |
line_number_start db ' [',0 |
macro dm string { db string,0 } |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/programs/fasm/trunk/variable.inc |
---|
0,0 → 1,116 |
; flat assembler core variables |
; Copyright (c) 1999-2005, Tomasz Grysztar. |
; All rights reserved. |
; Variables which have to be set up by interface: |
memory_start dd ? |
memory_end dd ? |
additional_memory dd ? |
additional_memory_end dd ? |
stack_limit dd ? |
input_file dd ? |
output_file dd ? |
passes_limit dw ? |
; Internal core variables: |
current_pass dw ? |
include_paths dd ? |
free_additional_memory dd ? |
source_start dd ? |
code_start dd ? |
code_size dd ? |
real_code_size dd ? |
written_size dd ? |
headers_size dd ? |
current_line dd ? |
macro_line dd ? |
macro_block dd ? |
macro_block_line dd ? |
macro_block_line_number dd ? |
macro_symbols dd ? |
struc_name dd ? |
struc_label dd ? |
instant_macro_start dd ? |
parameters_end dd ? |
locals_counter rb 8 |
current_locals_prefix dd ? |
anonymous_reverse dd ? |
anonymous_forward dd ? |
labels_list dd ? |
label_hash dd ? |
label_leaf dd ? |
hash_tree dd ? |
org_origin dq ? |
org_registers dd ? |
org_start dd ? |
org_symbol dd ? |
undefined_data_start dd ? |
undefined_data_end dd ? |
counter dd ? |
counter_limit dd ? |
error_line dd ? |
error dd ? |
display_buffer dd ? |
structures_buffer dd ? |
number_start dd ? |
current_offset dd ? |
value dq ? |
fp_value rd 8 |
adjustment dq ? |
symbol_identifier dd ? |
address_symbol dd ? |
address_high dd ? |
format_flags dd ? |
symbols_stream dd ? |
number_of_relocations dd ? |
number_of_sections dd ? |
stub_size dd ? |
stub_file dd ? |
current_section dd ? |
machine dw ? |
subsystem dw ? |
subsystem_version dd ? |
image_base dd ? |
image_base_high dd ? |
resource_data dd ? |
resource_size dd ? |
next_pass_needed db ? |
macro_status db ? |
parenthesis_stack db ? |
output_format db ? |
code_type db ? |
labels_type db ? |
prefixed_instruction db ? |
virtual_data db ? |
fp_sign db ? |
fp_format db ? |
value_size db ? |
size_override db ? |
address_size db ? |
operand_size db ? |
size_declared db ? |
value_undefined db ? |
value_type db ? |
compare_type db ? |
base_code db ? |
extended_code db ? |
postbyte_register db ? |
segment_register db ? |
mmx_size db ? |
jump_type db ? |
operand_prefix db ? |
rex_prefix db ? |
immediate_size db ? |
characters rb 100h |
converted rb 100h |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/programs/fasm/trunk/version.inc |
---|
0,0 → 1,39 |
; flat assembler version 1.64 |
; Copyright (c) 1999-2005, Tomasz Grysztar. |
; All rights reserved. |
; |
; This programs is free for commercial and non-commercial use as long as |
; the following conditions are adhered to. |
; |
; Redistribution and use in source and binary forms, with or without |
; modification, are permitted provided that the following conditions are |
; met: |
; |
; 1. Redistributions of source code must retain the above copyright notice, |
; this list of conditions and the following disclaimer. |
; 2. Redistributions in binary form must reproduce the above copyright |
; notice, this list of conditions and the following disclaimer in the |
; documentation and/or other materials provided with the distribution. |
; |
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
; TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
; PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR |
; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
; |
; The licence and distribution terms for any publically available |
; version or derivative of this code cannot be changed. i.e. this code |
; cannot simply be copied and put under another distribution licence |
; (including the GNU Public Licence). |
VERSION_STRING equ "1.64" |
VERSION_MAJOR = 1 |
VERSION_MINOR = 64 |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/programs/fasm/trunk/x86_64.inc |
---|
0,0 → 1,7923 |
; flat assembler core |
; Copyright (c) 1999-2005, Tomasz Grysztar. |
; All rights reserved. |
simple_instruction_except64: |
cmp [code_type],64 |
je illegal_instruction |
simple_instruction: |
stos byte [edi] |
jmp instruction_assembled |
simple_instruction_only64: |
cmp [code_type],64 |
jne illegal_instruction |
jmp simple_instruction |
simple_instruction_16bit_except64: |
cmp [code_type],64 |
je illegal_instruction |
simple_instruction_16bit: |
cmp [code_type],16 |
jne size_prefix |
stos byte [edi] |
jmp instruction_assembled |
size_prefix: |
mov ah,al |
mov al,66h |
stos word [edi] |
jmp instruction_assembled |
simple_instruction_32bit_except64: |
cmp [code_type],64 |
je illegal_instruction |
simple_instruction_32bit: |
cmp [code_type],16 |
je size_prefix |
stos byte [edi] |
jmp instruction_assembled |
simple_instruction_64bit: |
cmp [code_type],64 |
jne illegal_instruction |
mov ah,al |
mov al,48h |
stos word [edi] |
jmp instruction_assembled |
simple_extended_instruction: |
mov ah,al |
mov al,0Fh |
stos word [edi] |
jmp instruction_assembled |
prefix_instruction: |
stos byte [edi] |
or [prefixed_instruction],-1 |
jmp continue_line |
segment_prefix: |
mov ah,al |
shr ah,4 |
cmp ah,6 |
jne illegal_instruction |
and al,1111b |
mov [segment_register],al |
call store_segment_prefix |
or [prefixed_instruction],-1 |
jmp continue_line |
int_instruction: |
lods byte [esi] |
call get_size_operator |
cmp ah,1 |
ja invalid_operand_size |
cmp al,'(' |
jne invalid_operand |
call get_byte_value |
mov ah,al |
mov al,0CDh |
stos word [edi] |
jmp instruction_assembled |
iret_instruction: |
cmp [code_type],64 |
jne simple_instruction |
call operand_64bit |
jmp simple_instruction |
aa_instruction: |
cmp [code_type],64 |
je illegal_instruction |
push eax |
mov bl,10 |
cmp byte [esi],'(' |
jne aa_store |
inc esi |
xor al,al |
xchg al,[operand_size] |
cmp al,1 |
ja invalid_operand_size |
call get_byte_value |
mov bl,al |
aa_store: |
cmp [operand_size],0 |
jne invalid_operand |
pop eax |
mov ah,bl |
stos word [edi] |
jmp instruction_assembled |
basic_instruction: |
mov [base_code],al |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je basic_reg |
cmp al,'[' |
jne invalid_operand |
basic_mem: |
call get_address |
push edx bx cx |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,'(' |
je basic_mem_imm |
cmp al,10h |
jne invalid_operand |
basic_mem_reg: |
lods byte [esi] |
call convert_register |
mov [postbyte_register],al |
pop cx bx edx |
mov al,ah |
cmp al,1 |
je basic_mem_reg_8bit |
call operand_autodetect |
inc [base_code] |
basic_mem_reg_8bit: |
call store_instruction |
jmp instruction_assembled |
basic_mem_imm: |
mov al,[operand_size] |
cmp al,1 |
je basic_mem_imm_8bit |
cmp al,2 |
je basic_mem_imm_16bit |
cmp al,4 |
je basic_mem_imm_32bit |
cmp al,8 |
je basic_mem_imm_64bit |
or al,al |
jnz invalid_operand_size |
cmp [error_line],0 |
jne basic_mem_imm_8bit |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],operand_size_not_specified |
basic_mem_imm_8bit: |
call get_byte_value |
mov byte [value],al |
mov al,[base_code] |
shr al,3 |
mov [postbyte_register],al |
pop cx bx edx |
mov [base_code],80h |
call store_instruction_with_imm8 |
jmp instruction_assembled |
basic_mem_imm_16bit: |
call operand_16bit |
call get_word_value |
mov word [value],ax |
mov al,[base_code] |
shr al,3 |
mov [postbyte_register],al |
pop cx bx edx |
cmp [value_type],0 |
jne basic_mem_imm_16bit_store |
cmp [size_declared],0 |
jne basic_mem_imm_16bit_store |
cmp word [value],80h |
jb basic_mem_simm_8bit |
cmp word [value],-80h |
jae basic_mem_simm_8bit |
basic_mem_imm_16bit_store: |
mov [base_code],81h |
call store_instruction_with_imm16 |
jmp instruction_assembled |
basic_mem_simm_8bit: |
mov [base_code],83h |
call store_instruction_with_imm8 |
jmp instruction_assembled |
basic_mem_imm_32bit: |
call operand_32bit |
call get_dword_value |
basic_mem_imm_32bit_ok: |
mov dword [value],eax |
mov al,[base_code] |
shr al,3 |
mov [postbyte_register],al |
pop cx bx edx |
cmp [value_type],0 |
jne basic_mem_imm_32bit_store |
cmp [size_declared],0 |
jne basic_mem_imm_32bit_store |
cmp dword [value],80h |
jb basic_mem_simm_8bit |
cmp dword [value],-80h |
jae basic_mem_simm_8bit |
basic_mem_imm_32bit_store: |
mov [base_code],81h |
call store_instruction_with_imm32 |
jmp instruction_assembled |
basic_mem_imm_64bit: |
cmp [size_declared],0 |
jne long_immediate_not_encodable |
call operand_64bit |
call get_simm32 |
cmp [value_type],4 |
jae long_immediate_not_encodable |
jmp basic_mem_imm_32bit_ok |
get_simm32: |
call get_qword_value |
mov ecx,edx |
cdq |
cmp ecx,edx |
jne value_out_of_range |
ret |
basic_reg: |
lods byte [esi] |
call convert_register |
mov [postbyte_register],al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je basic_reg_reg |
cmp al,'(' |
je basic_reg_imm |
cmp al,'[' |
jne invalid_operand |
basic_reg_mem: |
call get_address |
mov al,[operand_size] |
cmp al,1 |
je basic_reg_mem_8bit |
call operand_autodetect |
add [base_code],3 |
call store_instruction |
jmp instruction_assembled |
basic_reg_mem_8bit: |
add [base_code],2 |
call store_instruction |
jmp instruction_assembled |
basic_reg_reg: |
lods byte [esi] |
call convert_register |
mov bl,[postbyte_register] |
mov [postbyte_register],al |
mov al,ah |
cmp al,1 |
je basic_reg_reg_8bit |
call operand_autodetect |
inc [base_code] |
basic_reg_reg_8bit: |
call store_nomem_instruction |
jmp instruction_assembled |
basic_reg_imm: |
mov al,[operand_size] |
cmp al,1 |
je basic_reg_imm_8bit |
cmp al,2 |
je basic_reg_imm_16bit |
cmp al,4 |
je basic_reg_imm_32bit |
cmp al,8 |
je basic_reg_imm_64bit |
or al,al |
jnz invalid_operand_size |
cmp [error_line],0 |
jne basic_reg_imm_32bit |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],operand_size_not_specified |
jmp basic_reg_imm_32bit |
basic_reg_imm_8bit: |
call get_byte_value |
mov dl,al |
mov bl,[base_code] |
shr bl,3 |
xchg bl,[postbyte_register] |
or bl,bl |
jz basic_al_imm |
mov [base_code],80h |
call store_nomem_instruction |
mov al,dl |
stos byte [edi] |
jmp instruction_assembled |
basic_al_imm: |
mov al,[base_code] |
add al,4 |
stos byte [edi] |
mov al,dl |
stos byte [edi] |
jmp instruction_assembled |
basic_reg_imm_16bit: |
call operand_16bit |
call get_word_value |
mov dx,ax |
mov bl,[base_code] |
shr bl,3 |
xchg bl,[postbyte_register] |
cmp [value_type],0 |
jne basic_reg_imm_16bit_store |
cmp [size_declared],0 |
jne basic_reg_imm_16bit_store |
cmp dx,80h |
jb basic_reg_simm_8bit |
cmp dx,-80h |
jae basic_reg_simm_8bit |
basic_reg_imm_16bit_store: |
or bl,bl |
jz basic_ax_imm |
mov [base_code],81h |
call store_nomem_instruction |
mov ax,dx |
call mark_relocation |
stos word [edi] |
jmp instruction_assembled |
basic_reg_simm_8bit: |
mov [base_code],83h |
call store_nomem_instruction |
mov al,dl |
stos byte [edi] |
jmp instruction_assembled |
basic_ax_imm: |
add [base_code],5 |
call store_instruction_code |
mov ax,dx |
call mark_relocation |
stos word [edi] |
jmp instruction_assembled |
basic_reg_imm_32bit: |
call operand_32bit |
call get_dword_value |
basic_reg_imm_32bit_ok: |
mov edx,eax |
mov bl,[base_code] |
shr bl,3 |
xchg bl,[postbyte_register] |
cmp [value_type],0 |
jne basic_reg_imm_32bit_store |
cmp [size_declared],0 |
jne basic_reg_imm_32bit_store |
cmp edx,80h |
jb basic_reg_simm_8bit |
cmp edx,-80h |
jae basic_reg_simm_8bit |
basic_reg_imm_32bit_store: |
or bl,bl |
jz basic_eax_imm |
mov [base_code],81h |
call store_nomem_instruction |
mov eax,edx |
call mark_relocation |
stos dword [edi] |
jmp instruction_assembled |
basic_eax_imm: |
add [base_code],5 |
call store_instruction_code |
mov eax,edx |
call mark_relocation |
stos dword [edi] |
jmp instruction_assembled |
basic_reg_imm_64bit: |
cmp [size_declared],0 |
jne long_immediate_not_encodable |
call operand_64bit |
call get_simm32 |
cmp [value_type],4 |
jae long_immediate_not_encodable |
jmp basic_reg_imm_32bit_ok |
single_operand_instruction: |
mov [base_code],0F6h |
mov [postbyte_register],al |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je single_reg |
cmp al,'[' |
jne invalid_operand |
single_mem: |
call get_address |
mov al,[operand_size] |
cmp al,1 |
je single_mem_8bit |
jb single_mem_nosize |
call operand_autodetect |
inc [base_code] |
call store_instruction |
jmp instruction_assembled |
single_mem_nosize: |
cmp [error_line],0 |
jne single_mem_8bit |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],operand_size_not_specified |
single_mem_8bit: |
call store_instruction |
jmp instruction_assembled |
single_reg: |
lods byte [esi] |
call convert_register |
mov bl,al |
mov al,ah |
cmp al,1 |
je single_reg_8bit |
call operand_autodetect |
inc [base_code] |
single_reg_8bit: |
call store_nomem_instruction |
jmp instruction_assembled |
mov_instruction: |
mov [base_code],88h |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je mov_reg |
cmp al,'[' |
jne invalid_operand |
mov_mem: |
call get_address |
push edx bx cx |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,'(' |
je mov_mem_imm |
cmp al,10h |
jne invalid_operand |
mov_mem_reg: |
lods byte [esi] |
cmp al,60h |
jb mov_mem_general_reg |
cmp al,70h |
jb mov_mem_sreg |
mov_mem_general_reg: |
call convert_register |
mov [postbyte_register],al |
pop cx bx edx |
cmp ah,1 |
je mov_mem_reg_8bit |
mov al,ah |
call operand_autodetect |
mov al,[postbyte_register] |
or al,bl |
or al,bh |
jz mov_mem_ax |
inc [base_code] |
call store_instruction |
jmp instruction_assembled |
mov_mem_reg_8bit: |
or al,bl |
or al,bh |
jz mov_mem_al |
call store_instruction |
jmp instruction_assembled |
mov_mem_al: |
test ch,22h |
jnz mov_mem_address16_al |
test ch,44h |
jnz mov_mem_address32_al |
test ch,88h |
jnz mov_mem_address64_al |
or ch,ch |
jnz invalid_address_size |
cmp [code_type],64 |
je mov_mem_address64_al |
cmp [code_type],32 |
je mov_mem_address32_al |
cmp edx,10000h |
jb mov_mem_address16_al |
mov_mem_address32_al: |
call store_segment_prefix_if_necessary |
call address_32bit_prefix |
mov [base_code],0A2h |
store_mov_address32: |
call store_instruction_code |
push instruction_assembled |
jmp store_address_32bit_value |
mov_mem_address16_al: |
call store_segment_prefix_if_necessary |
call address_16bit_prefix |
mov [base_code],0A2h |
store_mov_address16: |
cmp [code_type],64 |
je invalid_address |
call store_instruction_code |
mov eax,edx |
stos word [edi] |
cmp edx,10000h |
jge value_out_of_range |
jmp instruction_assembled |
mov_mem_address64_al: |
call store_segment_prefix_if_necessary |
mov [base_code],0A2h |
store_mov_address64: |
call store_instruction_code |
push instruction_assembled |
jmp store_address_64bit_value |
mov_mem_ax: |
test ch,22h |
jnz mov_mem_address16_ax |
test ch,44h |
jnz mov_mem_address32_ax |
test ch,88h |
jnz mov_mem_address64_ax |
or ch,ch |
jnz invalid_address_size |
cmp [code_type],64 |
je mov_mem_address64_ax |
cmp [code_type],32 |
je mov_mem_address32_ax |
cmp edx,10000h |
jb mov_mem_address16_ax |
mov_mem_address32_ax: |
call store_segment_prefix_if_necessary |
call address_32bit_prefix |
mov [base_code],0A3h |
jmp store_mov_address32 |
mov_mem_address16_ax: |
call store_segment_prefix_if_necessary |
call address_16bit_prefix |
mov [base_code],0A3h |
jmp store_mov_address16 |
mov_mem_address64_ax: |
call store_segment_prefix_if_necessary |
mov [base_code],0A3h |
jmp store_mov_address64 |
mov_mem_sreg: |
sub al,61h |
mov [postbyte_register],al |
pop cx bx edx |
mov ah,[operand_size] |
or ah,ah |
jz mov_mem_sreg_store |
cmp ah,2 |
jne invalid_operand_size |
mov_mem_sreg_store: |
mov [base_code],8Ch |
call store_instruction |
jmp instruction_assembled |
mov_mem_imm: |
mov al,[operand_size] |
cmp al,1 |
je mov_mem_imm_8bit |
cmp al,2 |
je mov_mem_imm_16bit |
cmp al,4 |
je mov_mem_imm_32bit |
cmp al,8 |
je mov_mem_imm_64bit |
or al,al |
jnz invalid_operand_size |
cmp [error_line],0 |
jne mov_mem_imm_32bit |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],operand_size_not_specified |
jmp mov_mem_imm_32bit |
mov_mem_imm_8bit: |
call get_byte_value |
mov byte [value],al |
mov [postbyte_register],0 |
mov [base_code],0C6h |
pop cx bx edx |
call store_instruction_with_imm8 |
jmp instruction_assembled |
mov_mem_imm_16bit: |
call operand_16bit |
call get_word_value |
mov word [value],ax |
mov [postbyte_register],0 |
mov [base_code],0C7h |
pop cx bx edx |
call store_instruction_with_imm16 |
jmp instruction_assembled |
mov_mem_imm_32bit: |
call operand_32bit |
call get_dword_value |
mov_mem_imm_32bit_store: |
mov dword [value],eax |
mov [postbyte_register],0 |
mov [base_code],0C7h |
pop cx bx edx |
call store_instruction_with_imm32 |
jmp instruction_assembled |
mov_mem_imm_64bit: |
cmp [size_declared],0 |
jne long_immediate_not_encodable |
call operand_64bit |
call get_simm32 |
cmp [value_type],4 |
jae long_immediate_not_encodable |
jmp mov_mem_imm_32bit_store |
mov_reg: |
lods byte [esi] |
mov ah,al |
sub ah,10h |
and ah,al |
test ah,0F0h |
jnz mov_sreg |
call convert_register |
mov [postbyte_register],al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
je mov_reg_mem |
cmp al,'(' |
je mov_reg_imm |
cmp al,10h |
jne invalid_operand |
mov_reg_reg: |
lods byte [esi] |
mov ah,al |
sub ah,10h |
and ah,al |
test ah,0F0h |
jnz mov_reg_sreg |
call convert_register |
mov bl,[postbyte_register] |
mov [postbyte_register],al |
mov al,ah |
cmp al,1 |
je mov_reg_reg_8bit |
call operand_autodetect |
inc [base_code] |
mov_reg_reg_8bit: |
call store_nomem_instruction |
jmp instruction_assembled |
mov_reg_sreg: |
mov bl,[postbyte_register] |
mov ah,al |
and al,1111b |
mov [postbyte_register],al |
shr ah,4 |
cmp ah,5 |
je mov_reg_creg |
cmp ah,7 |
je mov_reg_dreg |
ja mov_reg_treg |
dec [postbyte_register] |
cmp [operand_size],8 |
je mov_reg_sreg64 |
cmp [operand_size],4 |
je mov_reg_sreg32 |
cmp [operand_size],2 |
jne invalid_operand_size |
call operand_16bit |
jmp mov_reg_sreg_store |
mov_reg_sreg64: |
call operand_64bit |
jmp mov_reg_sreg_store |
mov_reg_sreg32: |
call operand_32bit |
mov_reg_sreg_store: |
mov [base_code],8Ch |
call store_nomem_instruction |
jmp instruction_assembled |
mov_reg_treg: |
cmp ah,9 |
jne invalid_operand |
mov [extended_code],24h |
jmp mov_reg_xrx |
mov_reg_dreg: |
mov [extended_code],21h |
jmp mov_reg_xrx |
mov_reg_creg: |
mov [extended_code],20h |
mov_reg_xrx: |
mov [base_code],0Fh |
cmp [code_type],64 |
je mov_reg_xrx_64bit |
cmp [operand_size],4 |
jne invalid_operand_size |
call store_nomem_instruction |
jmp instruction_assembled |
mov_reg_xrx_64bit: |
cmp [operand_size],8 |
jne invalid_operand_size |
call store_nomem_instruction |
jmp instruction_assembled |
mov_reg_mem: |
call get_address |
mov al,[operand_size] |
cmp al,1 |
je mov_reg_mem_8bit |
call operand_autodetect |
mov al,[postbyte_register] |
or al,bl |
or al,bh |
jz mov_ax_mem |
add [base_code],3 |
call store_instruction |
jmp instruction_assembled |
mov_reg_mem_8bit: |
mov al,[postbyte_register] |
or al,bl |
or al,bh |
jz mov_al_mem |
add [base_code],2 |
call store_instruction |
jmp instruction_assembled |
mov_al_mem: |
test ch,22h |
jnz mov_al_mem_address16 |
test ch,44h |
jnz mov_al_mem_address32 |
test ch,88h |
jnz mov_al_mem_address64 |
or ch,ch |
jnz invalid_address_size |
cmp [code_type],64 |
je mov_al_mem_address64 |
cmp [code_type],32 |
je mov_al_mem_address32 |
cmp edx,10000h |
jb mov_al_mem_address16 |
mov_al_mem_address32: |
call store_segment_prefix_if_necessary |
call address_32bit_prefix |
mov [base_code],0A0h |
jmp store_mov_address32 |
mov_al_mem_address16: |
call store_segment_prefix_if_necessary |
call address_16bit_prefix |
mov [base_code],0A0h |
jmp store_mov_address16 |
mov_al_mem_address64: |
call store_segment_prefix_if_necessary |
mov [base_code],0A0h |
jmp store_mov_address64 |
mov_ax_mem: |
test ch,22h |
jnz mov_ax_mem_address16 |
test ch,44h |
jnz mov_ax_mem_address32 |
test ch,88h |
jnz mov_ax_mem_address64 |
or ch,ch |
jnz invalid_address_size |
cmp [code_type],64 |
je mov_ax_mem_address64 |
cmp [code_type],32 |
je mov_ax_mem_address32 |
cmp edx,10000h |
jb mov_ax_mem_address16 |
mov_ax_mem_address32: |
call store_segment_prefix_if_necessary |
call address_32bit_prefix |
mov [base_code],0A1h |
jmp store_mov_address32 |
mov_ax_mem_address16: |
call store_segment_prefix_if_necessary |
mov [base_code],0A1h |
jmp store_mov_address16 |
mov_ax_mem_address64: |
call store_segment_prefix_if_necessary |
mov [base_code],0A1h |
jmp store_mov_address64 |
mov_reg_imm: |
mov al,[operand_size] |
cmp al,1 |
je mov_reg_imm_8bit |
cmp al,2 |
je mov_reg_imm_16bit |
cmp al,4 |
je mov_reg_imm_32bit |
cmp al,8 |
je mov_reg_imm_64bit |
or al,al |
jnz invalid_operand_size |
cmp [error_line],0 |
jne mov_reg_imm_32bit |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],operand_size_not_specified |
jmp mov_reg_imm_32bit |
mov_reg_imm_8bit: |
call get_byte_value |
mov dl,al |
mov al,0B0h |
call store_mov_reg_imm_code |
mov al,dl |
stos byte [edi] |
jmp instruction_assembled |
mov_reg_imm_16bit: |
call get_word_value |
mov dx,ax |
call operand_16bit |
mov al,0B8h |
call store_mov_reg_imm_code |
mov ax,dx |
call mark_relocation |
stos word [edi] |
jmp instruction_assembled |
mov_reg_imm_32bit: |
call operand_32bit |
call get_dword_value |
mov edx,eax |
mov al,0B8h |
call store_mov_reg_imm_code |
mov eax,edx |
call mark_relocation |
stos dword [edi] |
jmp instruction_assembled |
mov_reg_imm_64bit: |
call operand_64bit |
call get_qword_value |
mov ecx,edx |
cmp [size_declared],0 |
jne mov_reg_imm_64bit_store |
cmp [value_type],4 |
jae mov_reg_imm_64bit_store |
cdq |
cmp ecx,edx |
je mov_reg_64bit_imm_32bit |
mov_reg_imm_64bit_store: |
push eax ecx |
mov al,0B8h |
call store_mov_reg_imm_code |
pop edx eax |
call mark_relocation |
stos dword [edi] |
mov eax,edx |
stos dword [edi] |
jmp instruction_assembled |
store_mov_reg_imm_code: |
mov ah,[postbyte_register] |
test ah,1000b |
jz mov_reg_imm_prefix_ok |
or [rex_prefix],41h |
mov_reg_imm_prefix_ok: |
and ah,111b |
add al,ah |
mov [base_code],al |
call store_instruction_code |
ret |
mov_reg_64bit_imm_32bit: |
mov edx,eax |
mov bl,[postbyte_register] |
mov [postbyte_register],0 |
mov [base_code],0C7h |
call store_nomem_instruction |
mov eax,edx |
call mark_relocation |
stos dword [edi] |
jmp instruction_assembled |
mov_sreg: |
mov ah,al |
and al,111b |
mov [postbyte_register],al |
shr ah,4 |
cmp ah,5 |
je mov_creg |
cmp ah,7 |
je mov_dreg |
ja mov_treg |
cmp al,2 |
je illegal_instruction |
dec [postbyte_register] |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
je mov_sreg_mem |
cmp al,10h |
jne invalid_operand |
mov_sreg_reg: |
lods byte [esi] |
call convert_register |
or ah,ah |
jz mov_sreg_reg_size_ok |
cmp ah,2 |
jne invalid_operand_size |
mov bl,al |
mov_sreg_reg_size_ok: |
mov [base_code],8Eh |
call store_nomem_instruction |
jmp instruction_assembled |
mov_sreg_mem: |
call get_address |
mov al,[operand_size] |
or al,al |
jz mov_sreg_mem_size_ok |
cmp al,2 |
jne invalid_operand_size |
mov_sreg_mem_size_ok: |
mov [base_code],8Eh |
call store_instruction |
jmp instruction_assembled |
mov_treg: |
cmp ah,9 |
jne invalid_operand |
mov [extended_code],26h |
jmp mov_xrx |
mov_dreg: |
mov [extended_code],23h |
jmp mov_xrx |
mov_creg: |
mov [extended_code],22h |
mov_xrx: |
mov [base_code],0Fh |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
mov bl,al |
cmp [code_type],64 |
je mov_xrx_64bit |
cmp ah,4 |
jne invalid_operand_size |
call store_nomem_instruction |
jmp instruction_assembled |
mov_xrx_64bit: |
cmp ah,8 |
jne invalid_operand_size |
call store_nomem_instruction |
jmp instruction_assembled |
cmov_instruction: |
mov [base_code],0Fh |
mov [extended_code],al |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
mov [postbyte_register],al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
je cmov_reg_mem |
cmp al,10h |
jne invalid_operand |
cmov_reg_reg: |
lods byte [esi] |
call convert_register |
mov bl,al |
mov al,ah |
call operand_autodetect |
call store_nomem_instruction |
jmp instruction_assembled |
cmov_reg_mem: |
call get_address |
mov al,[operand_size] |
call operand_autodetect |
call store_instruction |
jmp instruction_assembled |
test_instruction: |
mov [base_code],84h |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je test_reg |
cmp al,'[' |
jne invalid_operand |
test_mem: |
call get_address |
push edx bx cx |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,'(' |
je test_mem_imm |
cmp al,10h |
jne invalid_operand |
test_mem_reg: |
lods byte [esi] |
call convert_register |
mov [postbyte_register],al |
pop cx bx edx |
mov al,ah |
cmp al,1 |
je test_mem_reg_8bit |
call operand_autodetect |
inc [base_code] |
test_mem_reg_8bit: |
call store_instruction |
jmp instruction_assembled |
test_mem_imm: |
mov al,[operand_size] |
cmp al,1 |
je test_mem_imm_8bit |
cmp al,2 |
je test_mem_imm_16bit |
cmp al,4 |
je test_mem_imm_32bit |
cmp al,8 |
je test_mem_imm_64bit |
or al,al |
jnz invalid_operand_size |
cmp [error_line],0 |
jne test_mem_imm_32bit |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],operand_size_not_specified |
jmp test_mem_imm_32bit |
test_mem_imm_8bit: |
call get_byte_value |
mov byte [value],al |
mov [postbyte_register],0 |
mov [base_code],0F6h |
pop cx bx edx |
call store_instruction_with_imm8 |
jmp instruction_assembled |
test_mem_imm_16bit: |
call operand_16bit |
call get_word_value |
mov word [value],ax |
mov [postbyte_register],0 |
mov [base_code],0F7h |
pop cx bx edx |
call store_instruction_with_imm16 |
jmp instruction_assembled |
test_mem_imm_32bit: |
call operand_32bit |
call get_dword_value |
test_mem_imm_32bit_store: |
mov dword [value],eax |
mov [postbyte_register],0 |
mov [base_code],0F7h |
pop cx bx edx |
call store_instruction_with_imm32 |
jmp instruction_assembled |
test_mem_imm_64bit: |
cmp [size_declared],0 |
jne long_immediate_not_encodable |
call operand_64bit |
call get_simm32 |
cmp [value_type],4 |
jae long_immediate_not_encodable |
jmp test_mem_imm_32bit_store |
test_reg: |
lods byte [esi] |
call convert_register |
mov [postbyte_register],al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
je test_reg_mem |
cmp al,'(' |
je test_reg_imm |
cmp al,10h |
jne invalid_operand |
test_reg_reg: |
lods byte [esi] |
call convert_register |
mov bl,[postbyte_register] |
mov [postbyte_register],al |
mov al,ah |
cmp al,1 |
je test_reg_reg_8bit |
call operand_autodetect |
inc [base_code] |
test_reg_reg_8bit: |
call store_nomem_instruction |
jmp instruction_assembled |
test_reg_imm: |
mov al,[operand_size] |
cmp al,1 |
je test_reg_imm_8bit |
cmp al,2 |
je test_reg_imm_16bit |
cmp al,4 |
je test_reg_imm_32bit |
cmp al,8 |
je test_reg_imm_64bit |
jmp invalid_operand_size |
test_reg_imm_8bit: |
call get_byte_value |
mov dl,al |
mov bl,[postbyte_register] |
mov [postbyte_register],0 |
mov [base_code],0F6h |
or bl,bl |
jz test_al_imm |
call store_nomem_instruction |
mov al,dl |
stos byte [edi] |
jmp instruction_assembled |
test_al_imm: |
mov [base_code],0A8h |
call store_instruction_code |
mov al,dl |
stos byte [edi] |
jmp instruction_assembled |
test_reg_imm_16bit: |
call operand_16bit |
call get_word_value |
mov dx,ax |
mov bl,[postbyte_register] |
mov [postbyte_register],0 |
mov [base_code],0F7h |
or bl,bl |
jz test_ax_imm |
call store_nomem_instruction |
mov ax,dx |
call mark_relocation |
stos word [edi] |
jmp instruction_assembled |
test_ax_imm: |
mov [base_code],0A9h |
call store_instruction_code |
mov ax,dx |
stos word [edi] |
jmp instruction_assembled |
test_reg_imm_32bit: |
call operand_32bit |
call get_dword_value |
test_reg_imm_32bit_store: |
mov edx,eax |
mov bl,[postbyte_register] |
mov [postbyte_register],0 |
mov [base_code],0F7h |
or bl,bl |
jz test_eax_imm |
call store_nomem_instruction |
mov eax,edx |
call mark_relocation |
stos dword [edi] |
jmp instruction_assembled |
test_eax_imm: |
mov [base_code],0A9h |
call store_instruction_code |
mov eax,edx |
stos dword [edi] |
jmp instruction_assembled |
test_reg_imm_64bit: |
cmp [size_declared],0 |
jne long_immediate_not_encodable |
call operand_64bit |
call get_simm32 |
cmp [value_type],4 |
jae long_immediate_not_encodable |
jmp test_reg_imm_32bit_store |
test_reg_mem: |
call get_address |
mov al,[operand_size] |
cmp al,1 |
je test_reg_mem_8bit |
call operand_autodetect |
inc [base_code] |
test_reg_mem_8bit: |
call store_instruction |
jmp instruction_assembled |
xchg_instruction: |
mov [base_code],86h |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je xchg_reg |
cmp al,'[' |
jne invalid_operand |
xchg_mem: |
call get_address |
push edx bx cx |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je test_mem_reg |
jmp invalid_operand |
xchg_reg: |
lods byte [esi] |
call convert_register |
mov [postbyte_register],al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
je test_reg_mem |
cmp al,10h |
jne invalid_operand |
xchg_reg_reg: |
lods byte [esi] |
call convert_register |
mov bl,al |
mov al,ah |
cmp al,1 |
je xchg_reg_reg_8bit |
call operand_autodetect |
cmp [postbyte_register],0 |
je xchg_ax_reg |
or bl,bl |
jnz xchg_reg_reg_store |
mov bl,[postbyte_register] |
xchg_ax_reg: |
cmp [code_type],64 |
jne xchg_ax_reg_ok |
cmp ah,4 |
jne xchg_ax_reg_ok |
or bl,bl |
jz xchg_reg_reg_store |
xchg_ax_reg_ok: |
test bl,1000b |
jz xchg_ax_reg_store |
or [rex_prefix],41h |
and bl,111b |
xchg_ax_reg_store: |
add bl,90h |
mov [base_code],bl |
call store_instruction_code |
jmp instruction_assembled |
xchg_reg_reg_store: |
inc [base_code] |
xchg_reg_reg_8bit: |
call store_nomem_instruction |
jmp instruction_assembled |
push_instruction: |
mov [extended_code],al |
push_next: |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je push_reg |
cmp al,'(' |
je push_imm |
cmp al,'[' |
jne invalid_operand |
push_mem: |
call get_address |
mov al,[operand_size] |
mov ah,[extended_code] |
cmp al,2 |
je push_mem_16bit |
cmp al,4 |
je push_mem_32bit |
cmp al,8 |
je push_mem_64bit |
or al,al |
jnz invalid_operand_size |
cmp ah,2 |
je push_mem_16bit |
cmp ah,4 |
je push_mem_32bit |
cmp ah,8 |
je push_mem_64bit |
cmp [error_line],0 |
jne push_mem_store |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],operand_size_not_specified |
jmp push_mem_store |
push_mem_16bit: |
test ah,not 2 |
jnz invalid_operand_size |
call operand_16bit |
jmp push_mem_store |
push_mem_32bit: |
test ah,not 4 |
jnz invalid_operand_size |
cmp [code_type],64 |
je illegal_instruction |
call operand_32bit |
jmp push_mem_store |
push_mem_64bit: |
test ah,not 8 |
jnz invalid_operand_size |
cmp [code_type],64 |
jne illegal_instruction |
push_mem_store: |
mov [base_code],0FFh |
mov [postbyte_register],110b |
call store_instruction |
jmp push_done |
push_reg: |
lods byte [esi] |
mov ah,al |
sub ah,10h |
and ah,al |
test ah,0F0h |
jnz push_sreg |
call convert_register |
test al,1000b |
jz push_reg_ok |
or [rex_prefix],41h |
and al,111b |
push_reg_ok: |
add al,50h |
mov [base_code],al |
mov al,ah |
mov ah,[extended_code] |
cmp al,2 |
je push_reg_16bit |
cmp al,4 |
je push_reg_32bit |
cmp al,8 |
jne invalid_operand_size |
push_reg_64bit: |
test ah,not 8 |
jnz invalid_operand_size |
cmp [code_type],64 |
jne illegal_instruction |
jmp push_reg_store |
push_reg_32bit: |
test ah,not 4 |
jnz invalid_operand_size |
cmp [code_type],64 |
je illegal_instruction |
call operand_32bit |
jmp push_reg_store |
push_reg_16bit: |
test ah,not 2 |
jnz invalid_operand_size |
call operand_16bit |
push_reg_store: |
call store_instruction_code |
jmp push_done |
push_sreg: |
mov bl,al |
mov dl,[operand_size] |
mov dh,[extended_code] |
cmp dl,2 |
je push_sreg16 |
cmp dl,4 |
je push_sreg32 |
cmp dl,8 |
je push_sreg64 |
or dl,dl |
jnz invalid_operand_size |
cmp dh,2 |
je push_sreg16 |
cmp dh,4 |
je push_sreg32 |
cmp dh,8 |
je push_sreg64 |
jmp push_sreg_store |
push_sreg16: |
test dh,not 2 |
jnz invalid_operand_size |
call operand_16bit |
jmp push_sreg_store |
push_sreg32: |
test dh,not 4 |
jnz invalid_operand_size |
cmp [code_type],64 |
je illegal_instruction |
call operand_32bit |
jmp push_sreg_store |
push_sreg64: |
test dh,not 8 |
jnz invalid_operand_size |
cmp [code_type],64 |
jne illegal_instruction |
push_sreg_store: |
mov al,bl |
cmp al,70h |
jae invalid_operand |
sub al,61h |
cmp al,4 |
jae push_sreg_386 |
shl al,3 |
add al,6 |
mov [base_code],al |
cmp [code_type],64 |
je illegal_instruction |
jmp push_reg_store |
push_sreg_386: |
sub al,4 |
shl al,3 |
add al,0A0h |
mov [extended_code],al |
mov [base_code],0Fh |
jmp push_reg_store |
push_imm: |
mov al,[operand_size] |
mov ah,[extended_code] |
or al,al |
je push_imm_size_ok |
or ah,ah |
je push_imm_size_ok |
cmp al,ah |
jne invalid_operand_size |
push_imm_size_ok: |
cmp al,2 |
je push_imm_16bit |
cmp al,4 |
je push_imm_32bit |
cmp al,8 |
je push_imm_64bit |
cmp ah,2 |
je push_imm_optimized_16bit |
cmp ah,4 |
je push_imm_optimized_32bit |
cmp ah,8 |
je push_imm_optimized_64bit |
or al,al |
jnz invalid_operand_size |
cmp [code_type],16 |
je push_imm_optimized_16bit |
cmp [code_type],32 |
je push_imm_optimized_32bit |
push_imm_optimized_64bit: |
cmp [code_type],64 |
jne illegal_instruction |
call get_simm32 |
mov edx,eax |
cmp [value_type],0 |
jne push_imm_32bit_store |
cmp eax,-80h |
jl push_imm_32bit_store |
cmp eax,80h |
jge push_imm_32bit_store |
jmp push_imm_8bit |
push_imm_optimized_32bit: |
cmp [code_type],64 |
je illegal_instruction |
call get_dword_value |
mov edx,eax |
cmp [value_type],0 |
jne push_imm_32bit_store |
cmp eax,-80h |
jl push_imm_32bit_store |
cmp eax,80h |
jge push_imm_32bit_store |
call operand_32bit |
jmp push_imm_8bit |
push_imm_optimized_16bit: |
call get_word_value |
mov dx,ax |
cmp [value_type],0 |
jne push_imm_16bit_store |
cmp ax,-80h |
jl push_imm_16bit_store |
cmp ax,80h |
jge push_imm_16bit_store |
call operand_16bit |
push_imm_8bit: |
mov ah,al |
mov al,6Ah |
stos word [edi] |
jmp push_done |
push_imm_16bit: |
call get_word_value |
mov dx,ax |
call operand_16bit |
push_imm_16bit_store: |
mov [base_code],68h |
call store_instruction_code |
mov ax,dx |
call mark_relocation |
stos word [edi] |
jmp push_done |
push_imm_64bit: |
cmp [code_type],64 |
jne illegal_instruction |
call get_simm32 |
mov edx,eax |
jmp push_imm_32bit_store |
push_imm_32bit: |
cmp [code_type],64 |
je illegal_instruction |
call get_dword_value |
mov edx,eax |
call operand_32bit |
push_imm_32bit_store: |
mov [base_code],68h |
call store_instruction_code |
mov eax,edx |
call mark_relocation |
stos dword [edi] |
push_done: |
lods byte [esi] |
dec esi |
cmp al,0Fh |
je instruction_assembled |
or al,al |
jz instruction_assembled |
mov [operand_size],0 |
mov [size_override],0 |
mov [operand_prefix],0 |
mov [rex_prefix],0 |
jmp push_next |
pop_instruction: |
mov [extended_code],al |
pop_next: |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je pop_reg |
cmp al,'[' |
jne invalid_operand |
pop_mem: |
call get_address |
mov al,[operand_size] |
mov ah,[extended_code] |
cmp al,2 |
je pop_mem_16bit |
cmp al,4 |
je pop_mem_32bit |
cmp al,8 |
je pop_mem_64bit |
or al,al |
jnz invalid_operand_size |
cmp ah,2 |
je pop_mem_16bit |
cmp ah,4 |
je pop_mem_32bit |
cmp ah,8 |
je pop_mem_64bit |
cmp [error_line],0 |
jne pop_mem_store |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],operand_size_not_specified |
jmp pop_mem_store |
pop_mem_16bit: |
test ah,not 2 |
jnz invalid_operand_size |
call operand_16bit |
jmp pop_mem_store |
pop_mem_32bit: |
test ah,not 4 |
jnz invalid_operand_size |
cmp [code_type],64 |
je illegal_instruction |
call operand_32bit |
jmp pop_mem_store |
pop_mem_64bit: |
test ah,not 8 |
jnz invalid_operand_size |
cmp [code_type],64 |
jne illegal_instruction |
pop_mem_store: |
mov [base_code],08Fh |
mov [postbyte_register],0 |
call store_instruction |
jmp pop_done |
pop_reg: |
lods byte [esi] |
mov ah,al |
sub ah,10h |
and ah,al |
test ah,0F0h |
jnz pop_sreg |
call convert_register |
test al,1000b |
jz pop_reg_ok |
or [rex_prefix],41h |
and al,111b |
pop_reg_ok: |
add al,58h |
mov [base_code],al |
mov al,ah |
mov ah,[extended_code] |
cmp al,2 |
je pop_reg_16bit |
cmp al,4 |
je pop_reg_32bit |
cmp al,8 |
je pop_reg_64bit |
jmp invalid_operand_size |
pop_reg_64bit: |
test ah,not 8 |
jnz invalid_operand_size |
cmp [code_type],64 |
jne illegal_instruction |
jmp pop_reg_store |
pop_reg_32bit: |
test ah,not 4 |
jnz invalid_operand_size |
cmp [code_type],64 |
je illegal_instruction |
call operand_32bit |
jmp pop_reg_store |
pop_reg_16bit: |
test ah,not 2 |
jnz invalid_operand_size |
call operand_16bit |
pop_reg_store: |
call store_instruction_code |
pop_done: |
lods byte [esi] |
dec esi |
cmp al,0Fh |
je instruction_assembled |
or al,al |
jz instruction_assembled |
mov [operand_size],0 |
mov [size_override],0 |
mov [operand_prefix],0 |
mov [rex_prefix],0 |
jmp pop_next |
pop_sreg: |
mov bl,al |
mov dl,[operand_size] |
mov dh,[extended_code] |
cmp dl,2 |
je pop_sreg16 |
cmp dl,4 |
je pop_sreg32 |
cmp dl,8 |
je pop_sreg64 |
or dl,dl |
jnz invalid_operand_size |
cmp dh,2 |
je pop_sreg16 |
cmp dh,4 |
je pop_sreg32 |
cmp dh,8 |
je pop_sreg64 |
jmp pop_sreg_store |
pop_sreg16: |
test dh,not 2 |
jnz invalid_operand_size |
call operand_16bit |
jmp pop_sreg_store |
pop_sreg32: |
test dh,not 4 |
jnz invalid_operand_size |
cmp [code_type],64 |
je illegal_instruction |
call operand_32bit |
jmp pop_sreg_store |
pop_sreg64: |
test dh,not 8 |
jnz invalid_operand_size |
cmp [code_type],64 |
jne illegal_instruction |
pop_sreg_store: |
mov al,bl |
cmp al,70h |
jae invalid_operand |
sub al,61h |
cmp al,4 |
jae pop_sreg_386 |
shl al,3 |
add al,7 |
mov [base_code],al |
cmp [code_type],64 |
je illegal_instruction |
jmp pop_reg_store |
pop_sreg_386: |
sub al,4 |
shl al,3 |
add al,0A1h |
mov [extended_code],al |
mov [base_code],0Fh |
jmp pop_reg_store |
inc_instruction: |
mov [base_code],al |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je inc_reg |
cmp al,'[' |
je inc_mem |
jne invalid_operand |
inc_mem: |
call get_address |
mov al,[operand_size] |
cmp al,1 |
je inc_mem_8bit |
jb inc_mem_nosize |
call operand_autodetect |
mov al,0FFh |
xchg al,[base_code] |
mov [postbyte_register],al |
call store_instruction |
jmp instruction_assembled |
inc_mem_nosize: |
cmp [error_line],0 |
jne inc_mem_8bit |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],operand_size_not_specified |
inc_mem_8bit: |
mov al,0FEh |
xchg al,[base_code] |
mov [postbyte_register],al |
call store_instruction |
jmp instruction_assembled |
inc_reg: |
lods byte [esi] |
call convert_register |
mov bl,al |
mov al,0FEh |
xchg al,[base_code] |
mov [postbyte_register],al |
mov al,ah |
cmp al,1 |
je inc_reg_8bit |
call operand_autodetect |
cmp [code_type],64 |
je inc_reg_long_form |
mov al,[postbyte_register] |
shl al,3 |
add al,bl |
add al,40h |
mov [base_code],al |
call store_instruction_code |
jmp instruction_assembled |
inc_reg_long_form: |
inc [base_code] |
inc_reg_8bit: |
call store_nomem_instruction |
jmp instruction_assembled |
set_instruction: |
mov [base_code],0Fh |
mov [extended_code],al |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je set_reg |
cmp al,'[' |
jne invalid_operand |
set_mem: |
call get_address |
cmp [operand_size],1 |
ja invalid_operand_size |
mov [postbyte_register],0 |
call store_instruction |
jmp instruction_assembled |
set_reg: |
lods byte [esi] |
call convert_register |
cmp ah,1 |
jne invalid_operand_size |
mov bl,al |
mov [postbyte_register],0 |
call store_nomem_instruction |
jmp instruction_assembled |
arpl_instruction: |
cmp [code_type],64 |
je illegal_instruction |
mov [base_code],63h |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je arpl_reg |
cmp al,'[' |
jne invalid_operand |
call get_address |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
mov [postbyte_register],al |
cmp ah,2 |
jne invalid_operand_size |
call store_instruction |
jmp instruction_assembled |
arpl_reg: |
lods byte [esi] |
call convert_register |
cmp ah,2 |
jne invalid_operand_size |
mov bl,al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
cmp ah,2 |
jne invalid_operand_size |
mov [postbyte_register],al |
call store_nomem_instruction |
jmp instruction_assembled |
bound_instruction: |
cmp [code_type],64 |
je illegal_instruction |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
mov [postbyte_register],al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
mov al,[operand_size] |
cmp al,2 |
je bound_16bit |
cmp al,4 |
je bound_32bit |
jmp invalid_operand_size |
bound_32bit: |
call operand_32bit |
mov [base_code],62h |
call store_instruction |
jmp instruction_assembled |
bound_16bit: |
call operand_16bit |
mov [base_code],62h |
call store_instruction |
jmp instruction_assembled |
enter_instruction: |
lods byte [esi] |
call get_size_operator |
cmp ah,2 |
je enter_imm16_size_ok |
or ah,ah |
jnz invalid_operand_size |
enter_imm16_size_ok: |
cmp al,'(' |
jne invalid_operand |
call get_word_value |
cmp [next_pass_needed],0 |
jne enter_imm16_ok |
cmp [value_type],0 |
jne invalid_use_of_symbol |
enter_imm16_ok: |
push eax |
mov [operand_size],0 |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp ah,1 |
je enter_imm8_size_ok |
or ah,ah |
jnz invalid_operand_size |
enter_imm8_size_ok: |
cmp al,'(' |
jne invalid_operand |
call get_byte_value |
mov dl,al |
pop ebx |
mov al,0C8h |
stos byte [edi] |
mov ax,bx |
stos word [edi] |
mov al,dl |
stos byte [edi] |
jmp instruction_assembled |
ret_instruction_only64: |
cmp [code_type],64 |
jne illegal_instruction |
jmp ret_instruction |
ret_instruction_32bit_except64: |
cmp [code_type],64 |
je illegal_instruction |
ret_instruction_32bit: |
call operand_32bit |
jmp ret_instruction |
ret_instruction_16bit: |
call operand_16bit |
jmp ret_instruction |
retf_instruction: |
cmp [code_type],64 |
jne ret_instruction |
ret_instruction_64bit: |
call operand_64bit |
ret_instruction: |
mov [base_code],al |
lods byte [esi] |
dec esi |
or al,al |
jz simple_ret |
cmp al,0Fh |
je simple_ret |
lods byte [esi] |
call get_size_operator |
or ah,ah |
jz ret_imm |
cmp ah,2 |
je ret_imm |
jmp invalid_operand_size |
ret_imm: |
cmp al,'(' |
jne invalid_operand |
call get_word_value |
cmp [next_pass_needed],0 |
jne ret_imm_ok |
cmp [value_type],0 |
jne invalid_use_of_symbol |
ret_imm_ok: |
mov dx,ax |
call store_instruction_code |
mov ax,dx |
stos word [edi] |
jmp instruction_assembled |
simple_ret: |
inc [base_code] |
call store_instruction_code |
jmp instruction_assembled |
lea_instruction: |
mov [base_code],8Dh |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
mov [postbyte_register],al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
xor al,al |
xchg al,[operand_size] |
push eax |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
pop eax |
call operand_autodetect |
call store_instruction |
jmp instruction_assembled |
ls_instruction: |
or al,al |
jz les_instruction |
cmp al,3 |
jz lds_instruction |
add al,0B0h |
mov [extended_code],al |
mov [base_code],0Fh |
jmp ls_code_ok |
les_instruction: |
mov [base_code],0C4h |
jmp ls_short_code |
lds_instruction: |
mov [base_code],0C5h |
ls_short_code: |
cmp [code_type],64 |
je illegal_instruction |
ls_code_ok: |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
mov [postbyte_register],al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
add [operand_size],2 |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
mov al,[operand_size] |
cmp al,4 |
je ls_16bit |
cmp al,6 |
je ls_32bit |
cmp al,10 |
je ls_64bit |
jmp invalid_operand_size |
ls_16bit: |
call operand_16bit |
call store_instruction |
jmp instruction_assembled |
ls_32bit: |
call operand_32bit |
call store_instruction |
jmp instruction_assembled |
ls_64bit: |
call operand_64bit |
call store_instruction |
jmp instruction_assembled |
sh_instruction: |
mov [postbyte_register],al |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je sh_reg |
cmp al,'[' |
jne invalid_operand |
sh_mem: |
call get_address |
push edx bx cx |
mov al,[operand_size] |
push eax |
mov [operand_size],0 |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,'(' |
je sh_mem_imm |
cmp al,10h |
jne invalid_operand |
sh_mem_reg: |
lods byte [esi] |
cmp al,11h |
jne invalid_operand |
pop eax cx bx edx |
cmp al,1 |
je sh_mem_cl_8bit |
jb sh_mem_cl_nosize |
call operand_autodetect |
mov [base_code],0D3h |
call store_instruction |
jmp instruction_assembled |
sh_mem_cl_nosize: |
cmp [error_line],0 |
jne sh_mem_cl_8bit |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],operand_size_not_specified |
sh_mem_cl_8bit: |
mov [base_code],0D2h |
call store_instruction |
jmp instruction_assembled |
sh_mem_imm: |
mov al,[operand_size] |
or al,al |
jz sh_mem_imm_size_ok |
cmp al,1 |
jne invalid_operand_size |
sh_mem_imm_size_ok: |
call get_byte_value |
mov byte [value],al |
pop eax cx bx edx |
cmp al,1 |
je sh_mem_imm_8bit |
jb sh_mem_imm_nosize |
call operand_autodetect |
cmp byte [value],1 |
je sh_mem_1 |
mov [base_code],0C1h |
call store_instruction_with_imm8 |
jmp instruction_assembled |
sh_mem_1: |
mov [base_code],0D1h |
call store_instruction |
jmp instruction_assembled |
sh_mem_imm_nosize: |
cmp [error_line],0 |
jne sh_mem_imm_8bit |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],operand_size_not_specified |
sh_mem_imm_8bit: |
cmp byte [value],1 |
je sh_mem_1_8bit |
mov [base_code],0C0h |
call store_instruction_with_imm8 |
jmp instruction_assembled |
sh_mem_1_8bit: |
mov [base_code],0D0h |
call store_instruction |
jmp instruction_assembled |
sh_reg: |
lods byte [esi] |
call convert_register |
mov bx,ax |
mov [operand_size],0 |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,'(' |
je sh_reg_imm |
cmp al,10h |
jne invalid_operand |
sh_reg_reg: |
lods byte [esi] |
cmp al,11h |
jne invalid_operand |
mov al,bh |
cmp al,1 |
je sh_reg_cl_8bit |
call operand_autodetect |
mov [base_code],0D3h |
call store_nomem_instruction |
jmp instruction_assembled |
sh_reg_cl_8bit: |
mov [base_code],0D2h |
call store_nomem_instruction |
jmp instruction_assembled |
sh_reg_imm: |
mov al,[operand_size] |
or al,al |
jz sh_reg_imm_size_ok |
cmp al,1 |
jne invalid_operand_size |
sh_reg_imm_size_ok: |
push ebx |
call get_byte_value |
mov dl,al |
pop ebx |
mov al,bh |
cmp al,1 |
je sh_reg_imm_8bit |
call operand_autodetect |
cmp dl,1 |
je sh_reg_1 |
mov [base_code],0C1h |
call store_nomem_instruction |
mov al,dl |
stos byte [edi] |
jmp instruction_assembled |
sh_reg_1: |
mov [base_code],0D1h |
call store_nomem_instruction |
jmp instruction_assembled |
sh_reg_imm_8bit: |
cmp dl,1 |
je sh_reg_1_8bit |
mov [base_code],0C0h |
call store_nomem_instruction |
mov al,dl |
stos byte [edi] |
jmp instruction_assembled |
sh_reg_1_8bit: |
mov [base_code],0D0h |
call store_nomem_instruction |
jmp instruction_assembled |
shd_instruction: |
mov [base_code],0Fh |
mov [extended_code],al |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je shd_reg |
cmp al,'[' |
jne invalid_operand |
shd_mem: |
call get_address |
push edx bx cx |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
mov [postbyte_register],al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
mov al,ah |
mov [operand_size],0 |
push eax |
lods byte [esi] |
call get_size_operator |
cmp al,'(' |
je shd_mem_reg_imm |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
cmp al,11h |
jne invalid_operand |
pop eax cx bx edx |
call operand_autodetect |
inc [extended_code] |
call store_instruction |
jmp instruction_assembled |
shd_mem_reg_imm: |
mov al,[operand_size] |
or al,al |
jz shd_mem_reg_imm_size_ok |
cmp al,1 |
jne invalid_operand_size |
shd_mem_reg_imm_size_ok: |
call get_byte_value |
mov byte [value],al |
pop eax cx bx edx |
call operand_autodetect |
call store_instruction_with_imm8 |
jmp instruction_assembled |
shd_reg: |
lods byte [esi] |
call convert_register |
mov [postbyte_register],al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
mov bl,[postbyte_register] |
mov [postbyte_register],al |
mov al,ah |
push eax ebx |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
mov [operand_size],0 |
lods byte [esi] |
call get_size_operator |
cmp al,'(' |
je shd_reg_reg_imm |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
cmp al,11h |
jne invalid_operand |
pop ebx eax |
call operand_autodetect |
inc [extended_code] |
call store_nomem_instruction |
jmp instruction_assembled |
shd_reg_reg_imm: |
mov al,[operand_size] |
or al,al |
jz shd_reg_reg_imm_size_ok |
cmp al,1 |
jne invalid_operand_size |
shd_reg_reg_imm_size_ok: |
call get_byte_value |
mov dl,al |
pop ebx eax |
call operand_autodetect |
call store_nomem_instruction |
mov al,dl |
stos byte [edi] |
jmp instruction_assembled |
movx_instruction: |
mov [base_code],0Fh |
mov [extended_code],al |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
mov [postbyte_register],al |
mov al,ah |
push eax |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
mov [operand_size],0 |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je movx_reg |
cmp al,'[' |
jne invalid_operand |
call get_address |
pop eax |
mov ah,[operand_size] |
cmp ah,al |
jae invalid_operand_size |
cmp ah,1 |
je movx_mem_8bit |
cmp ah,2 |
je movx_mem_16bit |
or ah,ah |
jnz invalid_operand_size |
cmp [error_line],0 |
jne movx_mem_8bit |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],operand_size_not_specified |
movx_mem_8bit: |
call operand_autodetect |
call store_instruction |
jmp instruction_assembled |
movx_mem_16bit: |
inc [extended_code] |
call operand_autodetect |
call store_instruction |
jmp instruction_assembled |
movx_reg: |
lods byte [esi] |
call convert_register |
pop ebx |
xchg bl,al |
cmp ah,al |
jae invalid_operand_size |
cmp ah,1 |
je movx_reg_8bit |
cmp ah,2 |
je movx_reg_16bit |
jmp invalid_operand_size |
movx_reg_8bit: |
call operand_autodetect |
call store_nomem_instruction |
jmp instruction_assembled |
movx_reg_16bit: |
call operand_autodetect |
inc [extended_code] |
call store_nomem_instruction |
jmp instruction_assembled |
movsxd_instruction: |
mov [base_code],al |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
mov [postbyte_register],al |
cmp ah,8 |
jne invalid_operand_size |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
mov [operand_size],0 |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je movsxd_reg |
cmp al,'[' |
jne invalid_operand |
call get_address |
cmp [operand_size],4 |
je movsxd_mem_store |
cmp [operand_size],0 |
jne invalid_operand_size |
movsxd_mem_store: |
call operand_64bit |
call store_instruction |
jmp instruction_assembled |
movsxd_reg: |
lods byte [esi] |
call convert_register |
cmp ah,4 |
jne invalid_operand_size |
call operand_64bit |
call store_nomem_instruction |
jmp instruction_assembled |
bt_instruction: |
mov [postbyte_register],al |
shl al,3 |
add al,83h |
mov [extended_code],al |
mov [base_code],0Fh |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je bt_reg |
cmp al,'[' |
jne invalid_operand |
call get_address |
push eax bx cx |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
cmp byte [esi],'(' |
je bt_mem_imm |
cmp byte [esi],11h |
jne bt_mem_reg |
cmp byte [esi+2],'(' |
je bt_mem_imm |
bt_mem_reg: |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
mov [postbyte_register],al |
pop cx bx edx |
mov al,ah |
call operand_autodetect |
call store_instruction |
jmp instruction_assembled |
bt_mem_imm: |
xor al,al |
xchg al,[operand_size] |
push eax |
lods byte [esi] |
call get_size_operator |
cmp al,'(' |
jne invalid_operand |
mov al,[operand_size] |
or al,al |
jz bt_mem_imm_size_ok |
cmp al,1 |
jne invalid_operand_size |
bt_mem_imm_size_ok: |
call get_byte_value |
mov byte [value],al |
pop eax |
or al,al |
jz bt_mem_imm_nosize |
call operand_autodetect |
bt_mem_imm_store: |
pop cx bx edx |
mov [extended_code],0BAh |
call store_instruction_with_imm8 |
jmp instruction_assembled |
bt_mem_imm_nosize: |
cmp [error_line],0 |
jne bt_mem_imm_store |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],operand_size_not_specified |
jmp bt_mem_imm_store |
bt_reg: |
lods byte [esi] |
call convert_register |
mov bl,al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
cmp byte [esi],'(' |
je bt_reg_imm |
cmp byte [esi],11h |
jne bt_reg_reg |
cmp byte [esi+2],'(' |
je bt_reg_imm |
bt_reg_reg: |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
mov [postbyte_register],al |
mov al,ah |
call operand_autodetect |
call store_nomem_instruction |
jmp instruction_assembled |
bt_reg_imm: |
xor al,al |
xchg al,[operand_size] |
push eax |
lods byte [esi] |
call get_size_operator |
cmp al,'(' |
jne invalid_operand |
mov al,[operand_size] |
or al,al |
jz bt_reg_imm_size_ok |
cmp al,1 |
jne invalid_operand_size |
bt_reg_imm_size_ok: |
call get_byte_value |
mov byte [value],al |
pop eax |
call operand_autodetect |
bt_reg_imm_store: |
mov [extended_code],0BAh |
call store_nomem_instruction |
mov al,byte [value] |
stos byte [edi] |
jmp instruction_assembled |
bs_instruction: |
mov [extended_code],al |
mov [base_code],0Fh |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
mov [postbyte_register],al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je bs_reg_reg |
cmp al,'[' |
jne invalid_argument |
call get_address |
mov al,[operand_size] |
call operand_autodetect |
call store_instruction |
jmp instruction_assembled |
bs_reg_reg: |
lods byte [esi] |
call convert_register |
mov bl,al |
mov al,ah |
call operand_autodetect |
call store_nomem_instruction |
jmp instruction_assembled |
imul_instruction: |
mov [base_code],0F6h |
mov [postbyte_register],5 |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je imul_reg |
cmp al,'[' |
jne invalid_operand |
imul_mem: |
call get_address |
mov al,[operand_size] |
cmp al,1 |
je imul_mem_8bit |
jb imul_mem_nosize |
call operand_autodetect |
inc [base_code] |
call store_instruction |
jmp instruction_assembled |
imul_mem_nosize: |
cmp [error_line],0 |
jne imul_mem_8bit |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],operand_size_not_specified |
imul_mem_8bit: |
call store_instruction |
jmp instruction_assembled |
imul_reg: |
lods byte [esi] |
call convert_register |
cmp byte [esi],',' |
je imul_reg_ |
mov bl,al |
mov al,ah |
cmp al,1 |
je imul_reg_8bit |
call operand_autodetect |
inc [base_code] |
call store_nomem_instruction |
jmp instruction_assembled |
imul_reg_8bit: |
call store_nomem_instruction |
jmp instruction_assembled |
imul_reg_: |
mov [postbyte_register],al |
inc esi |
cmp byte [esi],'(' |
je imul_reg_imm |
cmp byte [esi],11h |
jne imul_reg_noimm |
cmp byte [esi+2],'(' |
je imul_reg_imm |
imul_reg_noimm: |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je imul_reg_reg |
cmp al,'[' |
jne invalid_operand |
imul_reg_mem: |
call get_address |
push edx bx cx |
cmp byte [esi],',' |
je imul_reg_mem_imm |
mov al,[operand_size] |
call operand_autodetect |
pop cx bx edx |
mov [base_code],0Fh |
mov [extended_code],0AFh |
call store_instruction |
jmp instruction_assembled |
imul_reg_mem_imm: |
inc esi |
lods byte [esi] |
call get_size_operator |
cmp al,'(' |
jne invalid_operand |
mov al,[operand_size] |
cmp al,2 |
je imul_reg_mem_imm_16bit |
cmp al,4 |
je imul_reg_mem_imm_32bit |
cmp al,8 |
je imul_reg_mem_imm_64bit |
jmp invalid_operand_size |
imul_reg_mem_imm_16bit: |
call operand_16bit |
call get_word_value |
mov word [value],ax |
cmp [value_type],0 |
jne imul_reg_mem_imm_16bit_store |
cmp [size_declared],0 |
jne imul_reg_mem_imm_16bit_store |
cmp ax,-80h |
jl imul_reg_mem_imm_16bit_store |
cmp ax,80h |
jl imul_reg_mem_imm_8bit_store |
imul_reg_mem_imm_16bit_store: |
pop cx bx edx |
mov [base_code],69h |
call store_instruction_with_imm16 |
jmp instruction_assembled |
imul_reg_mem_imm_32bit: |
call operand_32bit |
call get_dword_value |
imul_reg_mem_imm_32bit_ok: |
mov dword [value],eax |
cmp [value_type],0 |
jne imul_reg_mem_imm_32bit_store |
cmp [size_declared],0 |
jne imul_reg_mem_imm_32bit_store |
cmp eax,-80h |
jl imul_reg_mem_imm_32bit_store |
cmp eax,80h |
jl imul_reg_mem_imm_8bit_store |
imul_reg_mem_imm_32bit_store: |
pop cx bx edx |
mov [base_code],69h |
call store_instruction_with_imm32 |
jmp instruction_assembled |
imul_reg_mem_imm_64bit: |
cmp [size_declared],0 |
jne long_immediate_not_encodable |
call operand_64bit |
call get_simm32 |
cmp [value_type],4 |
jae long_immediate_not_encodable |
jmp imul_reg_mem_imm_32bit_ok |
imul_reg_mem_imm_8bit_store: |
pop cx bx edx |
mov [base_code],6Bh |
call store_instruction_with_imm8 |
jmp instruction_assembled |
imul_reg_imm: |
mov bl,[postbyte_register] |
dec esi |
jmp imul_reg_reg_imm |
imul_reg_reg: |
lods byte [esi] |
call convert_register |
mov bl,al |
cmp byte [esi],',' |
je imul_reg_reg_imm |
mov al,ah |
call operand_autodetect |
mov [base_code],0Fh |
mov [extended_code],0AFh |
call store_nomem_instruction |
jmp instruction_assembled |
imul_reg_reg_imm: |
inc esi |
lods byte [esi] |
call get_size_operator |
cmp al,'(' |
jne invalid_operand |
mov al,[operand_size] |
cmp al,2 |
je imul_reg_reg_imm_16bit |
cmp al,4 |
je imul_reg_reg_imm_32bit |
cmp al,8 |
je imul_reg_reg_imm_64bit |
jmp invalid_operand_size |
imul_reg_reg_imm_16bit: |
call operand_16bit |
push ebx |
call get_word_value |
pop ebx |
mov dx,ax |
cmp [value_type],0 |
jne imul_reg_reg_imm_16bit_store |
cmp [size_declared],0 |
jne imul_reg_reg_imm_16bit_store |
cmp ax,-80h |
jl imul_reg_reg_imm_16bit_store |
cmp ax,80h |
jl imul_reg_reg_imm_8bit_store |
imul_reg_reg_imm_16bit_store: |
mov [base_code],69h |
call store_nomem_instruction |
mov ax,dx |
call mark_relocation |
stos word [edi] |
jmp instruction_assembled |
imul_reg_reg_imm_32bit: |
call operand_32bit |
push ebx |
call get_dword_value |
imul_reg_reg_imm_32bit_ok: |
pop ebx |
mov edx,eax |
cmp [value_type],0 |
jne imul_reg_reg_imm_32bit_store |
cmp [size_declared],0 |
jne imul_reg_reg_imm_32bit_store |
cmp eax,-80h |
jl imul_reg_reg_imm_32bit_store |
cmp eax,80h |
jl imul_reg_reg_imm_8bit_store |
imul_reg_reg_imm_32bit_store: |
mov [base_code],69h |
call store_nomem_instruction |
mov eax,edx |
call mark_relocation |
stos dword [edi] |
jmp instruction_assembled |
imul_reg_reg_imm_64bit: |
cmp [size_declared],0 |
jne long_immediate_not_encodable |
call operand_64bit |
push ebx |
call get_simm32 |
cmp [value_type],4 |
jae long_immediate_not_encodable |
jmp imul_reg_reg_imm_32bit_ok |
imul_reg_reg_imm_8bit_store: |
mov [base_code],6Bh |
call store_nomem_instruction |
mov al,dl |
stos byte [edi] |
jmp instruction_assembled |
in_instruction: |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
or al,al |
jnz invalid_operand |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
mov al,ah |
push eax |
mov [operand_size],0 |
lods byte [esi] |
call get_size_operator |
cmp al,'(' |
je in_imm |
cmp al,10h |
je in_reg |
jmp invalid_operand |
in_reg: |
lods byte [esi] |
cmp al,22h |
jne invalid_operand |
pop eax |
cmp al,1 |
je in_al_dx |
cmp al,2 |
je in_ax_dx |
cmp al,4 |
je in_eax_dx |
jmp invalid_operand_size |
in_al_dx: |
mov al,0ECh |
stos byte [edi] |
jmp instruction_assembled |
in_ax_dx: |
call operand_16bit |
mov [base_code],0EDh |
call store_instruction_code |
jmp instruction_assembled |
in_eax_dx: |
call operand_32bit |
mov [base_code],0EDh |
call store_instruction_code |
jmp instruction_assembled |
in_imm: |
mov al,[operand_size] |
or al,al |
jz in_imm_size_ok |
cmp al,1 |
jne invalid_operand_size |
in_imm_size_ok: |
call get_byte_value |
mov dl,al |
pop eax |
cmp al,1 |
je in_al_imm |
cmp al,2 |
je in_ax_imm |
cmp al,4 |
je in_eax_imm |
jmp invalid_operand_size |
in_al_imm: |
mov al,0E4h |
stos byte [edi] |
mov al,dl |
stos byte [edi] |
jmp instruction_assembled |
in_ax_imm: |
call operand_16bit |
mov [base_code],0E5h |
call store_instruction_code |
mov al,dl |
stos byte [edi] |
jmp instruction_assembled |
in_eax_imm: |
call operand_32bit |
mov [base_code],0E5h |
call store_instruction_code |
mov al,dl |
stos byte [edi] |
jmp instruction_assembled |
out_instruction: |
lods byte [esi] |
call get_size_operator |
cmp al,'(' |
je out_imm |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
cmp al,22h |
jne invalid_operand |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
mov [operand_size],0 |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
or al,al |
jnz invalid_operand |
mov al,ah |
cmp al,1 |
je out_dx_al |
cmp al,2 |
je out_dx_ax |
cmp al,4 |
je out_dx_eax |
jmp invalid_operand_size |
out_dx_al: |
mov al,0EEh |
stos byte [edi] |
jmp instruction_assembled |
out_dx_ax: |
call operand_16bit |
mov [base_code],0EFh |
call store_instruction_code |
jmp instruction_assembled |
out_dx_eax: |
call operand_32bit |
mov [base_code],0EFh |
call store_instruction_code |
jmp instruction_assembled |
out_imm: |
mov al,[operand_size] |
or al,al |
jz out_imm_size_ok |
cmp al,1 |
jne invalid_operand_size |
out_imm_size_ok: |
call get_byte_value |
mov dl,al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
mov [operand_size],0 |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
or al,al |
jnz invalid_operand |
mov al,ah |
cmp al,1 |
je out_imm_al |
cmp al,2 |
je out_imm_ax |
cmp al,4 |
je out_imm_eax |
jmp invalid_operand_size |
out_imm_al: |
mov al,0E6h |
stos byte [edi] |
mov al,dl |
stos byte [edi] |
jmp instruction_assembled |
out_imm_ax: |
call operand_16bit |
mov [base_code],0E7h |
call store_instruction_code |
mov al,dl |
stos byte [edi] |
jmp instruction_assembled |
out_imm_eax: |
call operand_32bit |
mov [base_code],0E7h |
call store_instruction_code |
mov al,dl |
stos byte [edi] |
jmp instruction_assembled |
conditional_jump: |
mov [base_code],al |
lods byte [esi] |
call get_jump_operator |
cmp [jump_type],2 |
je invalid_operand |
call get_size_operator |
cmp al,'(' |
jne invalid_operand |
cmp byte [esi],'.' |
je invalid_value |
call get_relative_offset |
sub eax,2 |
jo jump_out_of_range |
cmp [next_pass_needed],0 |
jne conditional_jump_value_ok |
cmp [value_type],1 |
je invalid_use_of_symbol |
ja conditional_jump_32bit |
conditional_jump_value_ok: |
mov bl,[operand_size] |
cmp bl,1 |
je conditional_jump_8bit |
cmp bl,2 |
je conditional_jump_16bit |
cmp bl,4 |
je conditional_jump_32bit |
or bl,bl |
jnz invalid_operand_size |
cmp eax,80h |
jb conditional_jump_8bit |
cmp eax,-80h |
jae conditional_jump_8bit |
cmp [code_type],16 |
je conditional_jump_16bit |
conditional_jump_32bit: |
sub eax,2 |
jo jump_out_of_range |
mov edx,eax |
mov ecx,edi |
call operand_32bit |
mov al,[base_code] |
add al,10h |
mov [extended_code],al |
mov [base_code],0Fh |
call store_instruction_code |
mov eax,edi |
sub eax,ecx |
sub edx,eax |
jo jump_out_of_range |
mov eax,edx |
call mark_relocation |
stos dword [edi] |
jmp instruction_assembled |
conditional_jump_16bit: |
mov edx,eax |
mov ecx,edi |
call operand_16bit |
mov al,[base_code] |
add al,10h |
mov [extended_code],al |
mov [base_code],0Fh |
call store_instruction_code |
mov eax,edi |
sub eax,ecx |
sub edx,eax |
jo jump_out_of_range |
mov eax,edx |
stos word [edi] |
cmp eax,10000h |
jge jump_out_of_range |
cmp eax,-10000h |
jl jump_out_of_range |
jmp instruction_assembled |
conditional_jump_8bit: |
mov edx,eax |
mov ah,al |
mov al,[base_code] |
stos word [edi] |
cmp edx,80h |
jge jump_out_of_range |
cmp edx,-80h |
jl jump_out_of_range |
jmp instruction_assembled |
jump_out_of_range: |
cmp [error_line],0 |
jne instruction_assembled |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],relative_jump_out_of_range |
jmp instruction_assembled |
loop_instruction_16bit: |
cmp [code_type],64 |
je illegal_instruction |
mov dl,al |
call address_16bit_prefix |
mov al,dl |
jmp loop_instruction |
loop_instruction_32bit: |
mov dl,al |
call address_32bit_prefix |
mov al,dl |
jmp loop_instruction |
loop_instruction_64bit: |
cmp [code_type],64 |
jne illegal_instruction |
loop_instruction: |
mov [base_code],al |
lods byte [esi] |
call get_jump_operator |
cmp [jump_type],2 |
je invalid_operand |
call get_size_operator |
cmp al,'(' |
jne invalid_operand |
cmp byte [esi],'.' |
je invalid_value |
call get_relative_offset |
cmp [next_pass_needed],0 |
jne loop_value_ok |
cmp [value_type],0 |
jne invalid_use_of_symbol |
loop_value_ok: |
mov bl,[operand_size] |
cmp bl,1 |
je loop_8bit |
or bl,bl |
jnz invalid_operand_size |
loop_8bit: |
sub eax,2 |
jo jump_out_of_range |
mov edx,eax |
mov al,[base_code] |
stos byte [edi] |
mov al,dl |
stos byte [edi] |
cmp edx,80h |
jge jump_out_of_range |
cmp edx,-80h |
jl jump_out_of_range |
jmp instruction_assembled |
call_instruction: |
mov [postbyte_register],10b |
mov [base_code],0E8h |
mov [extended_code],9Ah |
jmp process_jmp |
jmp_instruction: |
mov [postbyte_register],100b |
mov [base_code],0E9h |
mov [extended_code],0EAh |
process_jmp: |
lods byte [esi] |
call get_jump_operator |
call get_size_operator |
cmp al,'(' |
je jmp_imm |
mov [base_code],0FFh |
cmp al,10h |
je jmp_reg |
cmp al,'[' |
jne invalid_operand |
jmp_mem: |
call get_address |
mov edx,eax |
mov al,[operand_size] |
or al,al |
jz jmp_mem_size_not_specified |
cmp al,2 |
je jmp_mem_16bit |
cmp al,4 |
je jmp_mem_32bit |
cmp al,6 |
je jmp_mem_48bit |
cmp al,8 |
je jmp_mem_64bit |
cmp al,10 |
je jmp_mem_80bit |
jmp invalid_operand_size |
jmp_mem_size_not_specified: |
cmp [jump_type],2 |
je jmp_mem_far |
cmp [jump_type],1 |
je jmp_mem_near |
cmp [error_line],0 |
jne jmp_mem_near |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],operand_size_not_specified |
jmp_mem_near: |
cmp [code_type],16 |
je jmp_mem_16bit |
cmp [code_type],32 |
je jmp_mem_near_32bit |
jmp_mem_64bit: |
cmp [jump_type],2 |
je invalid_operand_size |
cmp [code_type],64 |
jne illegal_instruction |
call store_instruction |
jmp instruction_assembled |
jmp_mem_far: |
cmp [code_type],16 |
je jmp_mem_far_32bit |
jmp_mem_48bit: |
call operand_32bit |
jmp_mem_far_store: |
cmp [jump_type],1 |
je invalid_operand_size |
inc [postbyte_register] |
call store_instruction |
jmp instruction_assembled |
jmp_mem_80bit: |
call operand_64bit |
jmp jmp_mem_far_store |
jmp_mem_far_32bit: |
call operand_16bit |
jmp jmp_mem_far_store |
jmp_mem_32bit: |
cmp [jump_type],2 |
je jmp_mem_far_32bit |
cmp [jump_type],1 |
je jmp_mem_near_32bit |
cmp [code_type],16 |
je jmp_mem_far_32bit |
jmp_mem_near_32bit: |
cmp [code_type],64 |
je illegal_instruction |
call operand_32bit |
call store_instruction |
jmp instruction_assembled |
jmp_mem_16bit: |
cmp [jump_type],2 |
je invalid_operand_size |
call operand_16bit |
call store_instruction |
jmp instruction_assembled |
jmp_reg: |
cmp [jump_type],2 |
je invalid_operand |
lods byte [esi] |
call convert_register |
mov bl,al |
mov al,ah |
cmp al,2 |
je jmp_reg_16bit |
cmp al,4 |
je jmp_reg_32bit |
cmp al,8 |
jne invalid_operand_size |
jmp_reg_64bit: |
cmp [code_type],64 |
jne illegal_instruction |
call store_nomem_instruction |
jmp instruction_assembled |
jmp_reg_32bit: |
cmp [code_type],64 |
je illegal_instruction |
call store_nomem_instruction |
jmp instruction_assembled |
jmp_reg_16bit: |
call operand_16bit |
call store_nomem_instruction |
jmp instruction_assembled |
jmp_imm: |
cmp byte [esi],'.' |
je invalid_value |
mov ebx,esi |
dec esi |
call skip_symbol |
xchg esi,ebx |
cmp byte [ebx],':' |
je jmp_far |
call get_relative_offset |
cmp [jump_type],2 |
je invalid_operand |
sub eax,2 |
jo jump_out_of_range |
cmp [next_pass_needed],0 |
jne jmp_value_ok |
cmp [value_type],1 |
je invalid_use_of_symbol |
ja jmp_32bit |
jmp_value_ok: |
mov bl,[operand_size] |
cmp bl,1 |
je jmp_8bit |
cmp bl,2 |
je jmp_16bit |
cmp bl,4 |
je jmp_32bit |
or bl,bl |
jnz invalid_operand_size |
cmp [base_code],0E9h |
jne jmp_no8bit |
cmp eax,80h |
jb jmp_8bit |
cmp eax,-80h |
jae jmp_8bit |
jmp_no8bit: |
cmp [code_type],16 |
je jmp_16bit |
jmp_32bit: |
test [operand_size],not 4 |
jnz invalid_operand_size |
sub eax,2 |
jo jump_out_of_range |
mov edx,eax |
mov ecx,edi |
call operand_32bit |
call store_instruction_code |
mov eax,edi |
sub eax,ecx |
sub edx,eax |
jo jump_out_of_range |
mov eax,edx |
call mark_relocation |
stos dword [edi] |
jmp instruction_assembled |
jmp_16bit: |
mov edx,eax |
mov ecx,edi |
call operand_16bit |
call store_instruction_code |
mov eax,edi |
sub eax,ecx |
sub edx,eax |
jo jump_out_of_range |
mov eax,edx |
stos word [edi] |
cmp eax,10000h |
jge jump_out_of_range |
cmp eax,-10000h |
jl jump_out_of_range |
jmp instruction_assembled |
jmp_8bit: |
cmp [base_code],0E9h |
jne invalid_operand_size |
mov edx,eax |
mov ah,al |
mov al,0EBh |
stos word [edi] |
cmp edx,80h |
jge jump_out_of_range |
cmp edx,-80h |
jl jump_out_of_range |
jmp instruction_assembled |
jmp_far: |
cmp [jump_type],1 |
je invalid_operand |
cmp [code_type],64 |
je illegal_instruction |
mov al,[extended_code] |
mov [base_code],al |
call get_word_value |
push eax |
inc esi |
lods byte [esi] |
cmp al,'(' |
jne invalid_operand |
mov al,[value_type] |
push eax [symbol_identifier] |
cmp byte [esi],'.' |
je invalid_value |
mov al,[operand_size] |
cmp al,4 |
je jmp_far_16bit |
cmp al,6 |
je jmp_far_32bit |
or al,al |
jnz invalid_operand_size |
cmp [code_type],16 |
jne jmp_far_32bit |
jmp_far_16bit: |
call get_word_value |
mov ebx,eax |
call operand_16bit |
call store_instruction_code |
mov ax,bx |
call mark_relocation |
stos word [edi] |
jmp_far_segment: |
pop [symbol_identifier] eax |
mov [value_type],al |
pop eax |
call mark_relocation |
stos word [edi] |
jmp instruction_assembled |
jmp_far_32bit: |
call get_dword_value |
mov ebx,eax |
call operand_32bit |
call store_instruction_code |
mov eax,ebx |
call mark_relocation |
stos dword [edi] |
jmp jmp_far_segment |
movs_instruction: |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
or eax,eax |
jnz invalid_address |
or bl,ch |
jnz invalid_address |
cmp [segment_register],1 |
ja invalid_address |
push ebx |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
pop edx |
or eax,eax |
jnz invalid_address |
or bl,ch |
jnz invalid_address |
mov al,dh |
mov ah,bh |
shr al,4 |
shr ah,4 |
cmp al,ah |
jne address_sizes_do_not_agree |
and bh,111b |
and dh,111b |
cmp bh,6 |
jne invalid_address |
cmp dh,7 |
jne invalid_address |
cmp al,2 |
je movs_address_16bit |
cmp al,4 |
je movs_address_32bit |
cmp [code_type],64 |
jne invalid_address_size |
jmp movs_store |
movs_address_32bit: |
call address_32bit_prefix |
jmp movs_store |
movs_address_16bit: |
cmp [code_type],64 |
je invalid_address_size |
call address_16bit_prefix |
movs_store: |
cmp [segment_register],4 |
je movs_segment_ok |
call store_segment_prefix |
movs_segment_ok: |
mov al,0A4h |
mov bl,[operand_size] |
cmp bl,1 |
je simple_instruction |
inc al |
cmp bl,2 |
je simple_instruction_16bit |
cmp bl,4 |
je simple_instruction_32bit |
cmp bl,8 |
je simple_instruction_64bit |
or bl,bl |
jz operand_size_not_specified |
jmp invalid_operand_size |
lods_instruction: |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
or eax,eax |
jnz invalid_address |
or bl,ch |
jnz invalid_address |
cmp bh,26h |
je lods_address_16bit |
cmp bh,46h |
je lods_address_32bit |
cmp bh,86h |
jne invalid_address |
cmp [code_type],64 |
jne invalid_address_size |
jmp lods_store |
lods_address_32bit: |
call address_32bit_prefix |
jmp lods_store |
lods_address_16bit: |
cmp [code_type],64 |
je invalid_address_size |
call address_16bit_prefix |
lods_store: |
cmp [segment_register],4 |
je lods_segment_ok |
call store_segment_prefix |
lods_segment_ok: |
mov al,0ACh |
mov bl,[operand_size] |
cmp bl,1 |
je simple_instruction |
inc al |
cmp bl,2 |
je simple_instruction_16bit |
cmp bl,4 |
je simple_instruction_32bit |
cmp bl,8 |
je simple_instruction_64bit |
or bl,bl |
jz operand_size_not_specified |
jmp invalid_operand_size |
stos_instruction: |
mov [base_code],al |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
or eax,eax |
jnz invalid_address |
or bl,ch |
jnz invalid_address |
cmp bh,27h |
je stos_address_16bit |
cmp bh,47h |
je stos_address_32bit |
cmp bh,87h |
jne invalid_address |
cmp [code_type],64 |
jne invalid_address_size |
jmp stos_store |
stos_address_32bit: |
call address_32bit_prefix |
jmp stos_store |
stos_address_16bit: |
cmp [code_type],64 |
je invalid_address_size |
call address_16bit_prefix |
stos_store: |
cmp [segment_register],1 |
ja invalid_address |
mov al,[base_code] |
mov bl,[operand_size] |
cmp bl,1 |
je simple_instruction |
inc al |
cmp bl,2 |
je simple_instruction_16bit |
cmp bl,4 |
je simple_instruction_32bit |
cmp bl,8 |
je simple_instruction_64bit |
or bl,bl |
jz operand_size_not_specified |
jmp invalid_operand_size |
cmps_instruction: |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
or eax,eax |
jnz invalid_address |
or bl,ch |
jnz invalid_address |
mov al,[segment_register] |
push ax bx |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
or eax,eax |
jnz invalid_address |
or bl,ch |
jnz invalid_address |
pop dx ax |
cmp [segment_register],1 |
ja invalid_address |
mov [segment_register],al |
mov al,dh |
mov ah,bh |
shr al,4 |
shr ah,4 |
cmp al,ah |
jne address_sizes_do_not_agree |
and bh,111b |
and dh,111b |
cmp bh,7 |
jne invalid_address |
cmp dh,6 |
jne invalid_address |
cmp al,2 |
je cmps_address_16bit |
cmp al,4 |
je cmps_address_32bit |
cmp [code_type],64 |
jne invalid_address_size |
jmp cmps_store |
cmps_address_32bit: |
call address_32bit_prefix |
jmp cmps_store |
cmps_address_16bit: |
cmp [code_type],64 |
je invalid_address_size |
call address_16bit_prefix |
cmps_store: |
cmp [segment_register],4 |
je cmps_segment_ok |
call store_segment_prefix |
cmps_segment_ok: |
mov al,0A6h |
mov bl,[operand_size] |
cmp bl,1 |
je simple_instruction |
inc al |
cmp bl,2 |
je simple_instruction_16bit |
cmp bl,4 |
je simple_instruction_32bit |
cmp bl,8 |
je simple_instruction_64bit |
or bl,bl |
jz operand_size_not_specified |
jmp invalid_operand_size |
ins_instruction: |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
or eax,eax |
jnz invalid_address |
or bl,ch |
jnz invalid_address |
cmp bh,27h |
je ins_address_16bit |
cmp bh,47h |
je ins_address_32bit |
cmp bh,87h |
jne invalid_address |
cmp [code_type],64 |
jne invalid_address_size |
jmp ins_store |
ins_address_32bit: |
call address_32bit_prefix |
jmp ins_store |
ins_address_16bit: |
cmp [code_type],64 |
je invalid_address_size |
call address_16bit_prefix |
ins_store: |
cmp [segment_register],1 |
ja invalid_address |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
cmp al,22h |
jne invalid_operand |
mov al,6Ch |
mov bl,[operand_size] |
cmp bl,1 |
je simple_instruction |
inc al |
cmp bl,2 |
je simple_instruction_16bit |
cmp bl,4 |
je simple_instruction_32bit |
or bl,bl |
jz operand_size_not_specified |
jmp invalid_operand_size |
outs_instruction: |
lods byte [esi] |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
cmp al,22h |
jne invalid_operand |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
or eax,eax |
jnz invalid_address |
or bl,ch |
jnz invalid_address |
cmp bh,26h |
je outs_address_16bit |
cmp bh,46h |
je outs_address_32bit |
cmp bh,86h |
jne invalid_address |
cmp [code_type],64 |
jne invalid_address_size |
jmp outs_store |
outs_address_32bit: |
call address_32bit_prefix |
jmp outs_store |
outs_address_16bit: |
cmp [code_type],64 |
je invalid_address_size |
call address_16bit_prefix |
outs_store: |
cmp [segment_register],4 |
je outs_segment_ok |
call store_segment_prefix |
outs_segment_ok: |
mov al,6Eh |
mov bl,[operand_size] |
cmp bl,1 |
je simple_instruction |
inc al |
cmp bl,2 |
je simple_instruction_16bit |
cmp bl,4 |
je simple_instruction_32bit |
or bl,bl |
jz operand_size_not_specified |
jmp invalid_operand_size |
xlat_instruction: |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
or eax,eax |
jnz invalid_address |
or bl,ch |
jnz invalid_address |
cmp bh,23h |
je xlat_address_16bit |
cmp bh,43h |
je xlat_address_32bit |
cmp bh,83h |
jne invalid_address |
cmp [code_type],64 |
jne invalid_address_size |
jmp xlat_store |
xlat_address_32bit: |
call address_32bit_prefix |
jmp xlat_store |
xlat_address_16bit: |
cmp [code_type],64 |
je invalid_address_size |
call address_16bit_prefix |
xlat_store: |
call store_segment_prefix_if_necessary |
mov al,0D7h |
cmp [operand_size],1 |
jbe simple_instruction |
jmp invalid_operand_size |
pm_word_instruction: |
mov ah,al |
shr ah,4 |
and al,111b |
mov [base_code],0Fh |
mov [extended_code],ah |
mov [postbyte_register],al |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je pm_reg |
pm_mem: |
cmp al,'[' |
jne invalid_operand |
call get_address |
mov al,[operand_size] |
cmp al,2 |
je pm_mem_store |
or al,al |
jnz invalid_operand_size |
pm_mem_store: |
call store_instruction |
jmp instruction_assembled |
pm_reg: |
lods byte [esi] |
call convert_register |
mov bl,al |
cmp ah,2 |
jne invalid_operand_size |
call store_nomem_instruction |
jmp instruction_assembled |
pm_store_word_instruction: |
mov ah,al |
shr ah,4 |
and al,111b |
mov [base_code],0Fh |
mov [extended_code],ah |
mov [postbyte_register],al |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne pm_mem |
lods byte [esi] |
call convert_register |
mov bl,al |
mov al,ah |
call operand_autodetect |
call store_nomem_instruction |
jmp instruction_assembled |
lgdt_instruction: |
mov [base_code],0Fh |
mov [extended_code],1 |
mov [postbyte_register],al |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
mov al,[operand_size] |
cmp al,6 |
je lgdt_mem_48bit |
cmp al,10 |
je lgdt_mem_80bit |
or al,al |
jnz invalid_operand_size |
cmp [code_type],64 |
je lgdt_mem_80bit |
lgdt_mem_48bit: |
cmp [code_type],64 |
je illegal_instruction |
call store_instruction |
jmp instruction_assembled |
lgdt_mem_80bit: |
cmp [code_type],64 |
jne illegal_instruction |
call store_instruction |
jmp instruction_assembled |
lar_instruction: |
mov [extended_code],al |
mov [base_code],0Fh |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
mov [postbyte_register],al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
xor al,al |
xchg al,[operand_size] |
call operand_autodetect |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je lar_reg_reg |
cmp al,'[' |
jne invalid_operand |
call get_address |
mov al,[operand_size] |
or al,al |
jz lar_reg_mem |
cmp al,2 |
jne invalid_operand_size |
lar_reg_mem: |
call store_instruction |
jmp instruction_assembled |
lar_reg_reg: |
lods byte [esi] |
call convert_register |
cmp ah,2 |
jne invalid_operand_size |
mov bl,al |
call store_nomem_instruction |
jmp instruction_assembled |
invlpg_instruction: |
mov [base_code],0Fh |
mov [extended_code],1 |
mov [postbyte_register],7 |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
call store_instruction |
jmp instruction_assembled |
swapgs_instruction: |
mov [base_code],0Fh |
mov [extended_code],1 |
mov [postbyte_register],7 |
mov bl,al |
call store_nomem_instruction |
jmp instruction_assembled |
basic_486_instruction: |
mov [base_code],0Fh |
mov [extended_code],al |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je basic_486_reg |
cmp al,'[' |
jne invalid_operand |
call get_address |
push edx bx cx |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
mov [postbyte_register],al |
pop cx bx edx |
mov al,ah |
cmp al,1 |
je basic_486_mem_reg_8bit |
call operand_autodetect |
inc [extended_code] |
basic_486_mem_reg_8bit: |
call store_instruction |
jmp instruction_assembled |
basic_486_reg: |
lods byte [esi] |
call convert_register |
mov [postbyte_register],al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
mov bl,[postbyte_register] |
mov [postbyte_register],al |
mov al,ah |
cmp al,1 |
je basic_486_reg_reg_8bit |
call operand_autodetect |
inc [extended_code] |
basic_486_reg_reg_8bit: |
call store_nomem_instruction |
jmp instruction_assembled |
bswap_instruction: |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
add al,0C8h |
mov [extended_code],al |
mov [base_code],0Fh |
cmp ah,8 |
je bswap_reg64 |
cmp ah,4 |
jne invalid_operand_size |
call operand_32bit |
call store_instruction_code |
jmp instruction_assembled |
bswap_reg64: |
call operand_64bit |
call store_instruction_code |
jmp instruction_assembled |
cmpxchgx_instruction: |
mov [base_code],0Fh |
mov [extended_code],0C7h |
mov [postbyte_register],al |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
mov ah,1 |
xchg [postbyte_register],ah |
mov al,[operand_size] |
or al,al |
jz cmpxchgx_size_ok |
cmp al,ah |
jne invalid_operand_size |
cmpxchgx_size_ok: |
cmp ah,16 |
jne cmpxchgx_store |
call operand_64bit |
cmpxchgx_store: |
call store_instruction |
jmp instruction_assembled |
basic_fpu_instruction: |
mov [postbyte_register],al |
mov [base_code],0D8h |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je basic_fpu_streg |
cmp al,'[' |
je basic_fpu_mem |
dec esi |
mov ah,[postbyte_register] |
cmp ah,2 |
jb invalid_operand |
cmp ah,3 |
ja invalid_operand |
mov bl,1 |
call store_nomem_instruction |
jmp instruction_assembled |
basic_fpu_mem: |
call get_address |
mov al,[operand_size] |
cmp al,4 |
je basic_fpu_mem_32bit |
cmp al,8 |
je basic_fpu_mem_64bit |
or al,al |
jnz invalid_operand_size |
cmp [error_line],0 |
jne basic_fpu_mem_32bit |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],operand_size_not_specified |
basic_fpu_mem_32bit: |
call store_instruction |
jmp instruction_assembled |
basic_fpu_mem_64bit: |
mov [base_code],0DCh |
call store_instruction |
jmp instruction_assembled |
basic_fpu_streg: |
lods byte [esi] |
call convert_fpu_register |
mov bl,al |
mov ah,[postbyte_register] |
cmp ah,2 |
je basic_fpu_single_streg |
cmp ah,3 |
je basic_fpu_single_streg |
or al,al |
jz basic_fpu_st0 |
test ah,110b |
jz basic_fpu_streg_st0 |
xor [postbyte_register],1 |
basic_fpu_streg_st0: |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_fpu_register |
or al,al |
jnz invalid_operand |
mov [base_code],0DCh |
call store_nomem_instruction |
jmp instruction_assembled |
basic_fpu_st0: |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_fpu_register |
mov bl,al |
basic_fpu_single_streg: |
mov [base_code],0D8h |
call store_nomem_instruction |
jmp instruction_assembled |
simple_fpu_instruction: |
mov ah,al |
or ah,11000000b |
mov al,0D9h |
stos word [edi] |
jmp instruction_assembled |
fi_instruction: |
mov [postbyte_register],al |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
mov al,[operand_size] |
cmp al,2 |
je fi_mem_16bit |
cmp al,4 |
je fi_mem_32bit |
or al,al |
jnz invalid_operand_size |
cmp [error_line],0 |
jne fi_mem_32bit |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],operand_size_not_specified |
fi_mem_32bit: |
mov [base_code],0DAh |
call store_instruction |
jmp instruction_assembled |
fi_mem_16bit: |
mov [base_code],0DEh |
call store_instruction |
jmp instruction_assembled |
fld_instruction: |
mov [postbyte_register],al |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je fld_streg |
cmp al,'[' |
jne invalid_operand |
call get_address |
mov al,[operand_size] |
cmp al,4 |
je fld_mem_32bit |
cmp al,8 |
je fld_mem_64bit |
cmp al,10 |
je fld_mem_80bit |
or al,al |
jnz invalid_operand_size |
cmp [error_line],0 |
jne fld_mem_32bit |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],operand_size_not_specified |
fld_mem_32bit: |
mov [base_code],0D9h |
call store_instruction |
jmp instruction_assembled |
fld_mem_64bit: |
mov [base_code],0DDh |
call store_instruction |
jmp instruction_assembled |
fld_mem_80bit: |
mov al,[postbyte_register] |
cmp al,0 |
je fld_mem_80bit_store |
dec [postbyte_register] |
cmp al,3 |
je fld_mem_80bit_store |
jmp invalid_operand_size |
fld_mem_80bit_store: |
add [postbyte_register],5 |
mov [base_code],0DBh |
call store_instruction |
jmp instruction_assembled |
fld_streg: |
lods byte [esi] |
call convert_fpu_register |
mov bl,al |
cmp [postbyte_register],2 |
jae fst_streg |
mov [base_code],0D9h |
call store_nomem_instruction |
jmp instruction_assembled |
fst_streg: |
mov [base_code],0DDh |
call store_nomem_instruction |
jmp instruction_assembled |
fild_instruction: |
mov [postbyte_register],al |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
mov al,[operand_size] |
cmp al,2 |
je fild_mem_16bit |
cmp al,4 |
je fild_mem_32bit |
cmp al,8 |
je fild_mem_64bit |
or al,al |
jnz invalid_operand_size |
cmp [error_line],0 |
jne fild_mem_32bit |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],operand_size_not_specified |
fild_mem_32bit: |
mov [base_code],0DBh |
call store_instruction |
jmp instruction_assembled |
fild_mem_16bit: |
mov [base_code],0DFh |
call store_instruction |
jmp instruction_assembled |
fild_mem_64bit: |
mov al,[postbyte_register] |
cmp al,1 |
je fisttp_64bit_store |
jb fild_mem_64bit_store |
dec [postbyte_register] |
cmp al,3 |
je fild_mem_64bit_store |
jmp invalid_operand_size |
fild_mem_64bit_store: |
add [postbyte_register],5 |
mov [base_code],0DFh |
call store_instruction |
jmp instruction_assembled |
fisttp_64bit_store: |
mov [base_code],0DDh |
call store_instruction |
jmp instruction_assembled |
fbld_instruction: |
mov [postbyte_register],al |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
mov al,[operand_size] |
or al,al |
jz fbld_mem_80bit |
cmp al,10 |
je fbld_mem_80bit |
jmp invalid_operand_size |
fbld_mem_80bit: |
mov [base_code],0DFh |
call store_instruction |
jmp instruction_assembled |
faddp_instruction: |
mov [postbyte_register],al |
mov [base_code],0DEh |
mov edx,esi |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je faddp_streg |
mov esi,edx |
mov bl,1 |
call store_nomem_instruction |
jmp instruction_assembled |
faddp_streg: |
lods byte [esi] |
call convert_fpu_register |
mov bl,al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_fpu_register |
or al,al |
jnz invalid_operand |
call store_nomem_instruction |
jmp instruction_assembled |
fcompp_instruction: |
mov ax,0D9DEh |
stos word [edi] |
jmp instruction_assembled |
fucompp_instruction: |
mov ax,0E9DAh |
stos word [edi] |
jmp instruction_assembled |
fxch_instruction: |
mov dx,01D9h |
jmp fpu_single_operand |
ffreep_instruction: |
mov dx,00DFh |
jmp fpu_single_operand |
ffree_instruction: |
mov dl,0DDh |
mov dh,al |
fpu_single_operand: |
mov ebx,esi |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je fpu_streg |
or dh,dh |
jz invalid_operand |
mov esi,ebx |
shl dh,3 |
or dh,11000001b |
mov ax,dx |
stos word [edi] |
jmp instruction_assembled |
fpu_streg: |
lods byte [esi] |
call convert_fpu_register |
shl dh,3 |
or dh,al |
or dh,11000000b |
mov ax,dx |
stos word [edi] |
jmp instruction_assembled |
fstenv_instruction: |
mov byte [edi],9Bh |
inc edi |
fldenv_instruction: |
mov [base_code],0D9h |
jmp fpu_mem |
fsave_instruction: |
mov byte [edi],9Bh |
inc edi |
fnsave_instruction: |
mov [base_code],0DDh |
fpu_mem: |
mov [postbyte_register],al |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
cmp [operand_size],0 |
jne invalid_operand_size |
call store_instruction |
jmp instruction_assembled |
fstcw_instruction: |
mov byte [edi],9Bh |
inc edi |
fldcw_instruction: |
mov [postbyte_register],al |
mov [base_code],0D9h |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
mov al,[operand_size] |
or al,al |
jz fldcw_mem_16bit |
cmp al,2 |
je fldcw_mem_16bit |
jmp invalid_operand_size |
fldcw_mem_16bit: |
call store_instruction |
jmp instruction_assembled |
fstsw_instruction: |
mov al,9Bh |
stos byte [edi] |
fnstsw_instruction: |
mov [base_code],0DDh |
mov [postbyte_register],7 |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je fstsw_reg |
cmp al,'[' |
jne invalid_operand |
call get_address |
mov al,[operand_size] |
or al,al |
jz fstsw_mem_16bit |
cmp al,2 |
je fstsw_mem_16bit |
jmp invalid_operand_size |
fstsw_mem_16bit: |
call store_instruction |
jmp instruction_assembled |
fstsw_reg: |
lods byte [esi] |
call convert_register |
cmp ax,0200h |
jne invalid_operand |
mov ax,0E0DFh |
stos word [edi] |
jmp instruction_assembled |
finit_instruction: |
mov byte [edi],9Bh |
inc edi |
fninit_instruction: |
mov ah,al |
mov al,0DBh |
stos word [edi] |
jmp instruction_assembled |
fcmov_instruction: |
mov dh,0DAh |
jmp fcomi_streg |
fcomi_instruction: |
mov dh,0DBh |
jmp fcomi_streg |
fcomip_instruction: |
mov dh,0DFh |
fcomi_streg: |
mov dl,al |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_fpu_register |
mov ah,al |
cmp byte [esi],',' |
je fcomi_st0_streg |
add ah,dl |
mov al,dh |
stos word [edi] |
jmp instruction_assembled |
fcomi_st0_streg: |
or ah,ah |
jnz invalid_operand |
inc esi |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_fpu_register |
mov ah,al |
add ah,dl |
mov al,dh |
stos word [edi] |
jmp instruction_assembled |
mmx_instruction: |
mov [base_code],0Fh |
mov [extended_code],al |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
call make_mmx_prefix |
mov [postbyte_register],al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je mmx_mmreg_mmreg |
cmp al,'[' |
jne invalid_operand |
mmx_mmreg_mem: |
call get_address |
call store_instruction |
jmp instruction_assembled |
mmx_mmreg_mmreg: |
lods byte [esi] |
call convert_mmx_register |
mov bl,al |
call store_nomem_instruction |
jmp instruction_assembled |
mmx_ps_instruction: |
mov [base_code],0Fh |
mov [extended_code],al |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
call make_mmx_prefix |
mov [postbyte_register],al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
mov [operand_size],0 |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je mmx_mmreg_mmreg |
cmp al,'(' |
je mmx_ps_mmreg_imm8 |
cmp al,'[' |
je mmx_mmreg_mem |
jmp invalid_operand |
mmx_ps_mmreg_imm8: |
call get_byte_value |
mov byte [value],al |
test [operand_size],not 1 |
jnz invalid_value |
mov bl,[extended_code] |
mov al,bl |
shr bl,4 |
and al,1111b |
add al,70h |
mov [extended_code],al |
sub bl,0Ch |
shl bl,1 |
xchg bl,[postbyte_register] |
call store_nomem_instruction |
mov al,byte [value] |
stos byte [edi] |
jmp instruction_assembled |
pextrw_instruction: |
mov [base_code],0Fh |
mov [extended_code],al |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
cmp ah,4 |
jnz invalid_operand_size |
mov [postbyte_register],al |
mov [operand_size],0 |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
mov bl,al |
call make_mmx_prefix |
cmp [extended_code],0C5h |
je mmx_nomem_imm8 |
call store_nomem_instruction |
jmp instruction_assembled |
mmx_imm8: |
push bx cx edx |
mov [operand_size],0 |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
test ah,not 1 |
jnz invalid_operand_size |
cmp al,'(' |
jne invalid_operand |
call get_byte_value |
mov byte [value],al |
pop edx cx bx |
call store_instruction_with_imm8 |
jmp instruction_assembled |
mmx_nomem_imm8: |
call store_nomem_instruction |
mov [operand_size],0 |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
test ah,not 1 |
jnz invalid_operand_size |
cmp al,'(' |
jne invalid_operand |
call get_byte_value |
stosb |
jmp instruction_assembled |
pinsrw_instruction: |
mov [extended_code],al |
mov [base_code],0Fh |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
call make_mmx_prefix |
mov [postbyte_register],al |
mov [operand_size],0 |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je pinsrw_mmreg_reg |
cmp al,'[' |
jne invalid_operand |
call get_address |
cmp [operand_size],0 |
je mmx_imm8 |
cmp [operand_size],2 |
jne invalid_operand_size |
jmp mmx_imm8 |
pinsrw_mmreg_reg: |
lods byte [esi] |
call convert_register |
cmp ah,4 |
jne invalid_operand_size |
mov bl,al |
jmp mmx_nomem_imm8 |
pshufw_instruction: |
mov [mmx_size],8 |
mov [operand_prefix],al |
jmp pshuf_instruction |
pshufd_instruction: |
mov [mmx_size],16 |
mov [operand_prefix],al |
pshuf_instruction: |
mov [base_code],0Fh |
mov [extended_code],70h |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
cmp ah,[mmx_size] |
jne invalid_operand_size |
mov [postbyte_register],al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je pshuf_mmreg_mmreg |
cmp al,'[' |
jne invalid_operand |
call get_address |
jmp mmx_imm8 |
pshuf_mmreg_mmreg: |
lods byte [esi] |
call convert_mmx_register |
mov bl,al |
jmp mmx_nomem_imm8 |
movd_instruction: |
mov [base_code],0Fh |
mov [extended_code],7Eh |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je movd_reg |
cmp al,'[' |
jne invalid_operand |
call get_address |
test [operand_size],not 4 |
jnz invalid_operand_size |
mov [operand_size],0 |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
call make_mmx_prefix |
mov [postbyte_register],al |
call store_instruction |
jmp instruction_assembled |
movd_reg: |
lods byte [esi] |
cmp al,0B0h |
jae movd_mmreg |
call convert_register |
cmp ah,4 |
jne invalid_operand_size |
mov [operand_size],0 |
mov bl,al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
mov [postbyte_register],al |
call make_mmx_prefix |
call store_nomem_instruction |
jmp instruction_assembled |
movd_mmreg: |
mov [extended_code],6Eh |
call convert_mmx_register |
call make_mmx_prefix |
mov [postbyte_register],al |
mov [operand_size],0 |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je movd_mmreg_reg |
cmp al,'[' |
jne invalid_operand |
call get_address |
test [operand_size],not 4 |
jnz invalid_operand_size |
call store_instruction |
jmp instruction_assembled |
movd_mmreg_reg: |
lods byte [esi] |
call convert_register |
cmp ah,4 |
jne invalid_operand_size |
mov bl,al |
call store_nomem_instruction |
jmp instruction_assembled |
make_mmx_prefix: |
cmp [operand_size],16 |
jne no_mmx_prefix |
mov [operand_prefix],66h |
no_mmx_prefix: |
ret |
movq_instruction: |
mov [base_code],0Fh |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je movq_reg |
cmp al,'[' |
jne invalid_operand |
call get_address |
test [operand_size],not 8 |
jnz invalid_operand_size |
mov [operand_size],0 |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
mov [postbyte_register],al |
cmp ah,16 |
je movq_mem_xmmreg |
mov [extended_code],7Fh |
call store_instruction |
jmp instruction_assembled |
movq_mem_xmmreg: |
mov [extended_code],0D6h |
mov [operand_prefix],66h |
call store_instruction |
jmp instruction_assembled |
movq_reg: |
lods byte [esi] |
cmp al,0B0h |
jae movq_mmreg |
call convert_register |
cmp ah,8 |
jne invalid_operand_size |
mov [operand_size],0 |
mov bl,al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
mov [postbyte_register],al |
call make_mmx_prefix |
mov [extended_code],7Eh |
call operand_64bit |
call store_nomem_instruction |
jmp instruction_assembled |
movq_mmreg: |
call convert_mmx_register |
mov [postbyte_register],al |
mov [extended_code],6Fh |
cmp ah,16 |
jne movq_mmreg_ |
mov [extended_code],7Eh |
mov [operand_prefix],0F3h |
movq_mmreg_: |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
mov [operand_size],0 |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je movq_mmreg_reg |
call get_address |
test [operand_size],not 8 |
jnz invalid_operand_size |
call store_instruction |
jmp instruction_assembled |
movq_mmreg_reg: |
lods byte [esi] |
cmp al,0B0h |
jae movq_mmreg_mmreg |
mov [operand_size],0 |
call convert_register |
cmp ah,8 |
jne invalid_operand_size |
mov [extended_code],6Eh |
mov [operand_prefix],0 |
mov bl,al |
call make_mmx_prefix |
call operand_64bit |
call store_nomem_instruction |
jmp instruction_assembled |
movq_mmreg_mmreg: |
call convert_mmx_register |
mov bl,al |
call store_nomem_instruction |
jmp instruction_assembled |
movdq_instruction: |
mov [operand_prefix],al |
mov [base_code],0Fh |
mov [extended_code],6Fh |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je movdq_mmreg |
cmp al,'[' |
jne invalid_operand |
call get_address |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
cmp ah,16 |
jne invalid_operand_size |
mov [postbyte_register],al |
mov [extended_code],7Fh |
call store_instruction |
jmp instruction_assembled |
movdq_mmreg: |
lods byte [esi] |
call convert_mmx_register |
cmp ah,16 |
jne invalid_operand_size |
mov [postbyte_register],al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je movdq_mmreg_mmreg |
cmp al,'[' |
jne invalid_operand |
call get_address |
call store_instruction |
jmp instruction_assembled |
movdq_mmreg_mmreg: |
lods byte [esi] |
call convert_mmx_register |
cmp ah,16 |
jne invalid_operand_size |
mov bl,al |
call store_nomem_instruction |
jmp instruction_assembled |
lddqu_instruction: |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
cmp ah,16 |
jne invalid_operand_size |
push eax |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
pop eax |
mov [postbyte_register],al |
mov [operand_prefix],0F2h |
mov [base_code],0Fh |
mov [extended_code],0F0h |
call store_instruction |
jmp instruction_assembled |
movq2dq_instruction: |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
cmp ah,16 |
jne invalid_operand_size |
mov [postbyte_register],al |
mov [operand_size],0 |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
cmp ah,8 |
jne invalid_operand_size |
mov bl,al |
mov [operand_prefix],0F3h |
mov [base_code],0Fh |
mov [extended_code],0D6h |
call store_nomem_instruction |
jmp instruction_assembled |
movdq2q_instruction: |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
cmp ah,8 |
jne invalid_operand_size |
mov [postbyte_register],al |
mov [operand_size],0 |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
cmp ah,16 |
jne invalid_operand_size |
mov bl,al |
mov [operand_prefix],0F2h |
mov [base_code],0Fh |
mov [extended_code],0D6h |
call store_nomem_instruction |
jmp instruction_assembled |
sse_ps_instruction: |
mov [mmx_size],16 |
jmp sse_instruction |
sse_pd_instruction: |
mov [mmx_size],16 |
mov [operand_prefix],66h |
jmp sse_instruction |
sse_ss_instruction: |
mov [mmx_size],4 |
mov [operand_prefix],0F3h |
jmp sse_instruction |
sse_sd_instruction: |
mov [mmx_size],8 |
mov [operand_prefix],0F2h |
jmp sse_instruction |
comiss_instruction: |
mov [mmx_size],4 |
jmp sse_instruction |
comisd_instruction: |
mov [mmx_size],8 |
mov [operand_prefix],66h |
jmp sse_instruction |
cvtps2pd_instruction: |
mov [mmx_size],8 |
jmp sse_instruction |
cvtpd2dq_instruction: |
mov [mmx_size],16 |
mov [operand_prefix],0F2h |
jmp sse_instruction |
cvtdq2pd_instruction: |
mov [mmx_size],16 |
mov [operand_prefix],0F3h |
sse_instruction: |
mov [base_code],0Fh |
mov [extended_code],al |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
sse_xmmreg: |
lods byte [esi] |
call convert_mmx_register |
cmp ah,16 |
jne invalid_operand_size |
sse_reg: |
mov [postbyte_register],al |
mov [operand_size],0 |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je sse_xmmreg_xmmreg |
sse_reg_mem: |
cmp al,'[' |
jne invalid_operand |
call get_address |
cmp [operand_size],0 |
je sse_mem_size_ok |
mov al,[mmx_size] |
cmp [operand_size],al |
jne invalid_operand_size |
sse_mem_size_ok: |
cmp [extended_code],0C6h |
je mmx_imm8 |
call store_instruction |
jmp instruction_assembled |
sse_xmmreg_xmmreg: |
cmp [operand_prefix],66h |
jne sse_xmmreg_xmmreg_ok |
cmp [extended_code],12h |
je invalid_operand |
cmp [extended_code],16h |
je invalid_operand |
sse_xmmreg_xmmreg_ok: |
lods byte [esi] |
call convert_mmx_register |
cmp ah,16 |
jne invalid_operand_size |
mov bl,al |
cmp [extended_code],0C6h |
je mmx_nomem_imm8 |
call store_nomem_instruction |
jmp instruction_assembled |
ps_dq_instruction: |
mov [postbyte_register],al |
mov [operand_prefix],66h |
mov [base_code],0Fh |
mov [extended_code],73h |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
cmp ah,16 |
jne invalid_operand_size |
mov bl,al |
jmp mmx_nomem_imm8 |
movpd_instruction: |
mov [operand_prefix],66h |
movps_instruction: |
mov [base_code],0Fh |
mov [extended_code],al |
mov [mmx_size],16 |
jmp sse_mov_instruction |
movss_instruction: |
mov [mmx_size],4 |
mov [operand_prefix],0F3h |
jmp sse_movs |
movsd_instruction: |
mov al,0A5h |
mov ah,[esi] |
or ah,ah |
jz simple_instruction_32bit |
cmp ah,0Fh |
je simple_instruction_32bit |
mov [mmx_size],8 |
mov [operand_prefix],0F2h |
sse_movs: |
mov [base_code],0Fh |
mov [extended_code],10h |
jmp sse_mov_instruction |
sse_mov_instruction: |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je sse_xmmreg |
sse_mem: |
cmp al,'[' |
jne invalid_operand |
inc [extended_code] |
call get_address |
cmp [operand_size],0 |
je sse_mem_xmmreg |
mov al,[mmx_size] |
cmp [operand_size],al |
jne invalid_operand_size |
mov [operand_size],0 |
sse_mem_xmmreg: |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
cmp ah,16 |
jne invalid_operand_size |
mov [postbyte_register],al |
call store_instruction |
jmp instruction_assembled |
movlpd_instruction: |
mov [operand_prefix],66h |
movlps_instruction: |
mov [base_code],0Fh |
mov [extended_code],al |
mov [mmx_size],8 |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne sse_mem |
lods byte [esi] |
call convert_mmx_register |
cmp ah,16 |
jne invalid_operand_size |
mov [postbyte_register],al |
mov [operand_size],0 |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
jmp sse_reg_mem |
movhlps_instruction: |
mov [base_code],0Fh |
mov [extended_code],al |
mov [mmx_size],0 |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
cmp ah,16 |
jne invalid_operand_size |
mov [postbyte_register],al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je sse_xmmreg_xmmreg_ok |
jmp invalid_operand |
maskmovq_instruction: |
mov cl,8 |
jmp maskmov_instruction |
maskmovdqu_instruction: |
mov cl,16 |
mov [operand_prefix],66h |
maskmov_instruction: |
mov [base_code],0Fh |
mov [extended_code],0F7h |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
cmp ah,cl |
jne invalid_operand_size |
mov [postbyte_register],al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
mov bl,al |
call store_nomem_instruction |
jmp instruction_assembled |
movmskpd_instruction: |
mov [operand_prefix],66h |
movmskps_instruction: |
mov [base_code],0Fh |
mov [extended_code],50h |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
cmp ah,4 |
jne invalid_operand_size |
mov [operand_size],0 |
mov [postbyte_register],al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
cmp ah,16 |
jne invalid_operand_size |
mov bl,al |
call store_nomem_instruction |
jmp instruction_assembled |
cmppd_instruction: |
mov [operand_prefix],66h |
cmpps_instruction: |
mov [base_code],0Fh |
mov [extended_code],0C2h |
mov [mmx_size],16 |
mov byte [value],-1 |
jmp sse_cmp_instruction |
cmp_pd_instruction: |
mov [operand_prefix],66h |
cmp_ps_instruction: |
mov [base_code],0Fh |
mov [extended_code],0C2h |
mov [mmx_size],16 |
mov byte [value],al |
jmp sse_cmp_instruction |
cmpss_instruction: |
mov [mmx_size],4 |
mov [operand_prefix],0F3h |
jmp cmpsx_instruction |
cmpsd_instruction: |
mov al,0A7h |
mov ah,[esi] |
or ah,ah |
jz simple_instruction_32bit |
cmp ah,0Fh |
je simple_instruction_32bit |
mov [mmx_size],8 |
mov [operand_prefix],0F2h |
cmpsx_instruction: |
mov [base_code],0Fh |
mov [extended_code],0C2h |
mov byte [value],-1 |
jmp sse_cmp_instruction |
cmp_ss_instruction: |
mov [mmx_size],4 |
mov [operand_prefix],0F3h |
jmp cmp_sx_instruction |
cmp_sd_instruction: |
mov [mmx_size],8 |
mov [operand_prefix],0F2h |
cmp_sx_instruction: |
mov [base_code],0Fh |
mov [extended_code],0C2h |
mov byte [value],al |
sse_cmp_instruction: |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
cmp ah,16 |
jne invalid_operand_size |
mov [postbyte_register],al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
mov [operand_size],0 |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je sse_cmp_xmmreg_xmmreg |
cmp al,'[' |
jne invalid_operand |
call get_address |
mov al,[operand_size] |
or al,al |
jz sse_cmp_size_ok |
cmp al,[mmx_size] |
jne invalid_operand_size |
sse_cmp_size_ok: |
push bx cx edx |
call get_nextbyte |
pop edx cx bx |
call store_instruction_with_imm8 |
jmp instruction_assembled |
sse_cmp_xmmreg_xmmreg: |
lods byte [esi] |
call convert_mmx_register |
cmp ah,16 |
jne invalid_operand_size |
mov bl,al |
call store_nomem_instruction |
call get_nextbyte |
mov al,byte [value] |
stos byte [edi] |
jmp instruction_assembled |
get_nextbyte: |
cmp byte [value],-1 |
jne nextbyte_ok |
mov [operand_size],0 |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
test [operand_size],not 1 |
jnz invalid_value |
cmp al,'(' |
jne invalid_operand |
call get_byte_value |
cmp al,7 |
ja invalid_value |
mov byte [value],al |
nextbyte_ok: |
ret |
cvtpi2pd_instruction: |
mov [operand_prefix],66h |
cvtpi2ps_instruction: |
mov [base_code],0Fh |
mov [extended_code],al |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
cmp ah,16 |
jne invalid_operand_size |
mov [postbyte_register],al |
mov [operand_size],0 |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je cvtpi_xmmreg_xmmreg |
cmp al,'[' |
jne invalid_operand |
call get_address |
cmp [operand_size],0 |
je cvtpi_size_ok |
cmp [operand_size],8 |
jne invalid_operand_size |
cvtpi_size_ok: |
call store_instruction |
jmp instruction_assembled |
cvtpi_xmmreg_xmmreg: |
lods byte [esi] |
call convert_mmx_register |
cmp ah,8 |
jne invalid_operand_size |
mov bl,al |
call store_nomem_instruction |
jmp instruction_assembled |
cvtsi2ss_instruction: |
mov [operand_prefix],0F3h |
jmp cvtsi_instruction |
cvtsi2sd_instruction: |
mov [operand_prefix],0F2h |
cvtsi_instruction: |
mov [base_code],0Fh |
mov [extended_code],al |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
cmp ah,16 |
jne invalid_operand_size |
mov [postbyte_register],al |
mov [operand_size],0 |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je cvtsi_xmmreg_reg |
cmp al,'[' |
jne invalid_operand |
call get_address |
cmp [operand_size],0 |
je cvtsi_size_ok |
cmp [operand_size],4 |
jne invalid_operand_size |
cvtsi_size_ok: |
call store_instruction |
jmp instruction_assembled |
cvtsi_xmmreg_reg: |
lods byte [esi] |
call convert_register |
cmp ah,4 |
je cvtsi_xmmreg_reg_store |
cmp ah,8 |
jne invalid_operand_size |
call operand_64bit |
cvtsi_xmmreg_reg_store: |
mov bl,al |
call store_nomem_instruction |
jmp instruction_assembled |
cvtps2pi_instruction: |
mov [mmx_size],8 |
jmp cvtpd_instruction |
cvtpd2pi_instruction: |
mov [operand_prefix],66h |
mov [mmx_size],16 |
cvtpd_instruction: |
mov [base_code],0Fh |
mov [extended_code],al |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
cmp ah,8 |
jne invalid_operand_size |
mov [operand_size],0 |
jmp sse_reg |
cvtss2si_instruction: |
mov [operand_prefix],0F3h |
mov [mmx_size],4 |
jmp cvt2si_instruction |
cvtsd2si_instruction: |
mov [operand_prefix],0F2h |
mov [mmx_size],8 |
cvt2si_instruction: |
mov [extended_code],al |
mov [base_code],0Fh |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
mov [operand_size],0 |
cmp ah,4 |
je sse_reg |
cmp ah,8 |
jne invalid_operand_size |
call operand_64bit |
jmp sse_reg |
amd3dnow_instruction: |
mov [base_code],0Fh |
mov [extended_code],0Fh |
mov byte [value],al |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
cmp ah,8 |
jne invalid_operand_size |
mov [postbyte_register],al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
je amd3dnow_mmreg_mmreg |
cmp al,'[' |
jne invalid_operand |
call get_address |
call store_instruction_with_imm8 |
jmp instruction_assembled |
amd3dnow_mmreg_mmreg: |
lods byte [esi] |
call convert_mmx_register |
cmp ah,8 |
jne invalid_operand_size |
mov bl,al |
call store_nomem_instruction |
mov al,byte [value] |
stos byte [edi] |
jmp instruction_assembled |
fxsave_instruction: |
mov [extended_code],0AEh |
mov [base_code],0Fh |
mov [postbyte_register],al |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
mov ah,[operand_size] |
or ah,ah |
jz fxsave_size_ok |
mov al,[postbyte_register] |
cmp al,111b |
je clflush_size_check |
cmp al,10b |
jb invalid_operand_size |
cmp al,11b |
ja invalid_operand_size |
cmp ah,4 |
jne invalid_operand_size |
jmp fxsave_size_ok |
clflush_size_check: |
cmp ah,1 |
jne invalid_operand_size |
fxsave_size_ok: |
call store_instruction |
jmp instruction_assembled |
prefetch_instruction: |
mov [extended_code],18h |
prefetch_mem_8bit: |
mov [base_code],0Fh |
mov [postbyte_register],al |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
or ah,ah |
jz prefetch_size_ok |
cmp ah,1 |
jne invalid_operand_size |
prefetch_size_ok: |
call get_address |
call store_instruction |
jmp instruction_assembled |
amd_prefetch_instruction: |
mov [extended_code],0Dh |
jmp prefetch_mem_8bit |
fence_instruction: |
mov bl,al |
mov ax,0AE0Fh |
stos word [edi] |
mov al,bl |
stos byte [edi] |
jmp instruction_assembled |
pause_instruction: |
mov ax,90F3h |
stos word [edi] |
jmp instruction_assembled |
movntq_instruction: |
mov [mmx_size],8 |
jmp movnt_instruction |
movntps_instruction: |
mov [mmx_size],16 |
jmp movnt_instruction |
movntdq_instruction: |
mov [operand_prefix],66h |
mov [mmx_size],16 |
movnt_instruction: |
mov [extended_code],al |
mov [base_code],0Fh |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_mmx_register |
cmp ah,[mmx_size] |
jne invalid_operand_size |
mov [postbyte_register],al |
call store_instruction |
jmp instruction_assembled |
movnti_instruction: |
mov [base_code],0Fh |
mov [extended_code],al |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
cmp ah,4 |
je movnti_store |
cmp ah,8 |
jne invalid_operand_size |
call operand_64bit |
movnti_store: |
mov [postbyte_register],al |
call store_instruction |
jmp instruction_assembled |
monitor_instruction: |
mov [postbyte_register],al |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
cmp ax,0400h |
jne invalid_operand |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
cmp ax,0401h |
jne invalid_operand |
cmp [postbyte_register],0C8h |
jne monitor_instruction_store |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
cmp ax,0402h |
jne invalid_operand |
monitor_instruction_store: |
mov ax,010Fh |
stos word [edi] |
mov al,[postbyte_register] |
stos byte [edi] |
jmp instruction_assembled |
simple_vmx_instruction: |
mov ah,al |
mov al,0Fh |
stos byte [edi] |
mov al,1 |
stos word [edi] |
jmp instruction_assembled |
vmclear_instruction: |
mov [operand_prefix],66h |
jmp vmx_instruction |
vmxon_instruction: |
mov [operand_prefix],0F3h |
vmx_instruction: |
mov [postbyte_register],al |
mov [extended_code],0C7h |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
mov al,[operand_size] |
or al,al |
jz vmx_size_ok |
cmp al,8 |
jne invalid_operand_size |
vmx_size_ok: |
mov [base_code],0Fh |
call store_instruction |
jmp instruction_assembled |
vmread_instruction: |
mov [extended_code],78h |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
mov [postbyte_register],al |
vmread_check_size: |
cmp [code_type],64 |
je vmread_long |
cmp [operand_size],4 |
je vmx_size_ok |
jmp invalid_operand_size |
vmread_long: |
cmp [operand_size],8 |
je vmx_size_ok |
jmp invalid_operand_size |
vmwrite_instruction: |
mov [extended_code],79h |
lods byte [esi] |
call get_size_operator |
cmp al,10h |
jne invalid_operand |
lods byte [esi] |
call convert_register |
mov [postbyte_register],al |
lods byte [esi] |
cmp al,',' |
jne invalid_operand |
lods byte [esi] |
call get_size_operator |
cmp al,'[' |
jne invalid_operand |
call get_address |
jmp vmread_check_size |
convert_register: |
mov ah,al |
shr ah,4 |
and al,0Fh |
cmp ah,8 |
je match_register_size |
cmp ah,4 |
ja invalid_operand |
cmp ah,1 |
ja match_register_size |
cmp al,4 |
jb match_register_size |
or ah,ah |
jz high_byte_register |
or [rex_prefix],40h |
match_register_size: |
cmp ah,[operand_size] |
je register_size_ok |
cmp [operand_size],0 |
jne operand_sizes_do_not_match |
mov [operand_size],ah |
register_size_ok: |
ret |
high_byte_register: |
mov ah,1 |
or [rex_prefix],80h |
jmp match_register_size |
convert_fpu_register: |
mov ah,al |
shr ah,4 |
and al,111b |
cmp ah,10 |
jne invalid_operand |
jmp match_register_size |
convert_mmx_register: |
mov ah,al |
shr ah,4 |
cmp ah,0Ch |
je xmm_register |
ja invalid_operand |
and al,111b |
cmp ah,0Bh |
jne invalid_operand |
mov ah,8 |
jmp match_register_size |
xmm_register: |
and al,0Fh |
mov ah,16 |
cmp al,8 |
jb match_register_size |
cmp [code_type],64 |
jne invalid_operand |
jmp match_register_size |
get_size_operator: |
xor ah,ah |
cmp al,11h |
jne no_size_operator |
mov [size_declared],1 |
lods word [esi] |
xchg al,ah |
mov [size_override],1 |
cmp ah,[operand_size] |
je size_operator_ok |
cmp [operand_size],0 |
jne operand_sizes_do_not_match |
mov [operand_size],ah |
size_operator_ok: |
ret |
no_size_operator: |
mov [size_declared],0 |
cmp al,'[' |
jne size_operator_ok |
mov [size_override],0 |
ret |
get_jump_operator: |
mov [jump_type],0 |
cmp al,12h |
jne jump_operator_ok |
lods word [esi] |
mov [jump_type],al |
mov al,ah |
jump_operator_ok: |
ret |
get_address: |
mov [segment_register],0 |
mov [address_size],0 |
mov al,[code_type] |
shr al,3 |
mov [value_size],al |
mov al,[esi] |
and al,11110000b |
cmp al,60h |
jne get_size_prefix |
lods byte [esi] |
sub al,60h |
mov [segment_register],al |
mov al,[esi] |
and al,11110000b |
get_size_prefix: |
cmp al,70h |
jne address_size_prefix_ok |
lods byte [esi] |
sub al,70h |
cmp al,2 |
jb invalid_address_size |
cmp al,8 |
ja invalid_address_size |
mov [address_size],al |
mov [value_size],al |
address_size_prefix_ok: |
call calculate_address |
mov [address_high],edx |
mov edx,eax |
cmp [code_type],64 |
jne address_ok |
or bx,bx |
jnz address_ok |
test ch,0Fh |
jnz address_ok |
calculate_relative_address: |
call calculate_relative_offset |
mov [address_high],edx |
mov edx,[symbol_identifier] |
mov [address_symbol],edx |
mov edx,eax |
mov ch,[value_type] |
mov bx,0FF00h |
xor cl,cl |
address_ok: |
ret |
operand_16bit: |
cmp [code_type],16 |
je size_prefix_ok |
mov [operand_prefix],66h |
ret |
operand_32bit: |
cmp [code_type],16 |
jne size_prefix_ok |
mov [operand_prefix],66h |
size_prefix_ok: |
ret |
operand_64bit: |
cmp [code_type],64 |
jne invalid_operand_size |
or [rex_prefix],48h |
ret |
operand_autodetect: |
cmp al,2 |
je operand_16bit |
cmp al,4 |
je operand_32bit |
cmp al,8 |
je operand_64bit |
jmp invalid_operand_size |
store_segment_prefix_if_necessary: |
mov al,[segment_register] |
or al,al |
jz segment_prefix_ok |
cmp al,3 |
je ss_prefix |
cmp al,4 |
ja segment_prefix_386 |
jb segment_prefix_86 |
cmp bl,25h |
je segment_prefix_86 |
cmp bh,25h |
je segment_prefix_86 |
cmp bh,45h |
je segment_prefix_86 |
cmp bh,44h |
je segment_prefix_86 |
ret |
ss_prefix: |
cmp bl,25h |
je segment_prefix_ok |
cmp bh,25h |
je segment_prefix_ok |
cmp bh,45h |
je segment_prefix_ok |
cmp bh,44h |
je segment_prefix_ok |
jmp segment_prefix_86 |
store_segment_prefix: |
mov al,[segment_register] |
or al,al |
jz segment_prefix_ok |
cmp al,5 |
jae segment_prefix_386 |
segment_prefix_86: |
dec al |
shl al,3 |
add al,26h |
stos byte [edi] |
jmp segment_prefix_ok |
segment_prefix_386: |
add al,64h-5 |
stos byte [edi] |
segment_prefix_ok: |
ret |
store_instruction_code: |
mov al,[operand_prefix] |
or al,al |
jz operand_prefix_ok |
stos byte [edi] |
operand_prefix_ok: |
mov al,[rex_prefix] |
test al,40h |
jz rex_prefix_ok |
cmp [code_type],64 |
jne invalid_operand |
test al,0B0h |
jnz prefix_conflict |
stos byte [edi] |
rex_prefix_ok: |
mov al,[base_code] |
stos byte [edi] |
cmp al,0Fh |
jne instruction_code_ok |
store_extended_code: |
mov al,[extended_code] |
stos byte [edi] |
instruction_code_ok: |
ret |
store_nomem_instruction: |
test [postbyte_register],1000b |
jz nomem_reg_code_ok |
or [rex_prefix],44h |
and [postbyte_register],111b |
nomem_reg_code_ok: |
test bl,1000b |
jz nomem_rm_code_ok |
or [rex_prefix],41h |
and bl,111b |
nomem_rm_code_ok: |
call store_instruction_code |
mov al,[postbyte_register] |
shl al,3 |
or al,bl |
or al,11000000b |
stos byte [edi] |
ret |
store_instruction: |
mov [current_offset],edi |
test [postbyte_register],1000b |
jz reg_code_ok |
or [rex_prefix],44h |
and [postbyte_register],111b |
reg_code_ok: |
call store_segment_prefix_if_necessary |
or bx,bx |
jz address_immediate |
cmp bx,0F000h |
je address_rip_based |
cmp bx,0FF00h |
je address_relative |
mov al,bl |
or al,bh |
and al,11110000b |
cmp al,80h |
je postbyte_64bit |
cmp al,40h |
je postbyte_32bit |
cmp al,20h |
jne invalid_address |
cmp [code_type],64 |
je invalid_address_size |
call address_16bit_prefix |
call store_instruction_code |
cmp bx,2326h |
je address_bx_si |
cmp bx,2623h |
je address_bx_si |
cmp bx,2327h |
je address_bx_di |
cmp bx,2723h |
je address_bx_di |
cmp bx,2526h |
je address_bp_si |
cmp bx,2625h |
je address_bp_si |
cmp bx,2527h |
je address_bp_di |
cmp bx,2725h |
je address_bp_di |
cmp bx,2600h |
je address_si |
cmp bx,2700h |
je address_di |
cmp bx,2300h |
je address_bx |
cmp bx,2500h |
je address_bp |
jmp invalid_address |
address_bx_si: |
xor al,al |
jmp postbyte_16bit |
address_bx_di: |
mov al,1 |
jmp postbyte_16bit |
address_bp_si: |
mov al,10b |
jmp postbyte_16bit |
address_bp_di: |
mov al,11b |
jmp postbyte_16bit |
address_si: |
mov al,100b |
jmp postbyte_16bit |
address_di: |
mov al,101b |
jmp postbyte_16bit |
address_bx: |
mov al,111b |
jmp postbyte_16bit |
address_bp: |
mov al,110b |
postbyte_16bit: |
test ch,22h |
jnz address_16bit_value |
or ch,ch |
jnz address_sizes_do_not_agree |
cmp edx,10000h |
jge value_out_of_range |
cmp edx,-8000h |
jl value_out_of_range |
or dx,dx |
jz address |
cmp dx,80h |
jb address_8bit_value |
cmp dx,-80h |
jae address_8bit_value |
address_16bit_value: |
or al,10000000b |
mov cl,[postbyte_register] |
shl cl,3 |
or al,cl |
stos byte [edi] |
mov eax,edx |
stos word [edi] |
ret |
address_8bit_value: |
or al,01000000b |
mov cl,[postbyte_register] |
shl cl,3 |
or al,cl |
stos byte [edi] |
mov al,dl |
stos byte [edi] |
cmp dx,80h |
jge value_out_of_range |
cmp dx,-80h |
jl value_out_of_range |
ret |
address: |
cmp al,110b |
je address_8bit_value |
mov cl,[postbyte_register] |
shl cl,3 |
or al,cl |
stos byte [edi] |
ret |
postbyte_32bit: |
call address_32bit_prefix |
call store_instruction_code |
cmp bl,44h |
je invalid_address |
or cl,cl |
jz only_base_register |
jmp base_and_index |
postbyte_64bit: |
cmp [code_type],64 |
jne invalid_address_size |
test bh,1000b |
jz base_code_ok |
or [rex_prefix],41h |
base_code_ok: |
test bl,1000b |
jz index_code_ok |
or [rex_prefix],42h |
index_code_ok: |
call store_instruction_code |
or cl,cl |
jz only_base_register |
base_and_index: |
mov al,100b |
xor ah,ah |
cmp cl,1 |
je scale_ok |
cmp cl,2 |
je scale_1 |
cmp cl,4 |
je scale_2 |
or ah,11000000b |
jmp scale_ok |
scale_2: |
or ah,10000000b |
jmp scale_ok |
scale_1: |
or ah,01000000b |
scale_ok: |
or bh,bh |
jz only_index_register |
and bl,111b |
shl bl,3 |
or ah,bl |
and bh,111b |
or ah,bh |
test ch,44h |
jnz sib_address_32bit_value |
or ch,ch |
jnz address_sizes_do_not_agree |
cmp bh,5 |
je address_value |
or edx,edx |
jz sib_address |
address_value: |
cmp edx,80h |
jb sib_address_8bit_value |
cmp edx,-80h |
jae sib_address_8bit_value |
sib_address_32bit_value: |
or al,10000000b |
mov cl,[postbyte_register] |
shl cl,3 |
or al,cl |
stos word [edi] |
jmp store_address_32bit_value |
sib_address_8bit_value: |
or al,01000000b |
mov cl,[postbyte_register] |
shl cl,3 |
or al,cl |
stos word [edi] |
mov al,dl |
stos byte [edi] |
cmp edx,80h |
jge value_out_of_range |
cmp edx,-80h |
jl value_out_of_range |
ret |
sib_address: |
mov cl,[postbyte_register] |
shl cl,3 |
or al,cl |
stos word [edi] |
ret |
only_index_register: |
or ah,101b |
and bl,111b |
shl bl,3 |
or ah,bl |
mov cl,[postbyte_register] |
shl cl,3 |
or al,cl |
stos word [edi] |
test ch,44h |
jnz store_address_32bit_value |
or ch,ch |
jnz invalid_address_size |
jmp store_address_32bit_value |
zero_index_register: |
mov bl,4 |
mov cl,1 |
jmp base_and_index |
only_base_register: |
mov al,bh |
and al,111b |
cmp al,4 |
je zero_index_register |
test ch,44h |
jnz simple_address_32bit_value |
or ch,ch |
jnz address_sizes_do_not_agree |
or edx,edx |
jz simple_address |
cmp edx,80h |
jb simple_address_8bit_value |
cmp edx,-80h |
jae simple_address_8bit_value |
simple_address_32bit_value: |
or al,10000000b |
mov cl,[postbyte_register] |
shl cl,3 |
or al,cl |
stos byte [edi] |
jmp store_address_32bit_value |
simple_address_8bit_value: |
or al,01000000b |
mov cl,[postbyte_register] |
shl cl,3 |
or al,cl |
stos byte [edi] |
mov al,dl |
stos byte [edi] |
cmp edx,80h |
jge value_out_of_range |
cmp edx,-80h |
jl value_out_of_range |
ret |
simple_address: |
cmp al,5 |
je simple_address_8bit_value |
mov cl,[postbyte_register] |
shl cl,3 |
or al,cl |
stos byte [edi] |
ret |
address_immediate: |
cmp [code_type],64 |
je address_immediate_sib |
test ch,44h |
jnz address_immediate_32bit |
test ch,22h |
jnz address_immediate_16bit |
or ch,ch |
jnz invalid_address_size |
cmp [code_type],16 |
je addressing_16bit |
address_immediate_32bit: |
call address_32bit_prefix |
call store_instruction_code |
store_immediate_address: |
mov al,101b |
mov cl,[postbyte_register] |
shl cl,3 |
or al,cl |
stos byte [edi] |
store_address_32bit_value: |
test ch,0F0h |
jz address_32bit_relocation_ok |
mov al,2 |
xchg [value_type],al |
mov ebx,[address_symbol] |
xchg ebx,[symbol_identifier] |
call mark_relocation |
mov [value_type],al |
mov [symbol_identifier],ebx |
address_32bit_relocation_ok: |
mov eax,edx |
stos dword [edi] |
ret |
store_address_64bit_value: |
test ch,0F0h |
jz address_64bit_relocation_ok |
mov al,4 |
xchg [value_type],al |
mov ebx,[address_symbol] |
xchg ebx,[symbol_identifier] |
call mark_relocation |
mov [value_type],al |
mov [symbol_identifier],ebx |
address_64bit_relocation_ok: |
mov eax,edx |
stos dword [edi] |
mov eax,[address_high] |
stos dword [edi] |
ret |
address_immediate_sib: |
test ch,not 44h |
jnz invalid_address_size |
call address_32bit_prefix |
call store_instruction_code |
mov al,100b |
mov ah,100101b |
mov cl,[postbyte_register] |
shl cl,3 |
or al,cl |
stos word [edi] |
jmp store_address_32bit_value |
address_rip_based: |
cmp [code_type],64 |
jne invalid_address |
call store_instruction_code |
jmp store_immediate_address |
address_relative: |
call store_instruction_code |
movzx eax,[immediate_size] |
add eax,edi |
sub eax,[current_offset] |
add eax,5 |
sub edx,eax |
jo value_out_of_range |
mov al,101b |
mov cl,[postbyte_register] |
shl cl,3 |
or al,cl |
stos byte [edi] |
xchg [value_type],ch |
mov ebx,[address_symbol] |
xchg ebx,[symbol_identifier] |
mov eax,edx |
call mark_relocation |
mov [value_type],ch |
mov [symbol_identifier],ebx |
stos dword [edi] |
ret |
addressing_16bit: |
cmp edx,10000h |
jge address_immediate_32bit |
cmp edx,-8000h |
jl address_immediate_32bit |
movzx edx,dx |
address_immediate_16bit: |
call address_16bit_prefix |
call store_instruction_code |
mov al,110b |
mov cl,[postbyte_register] |
shl cl,3 |
or al,cl |
stos byte [edi] |
mov eax,edx |
stos word [edi] |
cmp edx,10000h |
jge value_out_of_range |
cmp edx,-8000h |
jl value_out_of_range |
ret |
address_16bit_prefix: |
cmp [code_type],16 |
je instruction_prefix_ok |
mov al,67h |
stos byte [edi] |
ret |
address_32bit_prefix: |
cmp [code_type],32 |
je instruction_prefix_ok |
mov al,67h |
stos byte [edi] |
instruction_prefix_ok: |
ret |
store_instruction_with_imm8: |
mov [immediate_size],1 |
call store_instruction |
mov al,byte [value] |
stos byte [edi] |
ret |
store_instruction_with_imm16: |
mov [immediate_size],2 |
call store_instruction |
mov ax,word [value] |
call mark_relocation |
stos word [edi] |
ret |
store_instruction_with_imm32: |
mov [immediate_size],4 |
call store_instruction |
mov eax,dword [value] |
call mark_relocation |
stos dword [edi] |
ret |
address_registers: |
db 2,'bp',0,25h |
db 2,'bx',0,23h |
db 2,'di',0,27h |
db 3,'eax',0,40h |
db 3,'ebp',0,45h |
db 3,'ebx',0,43h |
db 3,'ecx',0,41h |
db 3,'edi',0,47h |
db 3,'edx',0,42h |
db 3,'esi',0,46h |
db 3,'esp',0,44h |
db 3,'r10',10h,8Ah |
db 3,'r11',10h,8Bh |
db 3,'r12',10h,8Ch |
db 3,'r13',10h,8Dh |
db 3,'r14',10h,8Eh |
db 3,'r15',10h,8Fh |
db 2,'r8',10h,88h |
db 2,'r9',10h,89h |
db 3,'rax',0,80h |
db 3,'rbp',0,85h |
db 3,'rbx',0,83h |
db 3,'rcx',0,81h |
db 3,'rdi',0,87h |
db 3,'rdx',0,82h |
db 3,'rip',0,0F0h |
db 3,'rsi',0,86h |
db 3,'rsp',0,84h |
db 2,'si',0,26h |
db 0 |
address_sizes: |
db 4,'byte',0,1 |
db 5,'dword',0,4 |
db 5,'qword',0,8 |
db 4,'word',0,2 |
db 0 |
symbols: |
db 2,'ah',10h,04h |
db 2,'al',10h,10h |
db 2,'ax',10h,20h |
db 2,'bh',10h,07h |
db 2,'bl',10h,13h |
db 2,'bp',10h,25h |
db 3,'bpl',10h,15h |
db 2,'bx',10h,23h |
db 4,'byte',11h,1 |
db 2,'ch',10h,05h |
db 2,'cl',10h,11h |
db 3,'cr0',10h,50h |
db 3,'cr1',10h,51h |
db 3,'cr2',10h,52h |
db 3,'cr3',10h,53h |
db 3,'cr4',10h,54h |
db 3,'cr5',10h,55h |
db 3,'cr6',10h,56h |
db 3,'cr7',10h,57h |
db 3,'cr8',10h,58h |
db 3,'cr9',10h,59h |
db 4,'cr10',10h,5Ah |
db 4,'cr11',10h,5Bh |
db 4,'cr12',10h,5Ch |
db 4,'cr13',10h,5Dh |
db 4,'cr14',10h,5Eh |
db 4,'cr15',10h,5Fh |
db 2,'cs',10h,62h |
db 2,'cx',10h,21h |
db 2,'dh',10h,06h |
db 2,'di',10h,27h |
db 3,'dil',10h,17h |
db 2,'dl',10h,12h |
db 6,'dqword',11h,16 |
db 3,'dr0',10h,70h |
db 3,'dr1',10h,71h |
db 3,'dr2',10h,72h |
db 3,'dr3',10h,73h |
db 3,'dr4',10h,74h |
db 3,'dr5',10h,75h |
db 3,'dr6',10h,76h |
db 3,'dr7',10h,77h |
db 3,'dr8',10h,78h |
db 3,'dr9',10h,79h |
db 4,'dr10',10h,7Ah |
db 4,'dr11',10h,7Bh |
db 4,'dr12',10h,7Ch |
db 4,'dr13',10h,7Dh |
db 4,'dr14',10h,7Eh |
db 4,'dr15',10h,7Fh |
db 2,'ds',10h,64h |
db 5,'dword',11h,4 |
db 2,'dx',10h,22h |
db 3,'eax',10h,40h |
db 3,'ebp',10h,45h |
db 3,'ebx',10h,43h |
db 3,'ecx',10h,41h |
db 3,'edi',10h,47h |
db 3,'edx',10h,42h |
db 2,'es',10h,61h |
db 3,'esi',10h,46h |
db 3,'esp',10h,44h |
db 3,'far',12h,2 |
db 2,'fs',10h,65h |
db 5,'fword',11h,6 |
db 2,'gs',10h,66h |
db 3,'mm0',10h,0B0h |
db 3,'mm1',10h,0B1h |
db 3,'mm2',10h,0B2h |
db 3,'mm3',10h,0B3h |
db 3,'mm4',10h,0B4h |
db 3,'mm5',10h,0B5h |
db 3,'mm6',10h,0B6h |
db 3,'mm7',10h,0B7h |
db 4,'near',12h,1 |
db 5,'pword',11h,6 |
db 5,'qword',11h,8 |
db 3,'r10',10h,8Ah |
db 4,'r10b',10h,1Ah |
db 4,'r10d',10h,4Ah |
db 4,'r10w',10h,2Ah |
db 3,'r11',10h,8Bh |
db 4,'r11b',10h,1Bh |
db 4,'r11d',10h,4Bh |
db 4,'r11w',10h,2Bh |
db 3,'r12',10h,8Ch |
db 4,'r12b',10h,1Ch |
db 4,'r12d',10h,4Ch |
db 4,'r12w',10h,2Ch |
db 3,'r13',10h,8Dh |
db 4,'r13b',10h,1Dh |
db 4,'r13d',10h,4Dh |
db 4,'r13w',10h,2Dh |
db 3,'r14',10h,8Eh |
db 4,'r14b',10h,1Eh |
db 4,'r14d',10h,4Eh |
db 4,'r14w',10h,2Eh |
db 3,'r15',10h,8Fh |
db 4,'r15b',10h,1Fh |
db 4,'r15d',10h,4Fh |
db 4,'r15w',10h,2Fh |
db 2,'r8',10h,88h |
db 3,'r8b',10h,18h |
db 3,'r8d',10h,48h |
db 3,'r8w',10h,28h |
db 2,'r9',10h,89h |
db 3,'r9b',10h,19h |
db 3,'r9d',10h,49h |
db 3,'r9w',10h,29h |
db 3,'rax',10h,80h |
db 3,'rbp',10h,85h |
db 3,'rbx',10h,83h |
db 3,'rcx',10h,81h |
db 3,'rdi',10h,87h |
db 3,'rdx',10h,82h |
db 3,'rsi',10h,86h |
db 3,'rsp',10h,84h |
db 2,'si',10h,26h |
db 3,'sil',10h,16h |
db 2,'sp',10h,24h |
db 3,'spl',10h,14h |
db 2,'ss',10h,63h |
db 2,'st',10h,0A0h |
db 3,'st0',10h,0A0h |
db 3,'st1',10h,0A1h |
db 3,'st2',10h,0A2h |
db 3,'st3',10h,0A3h |
db 3,'st4',10h,0A4h |
db 3,'st5',10h,0A5h |
db 3,'st6',10h,0A6h |
db 3,'st7',10h,0A7h |
db 5,'tbyte',11h,0Ah |
db 3,'tr0',10h,90h |
db 3,'tr1',10h,91h |
db 3,'tr2',10h,92h |
db 3,'tr3',10h,93h |
db 3,'tr4',10h,94h |
db 3,'tr5',10h,95h |
db 3,'tr6',10h,96h |
db 3,'tr7',10h,97h |
db 5,'tword',11h,0Ah |
db 5,'use16',13h,16 |
db 5,'use32',13h,32 |
db 5,'use64',13h,64 |
db 4,'word',11h,2 |
db 4,'xmm0',10h,0C0h |
db 4,'xmm1',10h,0C1h |
db 5,'xmm10',10h,0CAh |
db 5,'xmm11',10h,0CBh |
db 5,'xmm12',10h,0CCh |
db 5,'xmm13',10h,0CDh |
db 5,'xmm14',10h,0CEh |
db 5,'xmm15',10h,0CFh |
db 4,'xmm2',10h,0C2h |
db 4,'xmm3',10h,0C3h |
db 4,'xmm4',10h,0C4h |
db 4,'xmm5',10h,0C5h |
db 4,'xmm6',10h,0C6h |
db 4,'xmm7',10h,0C7h |
db 4,'xmm8',10h,0C8h |
db 4,'xmm9',10h,0C9h |
db 0 |
data_handlers: |
dw data_bytes-assembler |
dw data_file-assembler |
dw reserve_bytes-assembler |
dw data_words-assembler |
dw data_unicode-assembler |
dw reserve_words-assembler |
dw data_dwords-assembler |
dw reserve_dwords-assembler |
dw data_pwords-assembler |
dw reserve_pwords-assembler |
dw data_qwords-assembler |
dw reserve_qwords-assembler |
dw data_twords-assembler |
dw reserve_twords-assembler |
data_directives: |
db 2,'db',1,0 |
db 2,'dd',4,6 |
db 2,'df',6,8 |
db 2,'dp',6,8 |
db 2,'dq',8,10 |
db 2,'dt',10,12 |
db 2,'du',2,4 |
db 2,'dw',2,3 |
db 4,'file',1,1 |
db 2,'rb',1,2 |
db 2,'rd',4,7 |
db 2,'rf',6,9 |
db 2,'rp',6,9 |
db 2,'rq',8,11 |
db 2,'rt',10,13 |
db 2,'rw',2,5 |
db 0 |
instructions: |
dw instructions_2-instructions |
dw instructions_3-instructions |
dw instructions_4-instructions |
dw instructions_5-instructions |
dw instructions_6-instructions |
dw instructions_7-instructions |
dw instructions_8-instructions |
dw instructions_9-instructions |
dw instructions_10-instructions |
dw instructions_11-instructions |
instructions_2: |
db 'bt',4 |
dw bt_instruction-assembler |
db 'if',0 |
dw if_directive-assembler |
db 'in',0 |
dw in_instruction-assembler |
db 'ja',77h |
dw conditional_jump-assembler |
db 'jb',72h |
dw conditional_jump-assembler |
db 'jc',72h |
dw conditional_jump-assembler |
db 'je',74h |
dw conditional_jump-assembler |
db 'jg',7Fh |
dw conditional_jump-assembler |
db 'jl',7Ch |
dw conditional_jump-assembler |
db 'jo',70h |
dw conditional_jump-assembler |
db 'jp',7Ah |
dw conditional_jump-assembler |
db 'js',78h |
dw conditional_jump-assembler |
db 'jz',74h |
dw conditional_jump-assembler |
db 'or',08h |
dw basic_instruction-assembler |
db 0 |
instructions_3: |
db 'aaa',37h |
dw simple_instruction_except64-assembler |
db 'aad',0D5h |
dw aa_instruction-assembler |
db 'aam',0D4h |
dw aa_instruction-assembler |
db 'aas',3Fh |
dw simple_instruction_except64-assembler |
db 'adc',10h |
dw basic_instruction-assembler |
db 'add',00h |
dw basic_instruction-assembler |
db 'and',20h |
dw basic_instruction-assembler |
db 'bsf',0BCh |
dw bs_instruction-assembler |
db 'bsr',0BDh |
dw bs_instruction-assembler |
db 'btc',7 |
dw bt_instruction-assembler |
db 'btr',6 |
dw bt_instruction-assembler |
db 'bts',5 |
dw bt_instruction-assembler |
db 'cbw',98h |
dw simple_instruction_16bit-assembler |
db 'cdq',99h |
dw simple_instruction_32bit-assembler |
db 'clc',0F8h |
dw simple_instruction-assembler |
db 'cld',0FCh |
dw simple_instruction-assembler |
db 'cli',0FAh |
dw simple_instruction-assembler |
db 'cmc',0F5h |
dw simple_instruction-assembler |
db 'cmp',38h |
dw basic_instruction-assembler |
db 'cqo',99h |
dw simple_instruction_64bit-assembler |
db 'cwd',99h |
dw simple_instruction_16bit-assembler |
db 'daa',27h |
dw simple_instruction_except64-assembler |
db 'das',2Fh |
dw simple_instruction_except64-assembler |
db 'dec',1 |
dw inc_instruction-assembler |
db 'div',6 |
dw single_operand_instruction-assembler |
db 'end',0 |
dw end_directive-assembler |
db 'fld',0 |
dw fld_instruction-assembler |
db 'fst',2 |
dw fld_instruction-assembler |
db 'hlt',0F4h |
dw simple_instruction-assembler |
db 'inc',0 |
dw inc_instruction-assembler |
db 'ins',6Ch |
dw ins_instruction-assembler |
db 'int',0CDh |
dw int_instruction-assembler |
db 'jae',73h |
dw conditional_jump-assembler |
db 'jbe',76h |
dw conditional_jump-assembler |
db 'jge',7Dh |
dw conditional_jump-assembler |
db 'jle',7Eh |
dw conditional_jump-assembler |
db 'jmp',0 |
dw jmp_instruction-assembler |
db 'jna',76h |
dw conditional_jump-assembler |
db 'jnb',73h |
dw conditional_jump-assembler |
db 'jnc',73h |
dw conditional_jump-assembler |
db 'jne',75h |
dw conditional_jump-assembler |
db 'jng',7Eh |
dw conditional_jump-assembler |
db 'jnl',7Dh |
dw conditional_jump-assembler |
db 'jno',71h |
dw conditional_jump-assembler |
db 'jnp',7Bh |
dw conditional_jump-assembler |
db 'jns',79h |
dw conditional_jump-assembler |
db 'jnz',75h |
dw conditional_jump-assembler |
db 'jpe',7Ah |
dw conditional_jump-assembler |
db 'jpo',7Bh |
dw conditional_jump-assembler |
db 'lar',2 |
dw lar_instruction-assembler |
db 'lds',3 |
dw ls_instruction-assembler |
db 'lea',0 |
dw lea_instruction-assembler |
db 'les',0 |
dw ls_instruction-assembler |
db 'lfs',4 |
dw ls_instruction-assembler |
db 'lgs',5 |
dw ls_instruction-assembler |
db 'lsl',3 |
dw lar_instruction-assembler |
db 'lss',2 |
dw ls_instruction-assembler |
db 'ltr',3 |
dw pm_word_instruction-assembler |
db 'mov',0 |
dw mov_instruction-assembler |
db 'mul',4 |
dw single_operand_instruction-assembler |
db 'neg',3 |
dw single_operand_instruction-assembler |
db 'nop',90h |
dw simple_instruction-assembler |
db 'not',2 |
dw single_operand_instruction-assembler |
db 'org',0 |
dw org_directive-assembler |
db 'out',0 |
dw out_instruction-assembler |
db 'pop',0 |
dw pop_instruction-assembler |
db 'por',0EBh |
dw mmx_instruction-assembler |
db 'rcl',2 |
dw sh_instruction-assembler |
db 'rcr',3 |
dw sh_instruction-assembler |
db 'rep',0F3h |
dw prefix_instruction-assembler |
db 'ret',0C2h |
dw ret_instruction-assembler |
db 'rol',0 |
dw sh_instruction-assembler |
db 'ror',1 |
dw sh_instruction-assembler |
db 'rsm',0AAh |
dw simple_extended_instruction-assembler |
db 'sal',4 |
dw sh_instruction-assembler |
db 'sar',7 |
dw sh_instruction-assembler |
db 'sbb',18h |
dw basic_instruction-assembler |
db 'shl',4 |
dw sh_instruction-assembler |
db 'shr',5 |
dw sh_instruction-assembler |
db 'stc',0F9h |
dw simple_instruction-assembler |
db 'std',0FDh |
dw simple_instruction-assembler |
db 'sti',0FBh |
dw simple_instruction-assembler |
db 'str',1 |
dw pm_store_word_instruction-assembler |
db 'sub',28h |
dw basic_instruction-assembler |
db 'ud2',0Bh |
dw simple_extended_instruction-assembler |
db 'xor',30h |
dw basic_instruction-assembler |
db 0 |
instructions_4: |
db 'arpl',0 |
dw arpl_instruction-assembler |
db 'call',0 |
dw call_instruction-assembler |
db 'cdqe',98h |
dw simple_instruction_64bit-assembler |
db 'clts',6 |
dw simple_extended_instruction-assembler |
db 'cmps',0A6h |
dw cmps_instruction-assembler |
db 'cwde',98h |
dw simple_instruction_32bit-assembler |
db 'data',0 |
dw data_directive-assembler |
db 'else',0 |
dw else_directive-assembler |
db 'emms',77h |
dw simple_extended_instruction-assembler |
db 'fabs',100001b |
dw simple_fpu_instruction-assembler |
db 'fadd',0 |
dw basic_fpu_instruction-assembler |
db 'fbld',4 |
dw fbld_instruction-assembler |
db 'fchs',100000b |
dw simple_fpu_instruction-assembler |
db 'fcom',2 |
dw basic_fpu_instruction-assembler |
db 'fcos',111111b |
dw simple_fpu_instruction-assembler |
db 'fdiv',6 |
dw basic_fpu_instruction-assembler |
db 'feni',0E0h |
dw finit_instruction-assembler |
db 'fild',0 |
dw fild_instruction-assembler |
db 'fist',2 |
dw fild_instruction-assembler |
db 'fld1',101000b |
dw simple_fpu_instruction-assembler |
db 'fldz',101110b |
dw simple_fpu_instruction-assembler |
db 'fmul',1 |
dw basic_fpu_instruction-assembler |
db 'fnop',010000b |
dw simple_fpu_instruction-assembler |
db 'fsin',111110b |
dw simple_fpu_instruction-assembler |
db 'fstp',3 |
dw fld_instruction-assembler |
db 'fsub',4 |
dw basic_fpu_instruction-assembler |
db 'ftst',100100b |
dw simple_fpu_instruction-assembler |
db 'fxam',100101b |
dw simple_fpu_instruction-assembler |
db 'fxch',0 |
dw fxch_instruction-assembler |
db 'heap',0 |
dw heap_directive-assembler |
db 'idiv',7 |
dw single_operand_instruction-assembler |
db 'imul',0 |
dw imul_instruction-assembler |
db 'insb',6Ch |
dw simple_instruction-assembler |
db 'insd',6Dh |
dw simple_instruction_32bit-assembler |
db 'insw',6Dh |
dw simple_instruction_16bit-assembler |
db 'int1',0F1h |
dw simple_instruction-assembler |
db 'int3',0CCh |
dw simple_instruction-assembler |
db 'into',0CEh |
dw simple_instruction_except64-assembler |
db 'invd',8 |
dw simple_extended_instruction-assembler |
db 'iret',0CFh |
dw iret_instruction-assembler |
db 'jcxz',0E3h |
dw loop_instruction_16bit-assembler |
db 'jnae',72h |
dw conditional_jump-assembler |
db 'jnbe',77h |
dw conditional_jump-assembler |
db 'jnge',7Ch |
dw conditional_jump-assembler |
db 'jnle',7Fh |
dw conditional_jump-assembler |
db 'lahf',9Fh |
dw simple_instruction_except64-assembler |
db 'lgdt',2 |
dw lgdt_instruction-assembler |
db 'lidt',3 |
dw lgdt_instruction-assembler |
db 'lldt',2 |
dw pm_word_instruction-assembler |
db 'lmsw',16h |
dw pm_word_instruction-assembler |
db 'load',0 |
dw load_directive-assembler |
db 'lock',0F0h |
dw prefix_instruction-assembler |
db 'lods',0ACh |
dw lods_instruction-assembler |
db 'loop',0E2h |
dw loop_instruction-assembler |
db 'movd',0 |
dw movd_instruction-assembler |
db 'movq',0 |
dw movq_instruction-assembler |
db 'movs',0A4h |
dw movs_instruction-assembler |
db 'orpd',56h |
dw sse_pd_instruction-assembler |
db 'orps',56h |
dw sse_ps_instruction-assembler |
db 'outs',6Eh |
dw outs_instruction-assembler |
db 'pand',0DBh |
dw mmx_instruction-assembler |
db 'popa',61h |
dw simple_instruction_except64-assembler |
db 'popd',4 |
dw pop_instruction-assembler |
db 'popf',9Dh |
dw simple_instruction-assembler |
db 'popq',8 |
dw pop_instruction-assembler |
db 'popw',2 |
dw pop_instruction-assembler |
db 'push',0 |
dw push_instruction-assembler |
db 'pxor',0EFh |
dw mmx_instruction-assembler |
db 'repe',0F3h |
dw prefix_instruction-assembler |
db 'repz',0F3h |
dw prefix_instruction-assembler |
db 'retd',0C2h |
dw ret_instruction_32bit_except64-assembler |
db 'retf',0CAh |
dw retf_instruction-assembler |
db 'retn',0C2h |
dw ret_instruction-assembler |
db 'retq',0C2h |
dw ret_instruction_only64-assembler |
db 'retw',0C2h |
dw ret_instruction_16bit-assembler |
db 'sahf',9Eh |
dw simple_instruction_except64-assembler |
db 'salc',0D6h |
dw simple_instruction_except64-assembler |
db 'scas',0AEh |
dw stos_instruction-assembler |
db 'seta',97h |
dw set_instruction-assembler |
db 'setb',92h |
dw set_instruction-assembler |
db 'setc',92h |
dw set_instruction-assembler |
db 'sete',94h |
dw set_instruction-assembler |
db 'setg',9Fh |
dw set_instruction-assembler |
db 'setl',9Ch |
dw set_instruction-assembler |
db 'seto',90h |
dw set_instruction-assembler |
db 'setp',9Ah |
dw set_instruction-assembler |
db 'sets',98h |
dw set_instruction-assembler |
db 'setz',94h |
dw set_instruction-assembler |
db 'sgdt',0 |
dw lgdt_instruction-assembler |
db 'shld',0A4h |
dw shd_instruction-assembler |
db 'shrd',0ACh |
dw shd_instruction-assembler |
db 'sidt',1 |
dw lgdt_instruction-assembler |
db 'sldt',0 |
dw pm_store_word_instruction-assembler |
db 'smsw',14h |
dw pm_store_word_instruction-assembler |
db 'stos',0AAh |
dw stos_instruction-assembler |
db 'test',0 |
dw test_instruction-assembler |
db 'verr',4 |
dw pm_word_instruction-assembler |
db 'verw',5 |
dw pm_word_instruction-assembler |
db 'wait',9Bh |
dw simple_instruction-assembler |
db 'xadd',0C0h |
dw basic_486_instruction-assembler |
db 'xchg',0 |
dw xchg_instruction-assembler |
db 'xlat',0D7h |
dw xlat_instruction-assembler |
db 0 |
instructions_5: |
db 'addpd',58h |
dw sse_pd_instruction-assembler |
db 'addps',58h |
dw sse_ps_instruction-assembler |
db 'addsd',58h |
dw sse_sd_instruction-assembler |
db 'addss',58h |
dw sse_ss_instruction-assembler |
db 'align',0 |
dw align_directive-assembler |
db 'andpd',54h |
dw sse_pd_instruction-assembler |
db 'andps',54h |
dw sse_ps_instruction-assembler |
db 'bound',0 |
dw bound_instruction-assembler |
db 'break',0 |
dw break_directive-assembler |
db 'bswap',0 |
dw bswap_instruction-assembler |
db 'cmova',47h |
dw cmov_instruction-assembler |
db 'cmovb',42h |
dw cmov_instruction-assembler |
db 'cmovc',42h |
dw cmov_instruction-assembler |
db 'cmove',44h |
dw cmov_instruction-assembler |
db 'cmovg',4Fh |
dw cmov_instruction-assembler |
db 'cmovl',4Ch |
dw cmov_instruction-assembler |
db 'cmovo',40h |
dw cmov_instruction-assembler |
db 'cmovp',4Ah |
dw cmov_instruction-assembler |
db 'cmovs',48h |
dw cmov_instruction-assembler |
db 'cmovz',44h |
dw cmov_instruction-assembler |
db 'cmppd',0 |
dw cmppd_instruction-assembler |
db 'cmpps',0 |
dw cmpps_instruction-assembler |
db 'cmpsb',0A6h |
dw simple_instruction-assembler |
db 'cmpsd',0 |
dw cmpsd_instruction-assembler |
db 'cmpsq',0 |
dw simple_instruction_64bit-assembler |
db 'cmpss',0 |
dw cmpss_instruction-assembler |
db 'cmpsw',0A7h |
dw simple_instruction_16bit-assembler |
db 'cpuid',0A2h |
dw simple_extended_instruction-assembler |
db 'divpd',5Eh |
dw sse_pd_instruction-assembler |
db 'divps',5Eh |
dw sse_ps_instruction-assembler |
db 'divsd',5Eh |
dw sse_sd_instruction-assembler |
db 'divss',5Eh |
dw sse_ss_instruction-assembler |
db 'enter',0 |
dw enter_instruction-assembler |
db 'entry',0 |
dw entry_directive-assembler |
db 'extrn',0 |
dw extrn_directive-assembler |
db 'f2xm1',110000b |
dw simple_fpu_instruction-assembler |
db 'faddp',0 |
dw faddp_instruction-assembler |
db 'fbstp',6 |
dw fbld_instruction-assembler |
db 'fclex',0E2h |
dw finit_instruction-assembler |
db 'fcomi',0F0h |
dw fcomi_instruction-assembler |
db 'fcomp',3 |
dw basic_fpu_instruction-assembler |
db 'fdisi',0E1h |
dw finit_instruction-assembler |
db 'fdivp',7 |
dw faddp_instruction-assembler |
db 'fdivr',7 |
dw basic_fpu_instruction-assembler |
db 'femms',0Eh |
dw simple_extended_instruction-assembler |
db 'ffree',0 |
dw ffree_instruction-assembler |
db 'fiadd',0 |
dw fi_instruction-assembler |
db 'ficom',2 |
dw fi_instruction-assembler |
db 'fidiv',6 |
dw fi_instruction-assembler |
db 'fimul',1 |
dw fi_instruction-assembler |
db 'finit',0E3h |
dw finit_instruction-assembler |
db 'fistp',3 |
dw fild_instruction-assembler |
db 'fisub',4 |
dw fi_instruction-assembler |
db 'fldcw',5 |
dw fldcw_instruction-assembler |
db 'fldpi',101011b |
dw simple_fpu_instruction-assembler |
db 'fmulp',1 |
dw faddp_instruction-assembler |
db 'fneni',0E0h |
dw fninit_instruction-assembler |
db 'fprem',111000b |
dw simple_fpu_instruction-assembler |
db 'fptan',110010b |
dw simple_fpu_instruction-assembler |
db 'fsave',6 |
dw fsave_instruction-assembler |
db 'fsqrt',111010b |
dw simple_fpu_instruction-assembler |
db 'fstcw',7 |
dw fstcw_instruction-assembler |
db 'fstsw',0 |
dw fstsw_instruction-assembler |
db 'fsubp',5 |
dw faddp_instruction-assembler |
db 'fsubr',5 |
dw basic_fpu_instruction-assembler |
db 'fucom',4 |
dw ffree_instruction-assembler |
db 'fwait',9Bh |
dw simple_instruction-assembler |
db 'fyl2x',110001b |
dw simple_fpu_instruction-assembler |
db 'iretd',0CFh |
dw simple_instruction_32bit-assembler |
db 'iretq',0CFh |
dw simple_instruction_64bit-assembler |
db 'iretw',0CFh |
dw simple_instruction_16bit-assembler |
db 'jecxz',0E3h |
dw loop_instruction_32bit-assembler |
db 'jrcxz',0E3h |
dw loop_instruction_64bit-assembler |
db 'label',0 |
dw label_directive-assembler |
db 'lddqu',0 |
dw lddqu_instruction-assembler |
db 'leave',0C9h |
dw simple_instruction-assembler |
db 'lodsb',0ACh |
dw simple_instruction-assembler |
db 'lodsd',0ADh |
dw simple_instruction_32bit-assembler |
db 'lodsq',0ADh |
dw simple_instruction_64bit-assembler |
db 'lodsw',0ADh |
dw simple_instruction_16bit-assembler |
db 'loopd',0E2h |
dw loop_instruction_32bit-assembler |
db 'loope',0E1h |
dw loop_instruction-assembler |
db 'loopq',0E2h |
dw loop_instruction_64bit-assembler |
db 'loopw',0E2h |
dw loop_instruction_16bit-assembler |
db 'loopz',0E1h |
dw loop_instruction-assembler |
db 'maxpd',5Fh |
dw sse_pd_instruction-assembler |
db 'maxps',5Fh |
dw sse_ps_instruction-assembler |
db 'maxsd',5Fh |
dw sse_sd_instruction-assembler |
db 'maxss',5Fh |
dw sse_ss_instruction-assembler |
db 'minpd',5Dh |
dw sse_pd_instruction-assembler |
db 'minps',5Dh |
dw sse_ps_instruction-assembler |
db 'minsd',5Dh |
dw sse_sd_instruction-assembler |
db 'minss',5Dh |
dw sse_ss_instruction-assembler |
db 'movsb',0A4h |
dw simple_instruction-assembler |
db 'movsd',0 |
dw movsd_instruction-assembler |
db 'movsq',0A5h |
dw simple_instruction_64bit-assembler |
db 'movss',0 |
dw movss_instruction-assembler |
db 'movsw',0A5h |
dw simple_instruction_16bit-assembler |
db 'movsx',0BEh |
dw movx_instruction-assembler |
db 'movzx',0B6h |
dw movx_instruction-assembler |
db 'mulpd',59h |
dw sse_pd_instruction-assembler |
db 'mulps',59h |
dw sse_ps_instruction-assembler |
db 'mulsd',59h |
dw sse_sd_instruction-assembler |
db 'mulss',59h |
dw sse_ss_instruction-assembler |
db 'mwait',0C9h |
dw monitor_instruction-assembler |
db 'outsb',6Eh |
dw simple_instruction-assembler |
db 'outsd',6Fh |
dw simple_instruction_32bit-assembler |
db 'outsw',6Fh |
dw simple_instruction_16bit-assembler |
db 'paddb',0FCh |
dw mmx_instruction-assembler |
db 'paddd',0FEh |
dw mmx_instruction-assembler |
db 'paddq',0D4h |
dw mmx_instruction-assembler |
db 'paddw',0FDh |
dw mmx_instruction-assembler |
db 'pandn',0DFh |
dw mmx_instruction-assembler |
db 'pause',0 |
dw pause_instruction-assembler |
db 'pavgb',0E0h |
dw mmx_instruction-assembler |
db 'pavgw',0E3h |
dw mmx_instruction-assembler |
db 'pf2id',1Dh |
dw amd3dnow_instruction-assembler |
db 'pf2iw',1Ch |
dw amd3dnow_instruction-assembler |
db 'pfacc',0AEh |
dw amd3dnow_instruction-assembler |
db 'pfadd',9Eh |
dw amd3dnow_instruction-assembler |
db 'pfmax',0A4h |
dw amd3dnow_instruction-assembler |
db 'pfmin',94h |
dw amd3dnow_instruction-assembler |
db 'pfmul',0B4h |
dw amd3dnow_instruction-assembler |
db 'pfrcp',96h |
dw amd3dnow_instruction-assembler |
db 'pfsub',9Ah |
dw amd3dnow_instruction-assembler |
db 'pi2fd',0Dh |
dw amd3dnow_instruction-assembler |
db 'pi2fw',0Ch |
dw amd3dnow_instruction-assembler |
db 'popad',61h |
dw simple_instruction_32bit_except64-assembler |
db 'popaw',61h |
dw simple_instruction_16bit_except64-assembler |
db 'popfd',9Dh |
dw simple_instruction_32bit_except64-assembler |
db 'popfw',9Dh |
dw simple_instruction_16bit-assembler |
db 'popfq',9Dh |
dw simple_instruction_only64-assembler |
db 'pslld',0F2h |
dw mmx_ps_instruction-assembler |
db 'psllq',0F3h |
dw mmx_ps_instruction-assembler |
db 'psllw',0F1h |
dw mmx_ps_instruction-assembler |
db 'psrad',0E2h |
dw mmx_ps_instruction-assembler |
db 'psraw',0E1h |
dw mmx_ps_instruction-assembler |
db 'psrld',0D2h |
dw mmx_ps_instruction-assembler |
db 'psrlq',0D3h |
dw mmx_ps_instruction-assembler |
db 'psrlw',0D1h |
dw mmx_ps_instruction-assembler |
db 'psubb',0F8h |
dw mmx_instruction-assembler |
db 'psubd',0FAh |
dw mmx_instruction-assembler |
db 'psubq',0FBh |
dw mmx_instruction-assembler |
db 'psubw',0F9h |
dw mmx_instruction-assembler |
db 'pusha',60h |
dw simple_instruction_except64-assembler |
db 'pushd',4 |
dw push_instruction-assembler |
db 'pushf',9Ch |
dw simple_instruction-assembler |
db 'pushq',8 |
dw push_instruction-assembler |
db 'pushw',2 |
dw push_instruction-assembler |
db 'rcpps',53h |
dw sse_ps_instruction-assembler |
db 'rcpss',53h |
dw sse_ss_instruction-assembler |
db 'rdmsr',32h |
dw simple_extended_instruction-assembler |
db 'rdpmc',33h |
dw simple_extended_instruction-assembler |
db 'rdtsc',31h |
dw simple_extended_instruction-assembler |
db 'repne',0F2h |
dw prefix_instruction-assembler |
db 'repnz',0F2h |
dw prefix_instruction-assembler |
db 'retfd',0CAh |
dw ret_instruction_32bit-assembler |
db 'retfq',0CAh |
dw ret_instruction_64bit-assembler |
db 'retfw',0CAh |
dw ret_instruction_16bit-assembler |
db 'retnd',0C2h |
dw ret_instruction_32bit_except64-assembler |
db 'retnq',0C2h |
dw ret_instruction_only64-assembler |
db 'retnw',0C2h |
dw ret_instruction_16bit-assembler |
db 'scasb',0AEh |
dw simple_instruction-assembler |
db 'scasd',0AFh |
dw simple_instruction_32bit-assembler |
db 'scasq',0AFh |
dw simple_instruction_64bit-assembler |
db 'scasw',0AFh |
dw simple_instruction_16bit-assembler |
db 'setae',93h |
dw set_instruction-assembler |
db 'setbe',96h |
dw set_instruction-assembler |
db 'setge',9Dh |
dw set_instruction-assembler |
db 'setle',9Eh |
dw set_instruction-assembler |
db 'setna',96h |
dw set_instruction-assembler |
db 'setnb',93h |
dw set_instruction-assembler |
db 'setnc',93h |
dw set_instruction-assembler |
db 'setne',95h |
dw set_instruction-assembler |
db 'setng',9Eh |
dw set_instruction-assembler |
db 'setnl',9Dh |
dw set_instruction-assembler |
db 'setno',91h |
dw set_instruction-assembler |
db 'setnp',9Bh |
dw set_instruction-assembler |
db 'setns',99h |
dw set_instruction-assembler |
db 'setnz',95h |
dw set_instruction-assembler |
db 'setpe',9Ah |
dw set_instruction-assembler |
db 'setpo',9Bh |
dw set_instruction-assembler |
db 'stack',0 |
dw stack_directive-assembler |
db 'store',0 |
dw store_directive-assembler |
db 'stosb',0AAh |
dw simple_instruction-assembler |
db 'stosd',0ABh |
dw simple_instruction_32bit-assembler |
db 'stosq',0ABh |
dw simple_instruction_64bit-assembler |
db 'stosw',0ABh |
dw simple_instruction_16bit-assembler |
db 'subpd',5Ch |
dw sse_pd_instruction-assembler |
db 'subps',5Ch |
dw sse_ps_instruction-assembler |
db 'subsd',5Ch |
dw sse_sd_instruction-assembler |
db 'subss',5Ch |
dw sse_ss_instruction-assembler |
db 'times',0 |
dw times_directive-assembler |
db 'vmxon',6 |
dw vmxon_instruction-assembler |
db 'while',0 |
dw while_directive-assembler |
db 'wrmsr',30h |
dw simple_extended_instruction-assembler |
db 'xlatb',0D7h |
dw simple_instruction-assembler |
db 'xorpd',57h |
dw sse_pd_instruction-assembler |
db 'xorps',57h |
dw sse_ps_instruction-assembler |
db 0 |
instructions_6: |
db 'andnpd',55h |
dw sse_pd_instruction-assembler |
db 'andnps',55h |
dw sse_ps_instruction-assembler |
db 'cmovae',43h |
dw cmov_instruction-assembler |
db 'cmovbe',46h |
dw cmov_instruction-assembler |
db 'cmovge',4Dh |
dw cmov_instruction-assembler |
db 'cmovle',4Eh |
dw cmov_instruction-assembler |
db 'cmovna',46h |
dw cmov_instruction-assembler |
db 'cmovnb',43h |
dw cmov_instruction-assembler |
db 'cmovnc',43h |
dw cmov_instruction-assembler |
db 'cmovne',45h |
dw cmov_instruction-assembler |
db 'cmovng',4Eh |
dw cmov_instruction-assembler |
db 'cmovnl',4Dh |
dw cmov_instruction-assembler |
db 'cmovno',41h |
dw cmov_instruction-assembler |
db 'cmovnp',4Bh |
dw cmov_instruction-assembler |
db 'cmovns',49h |
dw cmov_instruction-assembler |
db 'cmovnz',45h |
dw cmov_instruction-assembler |
db 'cmovpe',4Ah |
dw cmov_instruction-assembler |
db 'cmovpo',4Bh |
dw cmov_instruction-assembler |
db 'comisd',2Fh |
dw comisd_instruction-assembler |
db 'comiss',2Fh |
dw comiss_instruction-assembler |
db 'fcmovb',0C0h |
dw fcmov_instruction-assembler |
db 'fcmove',0C8h |
dw fcmov_instruction-assembler |
db 'fcmovu',0D8h |
dw fcmov_instruction-assembler |
db 'fcomip',0F0h |
dw fcomip_instruction-assembler |
db 'fcompp',0 |
dw fcompp_instruction-assembler |
db 'fdivrp',6 |
dw faddp_instruction-assembler |
db 'ffreep',0 |
dw ffreep_instruction-assembler |
db 'ficomp',3 |
dw fi_instruction-assembler |
db 'fidivr',7 |
dw fi_instruction-assembler |
db 'fisttp',1 |
dw fild_instruction-assembler |
db 'fisubr',5 |
dw fi_instruction-assembler |
db 'fldenv',4 |
dw fldenv_instruction-assembler |
db 'fldl2e',101010b |
dw simple_fpu_instruction-assembler |
db 'fldl2t',101001b |
dw simple_fpu_instruction-assembler |
db 'fldlg2',101100b |
dw simple_fpu_instruction-assembler |
db 'fldln2',101101b |
dw simple_fpu_instruction-assembler |
db 'fnclex',0E2h |
dw fninit_instruction-assembler |
db 'fndisi',0E1h |
dw fninit_instruction-assembler |
db 'fninit',0E3h |
dw fninit_instruction-assembler |
db 'fnsave',6 |
dw fnsave_instruction-assembler |
db 'fnstcw',7 |
dw fldcw_instruction-assembler |
db 'fnstsw',0 |
dw fnstsw_instruction-assembler |
db 'format',0 |
dw format_directive-assembler |
db 'fpatan',110011b |
dw simple_fpu_instruction-assembler |
db 'fprem1',110101b |
dw simple_fpu_instruction-assembler |
db 'frstor',4 |
dw fnsave_instruction-assembler |
db 'frstpm',0E5h |
dw fninit_instruction-assembler |
db 'fscale',111101b |
dw simple_fpu_instruction-assembler |
db 'fsetpm',0E4h |
dw fninit_instruction-assembler |
db 'fstenv',6 |
dw fstenv_instruction-assembler |
db 'fsubrp',4 |
dw faddp_instruction-assembler |
db 'fucomi',0E8h |
dw fcomi_instruction-assembler |
db 'fucomp',5 |
dw ffree_instruction-assembler |
db 'fxsave',0 |
dw fxsave_instruction-assembler |
db 'haddpd',07Ch |
dw sse_pd_instruction-assembler |
db 'haddps',07Ch |
dw cvtpd2dq_instruction-assembler |
db 'hsubpd',07Dh |
dw sse_pd_instruction-assembler |
db 'hsubps',07Dh |
dw cvtpd2dq_instruction-assembler |
db 'invlpg',0 |
dw invlpg_instruction-assembler |
db 'lfence',0E8h |
dw fence_instruction-assembler |
db 'looped',0E1h |
dw loop_instruction_32bit-assembler |
db 'loopeq',0E1h |
dw loop_instruction_64bit-assembler |
db 'loopew',0E1h |
dw loop_instruction_16bit-assembler |
db 'loopne',0E0h |
dw loop_instruction-assembler |
db 'loopnz',0E0h |
dw loop_instruction-assembler |
db 'loopzd',0E1h |
dw loop_instruction_32bit-assembler |
db 'loopzq',0E1h |
dw loop_instruction_64bit-assembler |
db 'loopzw',0E1h |
dw loop_instruction_16bit-assembler |
db 'mfence',0F0h |
dw fence_instruction-assembler |
db 'movapd',28h |
dw movpd_instruction-assembler |
db 'movaps',28h |
dw movps_instruction-assembler |
db 'movdqa',66h |
dw movdq_instruction-assembler |
db 'movdqu',0F3h |
dw movdq_instruction-assembler |
db 'movhpd',16h |
dw movlpd_instruction-assembler |
db 'movhps',16h |
dw movlps_instruction-assembler |
db 'movlpd',12h |
dw movlpd_instruction-assembler |
db 'movlps',12h |
dw movlps_instruction-assembler |
db 'movnti',0C3h |
dw movnti_instruction-assembler |
db 'movntq',0E7h |
dw movntq_instruction-assembler |
db 'movsxd',63h |
dw movsxd_instruction-assembler |
db 'movupd',10h |
dw movpd_instruction-assembler |
db 'movups',10h |
dw movps_instruction-assembler |
db 'paddsb',0ECh |
dw mmx_instruction-assembler |
db 'paddsw',0EDh |
dw mmx_instruction-assembler |
db 'pextrw',0C5h |
dw pextrw_instruction-assembler |
db 'pfnacc',8Ah |
dw amd3dnow_instruction-assembler |
db 'pfsubr',0AAh |
dw amd3dnow_instruction-assembler |
db 'pinsrw',0C4h |
dw pinsrw_instruction-assembler |
db 'pmaxsw',0EEh |
dw mmx_instruction-assembler |
db 'pmaxub',0DEh |
dw mmx_instruction-assembler |
db 'pminsw',0EAh |
dw mmx_instruction-assembler |
db 'pminub',0DAh |
dw mmx_instruction-assembler |
db 'pmulhw',0E5h |
dw mmx_instruction-assembler |
db 'pmullw',0D5h |
dw mmx_instruction-assembler |
db 'psadbw',0F6h |
dw mmx_instruction-assembler |
db 'pshufd',66h |
dw pshufd_instruction-assembler |
db 'pshufw',0 |
dw pshufw_instruction-assembler |
db 'pslldq',111b |
dw ps_dq_instruction-assembler |
db 'psrldq',011b |
dw ps_dq_instruction-assembler |
db 'psubsb',0E8h |
dw mmx_instruction-assembler |
db 'psubsw',0E9h |
dw mmx_instruction-assembler |
db 'pswapd',0BBh |
dw amd3dnow_instruction-assembler |
db 'public',0 |
dw public_directive-assembler |
db 'pushad',60h |
dw simple_instruction_32bit_except64-assembler |
db 'pushaw',60h |
dw simple_instruction_16bit_except64-assembler |
db 'pushfd',9Ch |
dw simple_instruction_32bit_except64-assembler |
db 'pushfq',9Ch |
dw simple_instruction_only64-assembler |
db 'pushfw',9Ch |
dw simple_instruction_16bit-assembler |
db 'rdtscp',1 |
dw swapgs_instruction-assembler |
db 'repeat',0 |
dw repeat_directive-assembler |
db 'setalc',0D6h |
dw simple_instruction_except64-assembler |
db 'setnae',92h |
dw set_instruction-assembler |
db 'setnbe',97h |
dw set_instruction-assembler |
db 'setnge',9Ch |
dw set_instruction-assembler |
db 'setnle',9Fh |
dw set_instruction-assembler |
db 'sfence',0F8h |
dw fence_instruction-assembler |
db 'shufpd',0C6h |
dw sse_pd_instruction-assembler |
db 'shufps',0C6h |
dw sse_ps_instruction-assembler |
db 'sqrtpd',51h |
dw sse_pd_instruction-assembler |
db 'sqrtps',51h |
dw sse_ps_instruction-assembler |
db 'sqrtsd',51h |
dw sse_sd_instruction-assembler |
db 'sqrtss',51h |
dw sse_ss_instruction-assembler |
db 'sysret',07h |
dw simple_extended_instruction-assembler |
db 'swapgs',0 |
dw swapgs_instruction-assembler |
db 'vmcall',0C1h |
dw simple_vmx_instruction-assembler |
db 'vmread',0 |
dw vmread_instruction-assembler |
db 'vmxoff',0C4h |
dw simple_vmx_instruction-assembler |
db 'wbinvd',9 |
dw simple_extended_instruction-assembler |
db 0 |
instructions_7: |
db 'clflush',111b |
dw fxsave_instruction-assembler |
db 'cmovnae',42h |
dw cmov_instruction-assembler |
db 'cmovnbe',47h |
dw cmov_instruction-assembler |
db 'cmovnge',4Ch |
dw cmov_instruction-assembler |
db 'cmovnle',4Fh |
dw cmov_instruction-assembler |
db 'cmpeqpd',0 |
dw cmp_pd_instruction-assembler |
db 'cmpeqps',0 |
dw cmp_ps_instruction-assembler |
db 'cmpeqsd',0 |
dw cmp_sd_instruction-assembler |
db 'cmpeqss',0 |
dw cmp_ss_instruction-assembler |
db 'cmplepd',2 |
dw cmp_pd_instruction-assembler |
db 'cmpleps',2 |
dw cmp_ps_instruction-assembler |
db 'cmplesd',2 |
dw cmp_sd_instruction-assembler |
db 'cmpless',2 |
dw cmp_ss_instruction-assembler |
db 'cmpltpd',1 |
dw cmp_pd_instruction-assembler |
db 'cmpltps',1 |
dw cmp_ps_instruction-assembler |
db 'cmpltsd',1 |
dw cmp_sd_instruction-assembler |
db 'cmpltss',1 |
dw cmp_ss_instruction-assembler |
db 'cmpxchg',0B0h |
dw basic_486_instruction-assembler |
db 'display',0 |
dw display_directive-assembler |
db 'fcmovbe',0D0h |
dw fcmov_instruction-assembler |
db 'fcmovnb',0C0h |
dw fcomi_instruction-assembler |
db 'fcmovne',0C8h |
dw fcomi_instruction-assembler |
db 'fcmovnu',0D8h |
dw fcomi_instruction-assembler |
db 'fdecstp',110110b |
dw simple_fpu_instruction-assembler |
db 'fincstp',110111b |
dw simple_fpu_instruction-assembler |
db 'fnstenv',6 |
dw fldenv_instruction-assembler |
db 'frndint',111100b |
dw simple_fpu_instruction-assembler |
db 'fsincos',111011b |
dw simple_fpu_instruction-assembler |
db 'fucomip',0E8h |
dw fcomip_instruction-assembler |
db 'fucompp',0 |
dw fucompp_instruction-assembler |
db 'fxrstor',1 |
dw fxsave_instruction-assembler |
db 'fxtract',110100b |
dw simple_fpu_instruction-assembler |
db 'fyl2xp1',111001b |
dw simple_fpu_instruction-assembler |
db 'ldmxcsr',10b |
dw fxsave_instruction-assembler |
db 'loopned',0E0h |
dw loop_instruction_32bit-assembler |
db 'loopneq',0E0h |
dw loop_instruction_64bit-assembler |
db 'loopnew',0E0h |
dw loop_instruction_16bit-assembler |
db 'loopnzd',0E0h |
dw loop_instruction_32bit-assembler |
db 'loopnzq',0E0h |
dw loop_instruction_64bit-assembler |
db 'loopnzw',0E0h |
dw loop_instruction_16bit-assembler |
db 'monitor',0C8h |
dw monitor_instruction-assembler |
db 'movddup',12h |
dw sse_sd_instruction-assembler |
db 'movdq2q',0 |
dw movdq2q_instruction-assembler |
db 'movhlps',12h |
dw movhlps_instruction-assembler |
db 'movlhps',16h |
dw movhlps_instruction-assembler |
db 'movntdq',0E7h |
dw movntdq_instruction-assembler |
db 'movntpd',2Bh |
dw movntdq_instruction-assembler |
db 'movntps',2Bh |
dw movntps_instruction-assembler |
db 'movq2dq',0 |
dw movq2dq_instruction-assembler |
db 'paddusb',0DCh |
dw mmx_instruction-assembler |
db 'paddusw',0DDh |
dw mmx_instruction-assembler |
db 'pavgusb',0BFh |
dw amd3dnow_instruction-assembler |
db 'pcmpeqb',74h |
dw mmx_instruction-assembler |
db 'pcmpeqd',76h |
dw mmx_instruction-assembler |
db 'pcmpeqw',75h |
dw mmx_instruction-assembler |
db 'pcmpgtb',64h |
dw mmx_instruction-assembler |
db 'pcmpgtd',66h |
dw mmx_instruction-assembler |
db 'pcmpgtw',65h |
dw mmx_instruction-assembler |
db 'pfcmpeq',0B0h |
dw amd3dnow_instruction-assembler |
db 'pfcmpge',90h |
dw amd3dnow_instruction-assembler |
db 'pfcmpgt',0A0h |
dw amd3dnow_instruction-assembler |
db 'pfpnacc',8Eh |
dw amd3dnow_instruction-assembler |
db 'pfrsqrt',97h |
dw amd3dnow_instruction-assembler |
db 'pmaddwd',0F5h |
dw mmx_instruction-assembler |
db 'pmulhrw',0B7h |
dw amd3dnow_instruction-assembler |
db 'pmulhuw',0E4h |
dw mmx_instruction-assembler |
db 'pmuludq',0F4h |
dw mmx_instruction-assembler |
db 'pshufhw',0F3h |
dw pshufd_instruction-assembler |
db 'pshuflw',0F2h |
dw pshufd_instruction-assembler |
db 'psubusb',0D8h |
dw mmx_instruction-assembler |
db 'psubusw',0D9h |
dw mmx_instruction-assembler |
db 'rsqrtps',52h |
dw sse_ps_instruction-assembler |
db 'rsqrtss',52h |
dw sse_ss_instruction-assembler |
db 'section',0 |
dw section_directive-assembler |
db 'segment',0 |
dw segment_directive-assembler |
db 'stmxcsr',11b |
dw fxsave_instruction-assembler |
db 'syscall',05h |
dw simple_extended_instruction-assembler |
db 'sysexit',35h |
dw simple_extended_instruction-assembler |
db 'ucomisd',2Eh |
dw comisd_instruction-assembler |
db 'ucomiss',2Eh |
dw comiss_instruction-assembler |
db 'virtual',0 |
dw virtual_directive-assembler |
db 'vmclear',6 |
dw vmclear_instruction-assembler |
db 'vmptrld',6 |
dw vmx_instruction-assembler |
db 'vmptrst',7 |
dw vmx_instruction-assembler |
db 'vmwrite',0 |
dw vmwrite_instruction-assembler |
db 0 |
instructions_8: |
db 'addsubpd',0D0h |
dw sse_pd_instruction-assembler |
db 'addsubps',0D0h |
dw cvtpd2dq_instruction-assembler |
db 'cmpneqpd',4 |
dw cmp_pd_instruction-assembler |
db 'cmpneqps',4 |
dw cmp_ps_instruction-assembler |
db 'cmpneqsd',4 |
dw cmp_sd_instruction-assembler |
db 'cmpneqss',4 |
dw cmp_ss_instruction-assembler |
db 'cmpnlepd',6 |
dw cmp_pd_instruction-assembler |
db 'cmpnleps',6 |
dw cmp_ps_instruction-assembler |
db 'cmpnlesd',6 |
dw cmp_sd_instruction-assembler |
db 'cmpnless',6 |
dw cmp_ss_instruction-assembler |
db 'cmpnltpd',5 |
dw cmp_pd_instruction-assembler |
db 'cmpnltps',5 |
dw cmp_ps_instruction-assembler |
db 'cmpnltsd',5 |
dw cmp_sd_instruction-assembler |
db 'cmpnltss',5 |
dw cmp_ss_instruction-assembler |
db 'cmpordpd',7 |
dw cmp_pd_instruction-assembler |
db 'cmpordps',7 |
dw cmp_ps_instruction-assembler |
db 'cmpordsd',7 |
dw cmp_sd_instruction-assembler |
db 'cmpordss',7 |
dw cmp_ss_instruction-assembler |
db 'cvtdq2pd',0E6h |
dw cvtdq2pd_instruction-assembler |
db 'cvtdq2ps',5Bh |
dw sse_ps_instruction-assembler |
db 'cvtpd2dq',0E6h |
dw cvtpd2dq_instruction-assembler |
db 'cvtpd2pi',2Dh |
dw cvtpd2pi_instruction-assembler |
db 'cvtpd2ps',5Ah |
dw sse_pd_instruction-assembler |
db 'cvtpi2pd',2Ah |
dw cvtpi2pd_instruction-assembler |
db 'cvtpi2ps',2Ah |
dw cvtpi2ps_instruction-assembler |
db 'cvtps2dq',5Bh |
dw sse_pd_instruction-assembler |
db 'cvtps2pd',5Ah |
dw cvtps2pd_instruction-assembler |
db 'cvtps2pi',2Dh |
dw cvtps2pi_instruction-assembler |
db 'cvtsd2si',2Dh |
dw cvtsd2si_instruction-assembler |
db 'cvtsd2ss',5Ah |
dw sse_sd_instruction-assembler |
db 'cvtsi2sd',2Ah |
dw cvtsi2sd_instruction-assembler |
db 'cvtsi2ss',2Ah |
dw cvtsi2ss_instruction-assembler |
db 'cvtss2sd',5Ah |
dw sse_ss_instruction-assembler |
db 'cvtss2si',2Dh |
dw cvtss2si_instruction-assembler |
db 'fcmovnbe',0D0h |
dw fcomi_instruction-assembler |
db 'maskmovq',0 |
dw maskmovq_instruction-assembler |
db 'movmskpd',0 |
dw movmskpd_instruction-assembler |
db 'movmskps',0 |
dw movmskps_instruction-assembler |
db 'movshdup',16h |
dw cvtdq2pd_instruction-assembler |
db 'movsldup',12h |
dw cvtdq2pd_instruction-assembler |
db 'packssdw',6Bh |
dw mmx_instruction-assembler |
db 'packsswb',63h |
dw mmx_instruction-assembler |
db 'packuswb',67h |
dw mmx_instruction-assembler |
db 'pfrcpit1',0A6h |
dw amd3dnow_instruction-assembler |
db 'pfrcpit2',0B6h |
dw amd3dnow_instruction-assembler |
db 'pfrsqit1',0A7h |
dw amd3dnow_instruction-assembler |
db 'pmovmskb',0D7h |
dw pextrw_instruction-assembler |
db 'prefetch',0 |
dw amd_prefetch_instruction-assembler |
db 'sysenter',34h |
dw simple_extended_instruction-assembler |
db 'unpckhpd',15h |
dw sse_pd_instruction-assembler |
db 'unpckhps',15h |
dw sse_ps_instruction-assembler |
db 'unpcklpd',14h |
dw sse_pd_instruction-assembler |
db 'unpcklps',14h |
dw sse_ps_instruction-assembler |
db 'vmlaunch',0C2h |
dw simple_vmx_instruction-assembler |
db 'vmresume',0C3h |
dw simple_vmx_instruction-assembler |
db 0 |
instructions_9: |
db 'cmpxchg8b',8 |
dw cmpxchgx_instruction-assembler |
db 'cvttpd2dq',0E6h |
dw sse_pd_instruction-assembler |
db 'cvttpd2pi',2Ch |
dw cvtpd2pi_instruction-assembler |
db 'cvttps2dq',5Bh |
dw cvtdq2pd_instruction-assembler |
db 'cvttps2pi',2Ch |
dw cvtps2pi_instruction-assembler |
db 'cvttsd2si',2Ch |
dw cvtsd2si_instruction-assembler |
db 'cvttss2si',2Ch |
dw cvtss2si_instruction-assembler |
db 'prefetchw',1 |
dw amd_prefetch_instruction-assembler |
db 'punpckhbw',68h |
dw mmx_instruction-assembler |
db 'punpckhdq',6Ah |
dw mmx_instruction-assembler |
db 'punpckhwd',69h |
dw mmx_instruction-assembler |
db 'punpcklbw',60h |
dw mmx_instruction-assembler |
db 'punpckldq',62h |
dw mmx_instruction-assembler |
db 'punpcklwd',61h |
dw mmx_instruction-assembler |
db 0 |
instructions_10: |
db 'cmpunordpd',3 |
dw cmp_pd_instruction-assembler |
db 'cmpunordps',3 |
dw cmp_ps_instruction-assembler |
db 'cmpunordsd',3 |
dw cmp_sd_instruction-assembler |
db 'cmpunordss',3 |
dw cmp_ss_instruction-assembler |
db 'cmpxchg16b',16 |
dw cmpxchgx_instruction-assembler |
db 'loadall286',5 |
dw simple_extended_instruction-assembler |
db 'loadall386',7 |
dw simple_extended_instruction-assembler |
db 'maskmovdqu',0 |
dw maskmovdqu_instruction-assembler |
db 'prefetcht0',1 |
dw prefetch_instruction-assembler |
db 'prefetcht1',2 |
dw prefetch_instruction-assembler |
db 'prefetcht2',3 |
dw prefetch_instruction-assembler |
db 'punpckhqdq',6Dh |
dw sse_pd_instruction-assembler |
db 'punpcklqdq',6Ch |
dw sse_pd_instruction-assembler |
db 0 |
instructions_11: |
db 'prefetchnta',0 |
dw prefetch_instruction-assembler |
db 0 |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |