0,0 → 1,2018 |
|
; flat assembler core |
; Copyright (c) 1999-2011, Tomasz Grysztar. |
; All rights reserved. |
|
calculate_expression: |
mov [current_offset],edi |
mov [value_undefined],0 |
cmp byte [esi],0 |
je get_string_value |
cmp byte [esi],'.' |
je convert_fp |
calculation_loop: |
lods byte [esi] |
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 |
cmp al,'!' |
je invalid_expression |
sub edi,14h |
mov ebx,edi |
sub ebx,14h |
cmp al,0E0h |
je calculate_rva |
cmp al,0E1h |
je calculate_plt |
cmp al,0D0h |
je calculate_not |
cmp al,083h |
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 |
mov [edi+12],al |
expression_value_ok: |
ret |
get_byte_number: |
xor eax,eax |
lods byte [esi] |
stos dword [edi] |
xor al,al |
stos dword [edi] |
got_number: |
mov word [edi-8+8],0 |
mov byte [edi-8+12],0 |
mov dword [edi-8+16],0 |
add edi,0Ch |
jmp calculation_loop |
get_word_number: |
xor eax,eax |
lods word [esi] |
stos dword [edi] |
xor ax,ax |
stos dword [edi] |
jmp got_number |
get_dword_number: |
movs dword [edi],[esi] |
xor eax,eax |
stos dword [edi] |
jmp got_number |
get_qword_number: |
movs dword [edi],[esi] |
movs dword [edi],[esi] |
jmp got_number |
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 |
mov [edi+16],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 |
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_out_of_scope |
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 eax,[current_offset] |
make_current_offset_label: |
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] |
mov al,[labels_type] |
mov [edi-12+12],al |
mov eax,[org_symbol] |
mov [edi-12+16],eax |
add edi,8 |
jmp calculation_loop |
org_origin_label: |
mov eax,[org_start] |
jmp make_current_offset_label |
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 |
make_qword_label_value: |
stos dword [edi] |
mov eax,edx |
stos dword [edi] |
add edi,0Ch |
jmp calculation_loop |
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 |
mov edx,invalid_value |
jmp error_undefined |
label_out_of_scope: |
mov edx,symbol_out_of_scope |
cmp [error_line],0 |
jne error_undefined |
mov [error_info],ebx |
jmp error_undefined |
label_undefined: |
mov edx,undefined_symbol |
cmp [error_line],0 |
jne error_undefined |
mov [error_info],ebx |
error_undefined: |
cmp [current_pass],1 |
ja 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 |
cmp [error_line],0 |
jne calculation_loop |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],edx |
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] |
jne invalid_sub |
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 |
or al,al |
jnz mul_first_register_ok |
mov [esi+8],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 |
or al,al |
jnz mul_calculated |
mov [esi+9],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] |
or ah,ah |
jnz invalid_use_of_symbol |
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] |
or ah,ah |
jnz invalid_use_of_symbol |
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 edx,[edi+4] |
xor [ebx+4],edx |
cmp [value_size],1 |
je xor_byte |
cmp [value_size],2 |
je xor_word |
cmp [value_size],4 |
je xor_dword |
cmp [value_size],6 |
je xor_pword |
xor_calculated: |
jmp calculation_loop |
prepare_xor_check: |
cmp edx,-1 |
je xor_check_ready |
xor edx,[ebx+4] |
xor eax,[ebx] |
cmp edx,-1 |
xor_check_ready: |
ret |
xor_byte: |
call prepare_xor_check |
jne xor_calculated |
xor edx,[ebx+4] |
jnz xor_calculated |
cmp eax,0FFFFFF80h |
jb xor_calculated |
xor eax,[ebx] |
cmp eax,0FFh |
ja xor_calculated |
mov [ebx+4],edx |
and dword [ebx],0FFh |
jmp xor_calculated |
xor_word: |
call prepare_xor_check |
jne xor_calculated |
xor edx,[ebx+4] |
jnz xor_calculated |
cmp eax,0FFFF8000h |
jb xor_calculated |
xor eax,[ebx] |
cmp eax,0FFFFh |
ja xor_calculated |
mov [ebx+4],edx |
and dword [ebx],0FFFFh |
jmp xor_calculated |
xor_dword: |
call prepare_xor_check |
jne xor_calculated |
xor edx,[ebx+4] |
jnz xor_calculated |
cmp eax,80000000h |
jb xor_calculated |
mov [ebx+4],edx |
jmp xor_calculated |
xor_pword: |
cmp edx,0FFFF8000h |
jae xor_pword_check |
xor edx,[ebx+4] |
xor eax,[ebx] |
cmp edx,0FFFF8000h |
jb xor_calculated |
xor_pword_check: |
xor edx,[ebx+4] |
cmp edx,0FFFFh |
ja xor_calculated |
and dword [ebx+4],0FFFFh |
jmp xor_calculated |
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 |
mov edx,[ebx+4] |
mov eax,[ebx] |
cmp ecx,32 |
jae shl_high |
shld edx,eax,cl |
shl eax,cl |
mov [ebx],eax |
mov [ebx+4],edx |
jmp calculation_loop |
shl_high: |
sub cl,32 |
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 |
mov edx,[ebx+4] |
mov eax,[ebx] |
cmp ecx,32 |
jae shr_high |
cmp [value_size],1 |
je shr_byte |
cmp [value_size],2 |
je shr_word |
cmp [value_size],4 |
je shr_dword |
cmp [value_size],6 |
je shr_pword |
shr_regular: |
shrd eax,edx,cl |
shr edx,cl |
mov [ebx],eax |
mov [ebx+4],edx |
jmp calculation_loop |
shr_byte: |
cmp edx,-1 |
jne shr_regular |
cmp eax,0FFFFFF80h |
jb shr_regular |
and eax,0FFh |
xor edx,edx |
jmp shr_regular |
shr_word: |
cmp edx,-1 |
jne shr_regular |
cmp eax,0FFFF8000h |
jb shr_regular |
and eax,0FFFFh |
xor edx,edx |
jmp shr_regular |
shr_dword: |
cmp edx,-1 |
jne shr_regular |
cmp eax,80000000h |
jb shr_regular |
xor edx,edx |
jmp shr_regular |
shr_pword: |
cmp edx,0FFFF8000h |
jb shr_regular |
and edx,0FFFFh |
jmp shr_regular |
shr_high: |
sub cl,32 |
cmp [value_size],1 |
je shr_byte_32plus |
cmp [value_size],2 |
je shr_word_32plus |
cmp [value_size],4 |
je shr_dword_32plus |
cmp [value_size],6 |
je shr_pword_32plus |
shr_32plus: |
shr edx,cl |
mov [ebx],edx |
mov dword [ebx+4],0 |
jmp calculation_loop |
shr_byte_32plus: |
cmp edx,-1 |
jne shr_32plus |
cmp eax,-80h |
jb shr_32plus |
jmp zero_value |
shr_word_32plus: |
cmp edx,-1 |
jne shr_32plus |
cmp eax,-8000h |
jb shr_32plus |
jmp zero_value |
shr_dword_32plus: |
cmp edx,-1 |
jne shr_32plus |
cmp eax,-80000000h |
jb shr_32plus |
jmp zero_value |
shr_pword_32plus: |
cmp edx,-8000h |
jb shr_32plus |
and edx,0FFFFh |
jmp shr_32plus |
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 word [edi+8],0 |
jne invalid_expression |
cmp [output_format],5 |
je calculate_gotoff |
cmp [output_format],4 |
je calculate_coff_rva |
cmp [output_format],3 |
jne invalid_expression |
test [format_flags],8 |
jnz pe64_rva |
mov al,2 |
bt [resolver_flags],0 |
jc rva_type_ok |
xor al,al |
rva_type_ok: |
cmp byte [edi+12],al |
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: |
mov al,4 |
bt [resolver_flags],0 |
jc pe64_rva_type_ok |
xor al,al |
pe64_rva_type_ok: |
cmp byte [edi+12],al |
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 |
calculate_gotoff: |
test [format_flags],8+1 |
jnz invalid_expression |
calculate_coff_rva: |
mov dl,5 |
cmp byte [edi+12],2 |
je change_value_type |
incorrect_change_of_value_type: |
cmp [error_line],0 |
jne change_value_type |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],invalid_use_of_symbol |
change_value_type: |
mov byte [edi+12],dl |
add edi,14h |
jmp calculation_loop |
calculate_plt: |
cmp word [edi+8],0 |
jne invalid_expression |
cmp [output_format],5 |
jne invalid_expression |
test [format_flags],1 |
jnz invalid_expression |
mov dl,6 |
mov dh,2 |
test [format_flags],8 |
jz check_value_for_plt |
mov dh,4 |
check_value_for_plt: |
mov eax,[edi] |
or eax,[edi+4] |
jnz incorrect_change_of_value_type |
cmp byte [edi+12],dh |
jne incorrect_change_of_value_type |
mov eax,[edi+16] |
cmp byte [eax],80h |
jne incorrect_change_of_value_type |
jmp change_value_type |
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: |
inc esi |
mov word [edi+8],0 |
mov byte [edi+12],0 |
mov al,[value_size] |
cmp al,2 |
je convert_fp_word |
cmp al,4 |
je convert_fp_dword |
cmp al,8 |
je convert_fp_qword |
jmp invalid_value |
convert_fp_word: |
xor eax,eax |
cmp word [esi+8],8000h |
je fp_word_store |
mov bx,[esi+8] |
mov ax,[esi+6] |
shl ax,1 |
shr ax,6 |
jnc fp_word_ok |
inc ax |
bt ax,10 |
jnc fp_word_ok |
and ax,1 shl 10 - 1 |
inc bx |
shr ax,1 |
fp_word_ok: |
add bx,0Fh |
cmp bx,01Fh |
jge value_out_of_range |
cmp bx,0 |
jg fp_word_exp_ok |
or ax,1 shl 10 |
mov cx,bx |
neg cx |
inc cx |
cmp cx,10 |
ja value_out_of_range |
xor bx,bx |
shr ax,cl |
jnc fp_word_exp_ok |
inc ax |
test ax,1 shl 10 |
jz fp_word_exp_ok |
and ax,1 shl 10 - 1 |
inc bx |
fp_word_exp_ok: |
shl bx,10 |
or ax,bx |
fp_word_store: |
mov bl,[esi+11] |
shl bx,15 |
or ax,bx |
mov [edi],eax |
xor eax,eax |
mov [edi+4],eax |
add esi,13 |
ret |
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,0FFh |
jge value_out_of_range |
cmp bx,0 |
jg fp_dword_exp_ok |
or eax,1 shl 23 |
mov cx,bx |
neg cx |
inc cx |
cmp cx,23 |
ja value_out_of_range |
xor bx,bx |
shr eax,cl |
jnc fp_dword_exp_ok |
inc eax |
test eax,1 shl 23 |
jz fp_dword_exp_ok |
and eax,1 shl 23 - 1 |
inc bx |
fp_dword_exp_ok: |
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,7FFh |
jge value_out_of_range |
cmp bx,0 |
jg fp_qword_exp_ok |
or edx,1 shl 20 |
mov cx,bx |
neg cx |
inc cx |
cmp cx,52 |
ja value_out_of_range |
cmp cx,32 |
jbe fp_qword_small_shift |
sub cx,32 |
mov eax,edx |
xor edx,edx |
shr eax,cl |
jmp fp_qword_shift_done |
fp_qword_small_shift: |
mov ebx,edx |
shr edx,cl |
shrd eax,ebx,cl |
fp_qword_shift_done: |
mov bx,0 |
jnc fp_qword_exp_ok |
add eax,1 |
adc edx,0 |
test edx,1 shl 20 |
jz fp_qword_exp_ok |
and edx,1 shl 20 - 1 |
inc bx |
fp_qword_exp_ok: |
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: |
inc esi |
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 |
cmp word [edi+8],0 |
jne invalid_value |
mov eax,[edi+16] |
mov [symbol_identifier],eax |
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 |
cmp word [edi+8],0 |
jne invalid_value |
mov eax,[edi+16] |
mov [symbol_identifier],eax |
mov al,[edi+12] |
mov [value_type],al |
cmp al,4 |
jne check_dword_value |
mov [value_type],2 |
mov eax,[edi] |
cdq |
cmp edx,[edi+4] |
jne range_exceeded |
ret |
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 |
jne 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 |
cmp word [edi+8],0 |
jne invalid_value |
mov eax,[edi+16] |
mov [symbol_identifier],eax |
mov al,[edi+12] |
mov [value_type],al |
check_qword_value: |
mov eax,[edi] |
mov edx,[edi+4] |
ret |
get_count_value: |
mov [value_size],8 |
mov [size_override],-1 |
call calculate_expression |
cmp word [edi+8],0 |
jne invalid_value |
mov al,[edi+12] |
or al,al |
jz check_count_value |
cmp [error_line],0 |
jne check_count_value |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],invalid_use_of_symbol |
check_count_value: |
mov eax,[edi] |
mov edx,[edi+4] |
or edx,edx |
jnz invalid_count_value |
ret |
invalid_count_value: |
cmp [error_line],0 |
jne zero_count |
mov eax,[current_line] |
mov [error_line],eax |
mov [error],invalid_value |
zero_count: |
xor eax,eax |
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_word_value: |
mov [address_size],2 |
mov [value_size],2 |
jmp calculate_address |
get_address_dword_value: |
mov [address_size],4 |
mov [value_size],4 |
jmp calculate_address |
get_address_qword_value: |
mov [address_size],8 |
mov [value_size],8 |
jmp calculate_address |
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] |
mov [value_type],al |
cmp al,6 |
je special_address_type_32bit |
cmp al,5 |
je special_address_type_32bit |
ja invalid_use_of_symbol |
test al,1 |
jnz invalid_use_of_symbol |
or al,al |
jz address_size_ok |
shl al,5 |
jmp address_symbol_ok |
special_address_type_32bit: |
mov al,40h |
address_symbol_ok: |
mov ah,[address_size] |
or [address_size],al |
shr al,4 |
or ah,ah |
jz address_size_ok |
cmp al,ah |
je address_size_ok |
cmp ax,0804h |
jne address_sizes_do_not_agree |
cmp [value_type],2 |
ja value_type_correction_ok |
mov [value_type],2 |
value_type_correction_ok: |
mov eax,[edi] |
cdq |
cmp edx,[edi+4] |
je address_size_ok |
cmp [error_line],0 |
jne address_size_ok |
mov ecx,[current_line] |
mov [error_line],ecx |
mov [error],value_out_of_range |
address_size_ok: |
xor ebx,ebx |
xor ecx,ecx |
mov cl,[value_type] |
shl ecx,16 |
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 |
mov ah,[address_size] |
and ah,0Fh |
jz address_registers_sizes_ok |
cmp al,ah |
jne address_sizes_do_not_match |
address_registers_sizes_ok: |
cmp al,4 |
je sib_allowed |
cmp al,8 |
je sib_allowed |
cmp al,0Fh |
je check_ip_relative_address |
or cl,cl |
jz check_word_value |
cmp cl,1 |
je check_word_value |
jmp invalid_address |
address_sizes_do_not_match: |
cmp al,0Fh |
jne invalid_address |
mov al,bh |
and al,0Fh |
cmp al,ah |
jne invalid_address |
check_ip_relative_address: |
cmp bh,0F4h |
je check_dword_value |
cmp bh,0F8h |
jne invalid_address |
mov eax,[edi] |
cdq |
cmp edx,[edi+4] |
jne range_exceeded |
ret |
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_with_base |
cmp cl,3 |
je special_index_scale |
cmp cl,5 |
je special_index_scale |
cmp cl,9 |
je special_index_scale |
cmp cl,2 |
jne check_index_scale |
cmp bl,45h |
jne special_index_scale |
cmp [code_type],64 |
je special_index_scale |
cmp [segment_register],4 |
jne special_index_scale |
cmp [value_type],0 |
jne check_index_scale |
mov al,[edi] |
cbw |
cwde |
cmp eax,[edi] |
jne check_index_scale |
cdq |
cmp edx,[edi+4] |
jne check_immediate_address |
special_index_scale: |
mov bh,bl |
dec cl |
check_immediate_address: |
mov al,[address_size] |
and al,0Fh |
cmp al,2 |
je check_word_value |
cmp al,4 |
je check_dword_value |
cmp al,8 |
je check_qword_value |
or al,al |
jnz invalid_value |
cmp [code_type],64 |
jne check_dword_value |
jmp check_qword_value |
check_index_with_base: |
cmp cl,1 |
jne check_index_scale |
cmp bl,44h |
je swap_base_with_index |
cmp bl,84h |
je swap_base_with_index |
cmp [code_type],64 |
je check_for_rbp_base |
cmp bl,45h |
jne check_for_ebp_base |
cmp [segment_register],3 |
je swap_base_with_index |
jmp check_immediate_address |
check_for_ebp_base: |
cmp bh,45h |
jne check_immediate_address |
cmp [segment_register],4 |
jne check_immediate_address |
swap_base_with_index: |
xchg bl,bh |
jmp check_immediate_address |
check_for_rbp_base: |
cmp bh,45h |
je swap_base_with_index |
cmp bh,85h |
je swap_base_with_index |
jmp check_immediate_address |
check_index_scale: |
test cl,not 1111b |
jnz invalid_address |
mov al,cl |
dec al |
and al,cl |
jz check_immediate_address |
jmp invalid_address |
calculate_relative_offset: |
cmp [value_undefined],0 |
jne relative_offset_ok |
test bh,bh |
setne ch |
cmp bx,word [org_registers] |
je origin_registers_ok |
xchg bh,bl |
xchg ch,cl |
cmp bx,word [org_registers] |
jne invalid_value |
origin_registers_ok: |
cmp cx,word [org_registers+2] |
jne invalid_value |
add eax,dword [org_origin] |
adc edx,dword [org_origin+4] |
sub eax,edi |
sbb edx,0 |
mov bl,[value_type] |
or bl,bl |
je relative_offset_ok |
test bl,1 |
jnz invalid_use_of_symbol |
mov ecx,[address_symbol] |
mov [symbol_identifier],ecx |
cmp bl,6 |
je plt_relative_offset |
cmp bl,[labels_type] |
jne invalid_use_of_symbol |
mov [value_type],0 |
cmp ecx,[org_symbol] |
je relative_offset_ok |
mov [value_type],3 |
relative_offset_ok: |
ret |
plt_relative_offset: |
mov [value_type],7 |
ret |
|
calculate_logical_expression: |
xor al,al |
calculate_embedded_logical_expression: |
mov [logical_value_wrapping],al |
call get_logical_value |
logical_loop: |
cmp byte [esi],'|' |
je logical_or |
cmp byte [esi],'&' |
je logical_and |
ret |
logical_or: |
inc esi |
or al,al |
jnz logical_value_already_determined |
push eax |
call get_logical_value |
pop ebx |
or al,bl |
jmp logical_loop |
logical_and: |
inc esi |
or al,al |
jz logical_value_already_determined |
push eax |
call get_logical_value |
pop ebx |
and al,bl |
jmp logical_loop |
logical_value_already_determined: |
push eax |
call skip_logical_value |
jc invalid_expression |
pop eax |
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,0FFh |
je invalid_expression |
cmp al,88h |
je check_for_defined |
cmp al,89h |
je check_for_used |
cmp al,'0' |
je given_false |
cmp al,'1' |
je given_true |
call get_value |
mov bl,[value_type] |
push eax edx ebx |
mov al,[esi] |
or al,al |
jz logical_number |
cmp al,0Fh |
je logical_number |
cmp al,'}' |
je logical_number |
cmp al,'&' |
je logical_number |
cmp al,'|' |
je logical_number |
inc 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 ebx edx eax |
or bl,bl |
jnz 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,'!' |
je invalid_expression |
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 |
jmp return_false |
given_false: |
inc esi |
return_false: |
xor al,al |
jmp logical_value_ok |
given_true: |
inc esi |
return_true: |
or al,-1 |
jmp logical_value_ok |
logical_expression: |
lods byte [esi] |
mov dl,[logical_value_wrapping] |
push edx |
call calculate_embedded_logical_expression |
pop edx |
mov [logical_value_wrapping],dl |
push eax |
lods byte [esi] |
cmp al,'}' |
jne invalid_expression |
pop eax |
logical_value_ok: |
pop ebx |
xor al,bl |
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,'!' |
je skip_expression |
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 |