diff --git a/lib/linguist/languages.yml b/lib/linguist/languages.yml index d9c3f4f2..42ce978d 100644 --- a/lib/linguist/languages.yml +++ b/lib/linguist/languages.yml @@ -157,6 +157,7 @@ Assembly: - nasm extensions: - .asm + - .inc Augeas: type: programming diff --git a/samples/Assembly/ASSEMBLE.inc b/samples/Assembly/ASSEMBLE.inc new file mode 100644 index 00000000..c4ffdae3 --- /dev/null +++ b/samples/Assembly/ASSEMBLE.inc @@ -0,0 +1,2048 @@ + +; flat assembler core +; Copyright (c) 1999-2014, Tomasz Grysztar. +; All rights reserved. + +assembler: + xor eax,eax + mov [stub_size],eax + mov [current_pass],ax + mov [resolver_flags],eax + mov [number_of_sections],eax + mov [actual_fixups_size],eax + assembler_loop: + mov eax,[labels_list] + mov [tagged_blocks],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 [addressing_space],eax + mov [error_line],eax + mov [counter],eax + mov [format_flags],eax + mov [number_of_relocations],eax + mov [undefined_data_end],eax + mov [file_extension],eax + mov [next_pass_needed],al + mov [output_format],al + mov [adjustment_sign],al + mov [code_type],16 + call init_addressing_space + pass_loop: + call assemble_line + jnc pass_loop + mov eax,[additional_memory_end] + cmp eax,[structures_buffer] + je pass_done + sub eax,18h + 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,LABEL_STRUCTURE_SIZE + 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 + cmp [error],undefined_symbol + jne error_confirmed + mov eax,[error_info] + or eax,eax + jz error_confirmed + test byte [eax+8],1 + jnz next_pass + error_confirmed: + call error_handler + error_handler: + mov eax,[error] + sub eax,error_handler + add [esp],eax + ret + next_pass: + inc [current_pass] + mov ax,[current_pass] + cmp ax,[passes_limit] + je code_cannot_be_generated + jmp assembler_loop + assemble_ok: + ret + +create_addressing_space: + mov ebx,[addressing_space] + test ebx,ebx + jz init_addressing_space + test byte [ebx+0Ah],1 + jnz illegal_instruction + mov eax,edi + sub eax,[ebx+18h] + mov [ebx+1Ch],eax + init_addressing_space: + mov ebx,[tagged_blocks] + mov dword [ebx-4],10h + mov dword [ebx-8],20h + sub ebx,8+20h + cmp ebx,edi + jbe out_of_memory + mov [tagged_blocks],ebx + mov [addressing_space],ebx + xor eax,eax + mov [ebx],edi + mov [ebx+4],eax + mov [ebx+8],eax + mov [ebx+10h],eax + mov [ebx+14h],eax + mov [ebx+18h],edi + mov [ebx+1Ch],eax + ret + +assemble_line: + mov eax,[tagged_blocks] + 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,4 + je label_addressing_space + 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 instruction_assembled + new_line: + lods dword [esi] + mov [current_line],eax + mov [prefixed_instruction],0 + cmp [symbols_file],0 + je continue_line + cmp [next_pass_needed],0 + jne continue_line + mov ebx,[tagged_blocks] + mov dword [ebx-4],1 + mov dword [ebx-8],14h + sub ebx,8+14h + cmp ebx,edi + jbe out_of_memory + mov [tagged_blocks],ebx + mov [ebx],eax + mov [ebx+4],edi + mov eax,[addressing_space] + mov [ebx+8],eax + mov al,[code_type] + mov [ebx+10h],al + 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 [label_size],al + call make_label + jmp continue_line + make_label: + mov eax,edi + xor edx,edx + xor cl,cl + mov ebp,[addressing_space] + sub eax,[ds:ebp] + sbb edx,[ds:ebp+4] + sbb cl,[ds:ebp+8] + jp label_value_ok + call recoverable_overflow + label_value_ok: + mov [address_sign],cl + test byte [ds:ebp+0Ah],1 + jnz make_virtual_label + or byte [ebx+9],1 + xchg eax,[ebx] + xchg edx,[ebx+4] + mov ch,[ebx+9] + shr ch,1 + and ch,1 + neg ch + sub eax,[ebx] + sbb edx,[ebx+4] + sbb ch,cl + mov dword [adjustment],eax + mov dword [adjustment+4],edx + mov [adjustment_sign],ch + or al,ch + or eax,edx + setnz ah + jmp finish_label + 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: + mov ebp,[addressing_space] + mov ch,[ds:ebp+9] + mov cl,[label_size] + mov edx,[ds:ebp+14h] + mov ebp,[ds:ebp+10h] + finish_label_symbol: + mov al,[address_sign] + xor al,[ebx+9] + and al,10b + or ah,al + xor [ebx+9],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 + cmp ebp,[ebx+12] + mov [ebx+12],ebp + setne al + or ah,al + or ch,ch + jz label_symbol_ok + cmp edx,[ebx+20] + mov [ebx+20],edx + setne al + or ah,al + label_symbol_ok: + mov cx,[current_pass] + xchg [ebx+16],cx + mov edx,[current_line] + mov [ebx+28],edx + and byte [ebx+8],not 2 + test byte [ebx+8],1 + jz new_label + cmp cx,[ebx+16] + je symbol_already_defined + btr dword [ebx+8],10 + jc requalified_label + inc cx + sub cx,[ebx+16] + setnz al + or ah,al + jz label_made + test byte [ebx+8],8 + jz label_made + mov cx,[current_pass] + cmp cx,[ebx+18] + jne label_made + requalified_label: + or [next_pass_needed],-1 + label_made: + ret + new_label: + or byte [ebx+8],1 + ret + 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 + or dl,4 + mov [eax+8],dl + get_constant_value: + push eax + mov al,byte [esi-1] + push eax + or [size_override],-1 + call get_value + pop ebx + mov ch,bl + pop ebx + pop ecx + test cl,4 + jnz constant_referencing_mode_ok + and byte [ebx+8],not 4 + constant_referencing_mode_ok: + 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 + mov al,[value_sign] + xor al,[ebx+9] + and al,10b + or ah,al + xor [ebx+9],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 + mov edx,[current_line] + mov [ebx+28],edx + 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 + and byte [ebx+9],not 4 + jmp instruction_assembled + redeclare_constant: + btr dword [ebx+8],10 + jc requalified_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 + requalified_constant: + or [next_pass_needed],-1 + jmp instruction_assembled + new_constant: + or byte [ebx+8],1+2 + jmp instruction_assembled + label_addressing_space: + lods dword [esi] + cmp eax,0Fh + jb invalid_use_of_symbol + je reserved_word_used_as_symbol + mov cx,[current_pass] + test byte [eax+8],1 + jz make_addressing_space_label + cmp cx,[eax+16] + je symbol_already_defined + test byte [eax+9],4 + jnz make_addressing_space_label + or [next_pass_needed],-1 + make_addressing_space_label: + mov dx,[eax+8] + and dx,not (2 or 100h) + or dx,1 or 4 or 400h + mov [eax+8],dx + mov [eax+16],cx + mov edx,[current_line] + mov [eax+28],edx + mov ebx,[addressing_space] + mov [eax],ebx + or byte [ebx+0Ah],2 + jmp continue_line + assemble_instruction: +; mov [operand_size],0 +; mov [size_override],0 +; mov [operand_prefix],0 +; mov [opcode_prefix],0 + and dword [operand_size],0 +; mov [rex_prefix],0 +; mov [vex_required],0 +; mov [vex_register],0 +; mov [immediate_size],0 + and dword [rex_prefix],0 + call instruction_handler + instruction_handler: + movzx ebx,word [esi] + mov al,[esi+2] + add esi,3 + add [esp],ebx + ret + 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 + +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 + push eax + mov ebx,[addressing_space] + mov eax,edi + sub eax,[ebx+18h] + mov [ebx+1Ch],eax + test byte [ebx+0Ah],1 + jnz in_virtual + call init_addressing_space + jmp org_space_ok + in_virtual: + call close_virtual_addressing_space + call init_addressing_space + or byte [ebx+0Ah],1 + org_space_ok: + pop eax + mov [ebx+9],cl + mov cl,[value_sign] + sub [ebx],eax + sbb [ebx+4],edx + sbb byte [ebx+8],cl + jp org_value_ok + call recoverable_overflow + org_value_ok: + mov edx,[symbol_identifier] + mov [ebx+14h],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 + mov [label_size],0 + 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 [label_size],ah + label_size_ok: + cmp byte [esi],80h + je get_free_label_value + call make_label + jmp instruction_assembled + get_free_label_value: + inc esi + lods byte [esi] + cmp al,'(' + jne invalid_argument + push ebx ecx + or byte [ebx+8],4 + 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 + and byte [ebx+8],not 4 + mov ch,[value_type] + test ch,1 + jnz 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 + mov edx,[address_symbol] + mov cl,[label_size] + call finish_label_symbol + 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 + and dword [value],0 + and dword [value+4],0 + lods byte [esi] + cmp al,82h + jne invalid_argument + call get_data_point + jc value_loaded + push esi edi + mov esi,ebx + mov edi,value + rep movs byte [edi],[esi] + pop edi esi + value_loaded: + mov [value_sign],0 + mov eax,dword [value] + mov edx,dword [value+4] + pop ebx + xor cx,cx + jmp make_constant + get_data_point: + mov ebx,[addressing_space] + mov ecx,edi + sub ecx,[ebx+18h] + mov [ebx+1Ch],ecx + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],11h + jne get_data_address + cmp word [esi+1+4],'):' + jne get_data_address + inc esi + lods dword [esi] + add esi,2 + cmp byte [esi],'(' + jne invalid_argument + inc esi + cmp eax,0Fh + jbe reserved_word_used_as_symbol + mov edx,undefined_symbol + test byte [eax+8],1 + jz addressing_space_unavailable + mov edx,symbol_out_of_scope + mov cx,[eax+16] + cmp cx,[current_pass] + jne addressing_space_unavailable + test byte [eax+9],4 + jz invalid_use_of_symbol + mov ebx,eax + mov ax,[current_pass] + mov [ebx+18],ax + or byte [ebx+8],8 + cmp [symbols_file],0 + je get_addressing_space + cmp [next_pass_needed],0 + jne get_addressing_space + call store_label_reference + get_addressing_space: + mov ebx,[ebx] + get_data_address: + push ebx + cmp byte [esi],'.' + je invalid_value + or [size_override],-1 + call get_address_value + pop ebp + call calculate_relative_offset + cmp [next_pass_needed],0 + jne data_address_type_ok + cmp [value_type],0 + jne invalid_use_of_symbol + data_address_type_ok: + mov ebx,edi + xor ecx,ecx + add ebx,eax + adc edx,ecx + mov eax,ebx + sub eax,[ds:ebp+18h] + sbb edx,ecx + jnz bad_data_address + mov cl,[operand_size] + add eax,ecx + cmp eax,[ds:ebp+1Ch] + ja bad_data_address + clc + ret + addressing_space_unavailable: + cmp [error_line],0 + jne get_data_address + push [current_line] + pop [error_line] + mov [error],edx + mov [error_info],eax + jmp get_data_address + bad_data_address: + call recoverable_overflow + stc + ret +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: + or [size_override],-1 + 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 byte [esi] + cmp al,80h + jne invalid_argument + call get_data_point + jc instruction_assembled + push esi edi + mov esi,value + mov edi,ebx + rep movs byte [edi],[esi] + mov eax,edi + pop edi esi + cmp ebx,[undefined_data_end] + jae instruction_assembled + cmp eax,[undefined_data_start] + jbe instruction_assembled + mov [undefined_data_start],eax + 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,[tagged_blocks] + sub edi,8 + sub edi,eax + cmp edi,[esp] + jbe out_of_memory + mov [tagged_blocks],edi + rep movs byte [edi],[esi] + stos dword [edi] + xor eax,eax + stos dword [edi] + pop edi + inc esi + jmp display_next + display_byte: + call get_byte_value + push edi + mov edi,[tagged_blocks] + sub edi,8+1 + mov [tagged_blocks],edi + stos byte [edi] + mov eax,1 + stos dword [edi] + dec eax + stos dword [edi] + pop edi + display_next: + cmp edi,[tagged_blocks] + ja out_of_memory + lods byte [esi] + cmp al,',' + je display_directive + dec esi + jmp instruction_assembled +show_display_buffer: + mov eax,[tagged_blocks] + or eax,eax + jz display_done + mov esi,[labels_list] + cmp esi,eax + je display_done + display_messages: + sub esi,8 + mov eax,[esi+4] + mov ecx,[esi] + sub esi,ecx + test eax,eax + jnz skip_block + push esi + call display_block + pop esi + skip_block: + cmp esi,[tagged_blocks] + jne display_messages + display_done: + ret + +times_directive: + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + call get_count_value + cmp eax,0 + je zero_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 + zero_times: + call skip_symbol + jnc zero_times + 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] + or bh,bh + setnz ch + jmp set_virtual + virtual_at_current: + dec esi + mov ebp,[addressing_space] + mov al,[ds:ebp+9] + mov [value_type],al + mov eax,edi + xor edx,edx + xor cl,cl + sub eax,[ds:ebp] + sbb edx,[ds:ebp+4] + sbb cl,[ds:ebp+8] + mov [address_sign],cl + mov bx,[ds:ebp+10h] + mov cx,[ds:ebp+10h+2] + xchg bh,bl + xchg ch,cl + mov ebp,[ds:ebp+14h] + set_virtual: + xchg bl,bh + xchg cl,ch + shl ecx,16 + mov cx,bx + push ecx eax + call allocate_structure_data + mov word [ebx],virtual_directive-instruction_handler + mov ecx,[addressing_space] + mov [ebx+12],ecx + mov [ebx+8],edi + mov ecx,[current_line] + mov [ebx+4],ecx + mov ebx,[addressing_space] + mov eax,edi + sub eax,[ebx+18h] + mov [ebx+1Ch],eax + call init_addressing_space + or byte [ebx+0Ah],1 + pop eax + mov cl,[address_sign] + not eax + not edx + not cl + add eax,1 + adc edx,0 + adc cl,0 + add eax,edi + adc edx,0 + adc cl,0 + mov [ebx],eax + mov [ebx+4],edx + mov [ebx+8],cl + pop dword [ebx+10h] + mov [ebx+14h],ebp + mov al,[value_type] + test al,1 + jnz invalid_use_of_symbol + mov [ebx+9],al + jmp instruction_assembled + allocate_structure_data: + mov ebx,[structures_buffer] + sub ebx,18h + 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] + je structure_data_found + add ebx,18h + jmp scan_structures + structure_data_found: + ret + no_such_structure: + stc + ret + end_virtual: + call find_structure_data + jc unexpected_instruction + push ebx + call close_virtual_addressing_space + pop ebx + mov eax,[ebx+12] + mov [addressing_space],eax + mov edi,[ebx+8] + remove_structure_data: + push esi edi + mov ecx,ebx + sub ecx,[structures_buffer] + shr ecx,2 + lea esi,[ebx-4] + lea edi,[esi+18h] + std + rep movs dword [edi],[esi] + cld + add [structures_buffer],18h + pop edi esi + ret + close_virtual_addressing_space: + mov ebx,[addressing_space] + mov eax,edi + sub eax,[ebx+18h] + mov [ebx+1Ch],eax + test byte [ebx+0Ah],2 + jz addressing_space_closed + push esi edi ecx edx + mov ecx,eax + mov eax,[tagged_blocks] + mov dword [eax-4],11h + mov dword [eax-8],ecx + sub eax,8 + sub eax,ecx + mov [tagged_blocks],eax + lea edi,[eax+ecx-1] + xchg eax,[ebx+18h] + lea esi,[eax+ecx-1] + mov eax,edi + sub eax,esi + std + shr ecx,1 + jnc virtual_byte_ok + movs byte [edi],[esi] + virtual_byte_ok: + dec esi + dec edi + shr ecx,1 + jnc virtual_word_ok + movs word [edi],[esi] + virtual_word_ok: + sub esi,2 + sub edi,2 + rep movs dword [edi],[esi] + cld + xor edx,edx + add [ebx],eax + adc dword [ebx+4],edx + adc byte [ebx+8],dl + pop edx ecx edi esi + addressing_space_closed: + 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_count_value + cmp eax,0 + je zero_repeat + call allocate_structure_data + mov word [ebx],repeat_directive-instruction_handler + 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 + 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-instruction_handler + jne unexpected_instruction + ret +while_directive: + cmp [prefixed_instruction],0 + jne unexpected_instruction + call allocate_structure_data + mov word [ebx],while_directive-instruction_handler + 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-instruction_handler + 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-instruction_handler + 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-instruction_handler + 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-instruction_handler + 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-instruction_handler + 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-instruction_handler + je else_found + cmp ax,if_directive-instruction_handler + jne unexpected_instruction + stc + ret + else_found: + clc + ret + find_end_if: + call find_structure_end + cmp ax,if_directive-instruction_handler + jne unexpected_instruction + ret + find_structure_end: + push [error_line] + mov eax,[current_line] + mov [error_line],eax + find_end_directive: + call skip_symbol + jnc find_end_directive + 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-instruction_handler + je find_end_directive + add esi,4 + cmp ax,repeat_directive-instruction_handler + je skip_repeat + cmp ax,while_directive-instruction_handler + je skip_while + cmp ax,if_directive-instruction_handler + je skip_if + cmp ax,else_directive-instruction_handler + je structure_end + cmp ax,end_directive-instruction_handler + jne find_end_directive + cmp byte [esi],1 + jne find_end_directive + mov ax,[esi+1] + add esi,4 + cmp ax,repeat_directive-instruction_handler + je structure_end + cmp ax,while_directive-instruction_handler + je structure_end + cmp ax,if_directive-instruction_handler + 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-instruction_handler + 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-instruction_handler + je end_virtual + cmp ax,repeat_directive-instruction_handler + je end_repeat + cmp ax,while_directive-instruction_handler + je end_while + cmp ax,if_directive-instruction_handler + je end_if + cmp ax,data_directive-instruction_handler + 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-instruction_handler + je break_repeat + cmp ax,while_directive-instruction_handler + je break_while + cmp ax,if_directive-instruction_handler + je break_if + add ebx,18h + 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,[tagged_blocks] + ja out_of_memory + rep movs byte [edi],[esi] + inc esi + ret + undefined_data: + mov ebp,[addressing_space] + test byte [ds:ebp+0Ah],1 + jz 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,[tagged_blocks] + 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_count_value + inc esi + or eax,eax + jz duplicate_zero_times + cmp byte [esi],'{' + jne duplicate_single_data_value + inc esi + duplicate_data: + push eax esi + duplicated_values: + cmp edi,[tagged_blocks] + 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,[tagged_blocks] + 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 + duplicate_zero_times: + cmp byte [esi],'{' + jne skip_single_data_value + inc esi + skip_data_value: + call skip_symbol + jc invalid_argument + cmp byte [esi],'}' + jne skip_data_value + inc esi + jmp data_defined + skip_single_data_value: + call skip_symbol + jmp data_defined + simple_data_value: + cmp edi,[tagged_blocks] + 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 + and 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,[tagged_blocks] + 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 + and 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 + and dword [edi],0 + scas dword [edi] + and 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 + and dword [edi],0 + scas dword [edi] + and 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 + and dword [edi],0 + scas dword [edi] + and dword [edi],0 + scas dword [edi] + and 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 + jo value_out_of_range + cmp ax,7FFFh + jge value_out_of_range + cmp ax,0 + jg tword_exp_ok + mov cx,ax + neg cx + inc cx + cmp cx,64 + jae value_out_of_range + cmp cx,32 + ja large_shift + mov eax,[esi] + mov edx,[esi+4] + mov ebx,edx + shr edx,cl + shrd eax,ebx,cl + jmp tword_mantissa_shift_done + large_shift: + sub cx,32 + xor edx,edx + mov eax,[esi+4] + shr eax,cl + tword_mantissa_shift_done: + jnc store_shifted_mantissa + add eax,1 + adc edx,0 + store_shifted_mantissa: + mov [edi-8],eax + mov [edi-4],edx + xor ax,ax + test edx,1 shl 31 + jz tword_exp_ok + inc ax + tword_exp_ok: + 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 + cmp byte [esi],':' + jne invalid_operand + 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_count_value + pop ebx + mov edx,eax + sub [esp],edx + jc value_out_of_range + 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_count_value + pop edx ebx + cmp eax,[esp] + ja value_out_of_range + mov [esp],eax + size_ok: + xor al,al + call lseek + pop ecx + mov edx,edi + add edi,ecx + jc out_of_memory + cmp edi,[tagged_blocks] + 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 eax,[current_line] + find_current_source_path: + mov esi,[eax] + test byte [eax+7],80h + jz get_current_path + mov eax,[eax+8] + jmp find_current_source_path + 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 expand_path + pop edx + mov esi,edx + call open + jnc file_opened + mov edx,[include_paths] + search_in_include_paths: + push edx esi + mov edi,esi + mov esi,[esp+4] + call get_include_directory + mov [esp+4],esi + mov esi,[esp+8] + call expand_path + pop edx + mov esi,edx + call open + pop edx + jnc file_opened + cmp byte [edx],0 + jne search_in_include_paths + mov edi,esi + mov esi,[esp] + push edi + call expand_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_count_value + mov ecx,eax + mov edx,ecx + add edx,edi + jc out_of_memory + cmp edx,[tagged_blocks] + 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_words: + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + call get_count_value + mov ecx,eax + mov edx,ecx + shl edx,1 + jc out_of_memory + add edx,edi + jc out_of_memory + cmp edx,[tagged_blocks] + 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_count_value + 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,[tagged_blocks] + 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_count_value + 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,[tagged_blocks] + 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_count_value + 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,[tagged_blocks] + 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_count_value + 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,[tagged_blocks] + 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_count_value + mov edx,eax + dec edx + test eax,edx + jnz invalid_align_value + or eax,eax + jz invalid_align_value + cmp eax,1 + je instruction_assembled + mov ecx,edi + mov ebp,[addressing_space] + sub ecx,[ds:ebp] + cmp dword [ds:ebp+10h],0 + jne section_not_aligned_enough + cmp byte [ds:ebp+9],0 + je make_alignment + cmp [output_format],3 + je pe_alignment + mov ebx,[ds:ebp+14h] + 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,[tagged_blocks] + ja out_of_memory + push edi + cmp [next_pass_needed],0 + je nops + add edi,ecx + jmp reserved_data + invalid_align_value: + cmp [error_line],0 + jne instruction_assembled + mov eax,[current_line] + mov [error_line],eax + mov [error],invalid_value + jmp instruction_assembled + 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 +err_directive: + mov al,[esi] + cmp al,0Fh + je invoked_error + or al,al + jz invoked_error + jmp extra_characters_on_line +assert_directive: + call calculate_logical_expression + or al,al + jnz instruction_assembled + cmp [error_line],0 + jne instruction_assembled + mov eax,[current_line] + mov [error_line],eax + mov [error],assertion_failed + jmp instruction_assembled diff --git a/samples/Assembly/FASM.asm b/samples/Assembly/FASM.asm new file mode 100644 index 00000000..9a2201ae --- /dev/null +++ b/samples/Assembly/FASM.asm @@ -0,0 +1,350 @@ + +; flat assembler interface for Win32 +; Copyright (c) 1999-2014, Tomasz Grysztar. +; All rights reserved. + + format PE console + +section '.text' code readable executable + +start: + + mov [con_handle],STD_OUTPUT_HANDLE + mov esi,_logo + call display_string + + call get_params + jc information + + call init_memory + + mov esi,_memory_prefix + call display_string + mov eax,[memory_end] + sub eax,[memory_start] + add eax,[additional_memory_end] + sub eax,[additional_memory] + shr eax,10 + call display_number + mov esi,_memory_suffix + call display_string + + call [GetTickCount] + 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 [GetTickCount] + 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 + jmp exit_program + +information: + mov esi,_usage + call display_string + mov al,1 + jmp exit_program + +get_params: + mov [input_file],0 + mov [output_file],0 + mov [symbols_file],0 + mov [memory_setting],0 + mov [passes_limit],100 + call [GetCommandLine] + mov esi,eax + mov edi,params + find_command_start: + lodsb + cmp al,20h + je find_command_start + cmp al,22h + je skip_quoted_name + skip_name: + lodsb + cmp al,20h + je find_param + or al,al + jz all_params + jmp skip_name + skip_quoted_name: + lodsb + cmp al,22h + je find_param + or al,al + jz all_params + jmp skip_quoted_name + find_param: + lodsb + cmp al,20h + je find_param + cmp al,'-' + je option_param + cmp al,0Dh + je all_params + or al,al + jz all_params + cmp [input_file],0 + jne get_output_file + mov [input_file],edi + jmp process_param + get_output_file: + cmp [output_file],0 + jne bad_params + mov [output_file],edi + process_param: + cmp al,22h + je string_param + copy_param: + stosb + lodsb + cmp al,20h + je param_end + cmp al,0Dh + je param_end + or al,al + jz param_end + jmp copy_param + string_param: + lodsb + cmp al,22h + je string_param_end + cmp al,0Dh + je param_end + or al,al + jz param_end + stosb + jmp string_param + option_param: + lodsb + cmp al,'m' + je memory_option + cmp al,'M' + je memory_option + cmp al,'p' + je passes_option + cmp al,'P' + je passes_option + cmp al,'s' + je symbols_option + cmp al,'S' + je symbols_option + bad_params: + stc + ret + get_option_value: + xor eax,eax + mov edx,eax + get_option_digit: + lodsb + cmp al,20h + je option_value_ok + cmp al,0Dh + je option_value_ok + or al,al + jz option_value_ok + sub al,30h + jc invalid_option_value + cmp al,9 + ja invalid_option_value + imul edx,10 + jo invalid_option_value + add edx,eax + jc invalid_option_value + jmp get_option_digit + option_value_ok: + dec esi + clc + ret + invalid_option_value: + stc + ret + memory_option: + lodsb + cmp al,20h + je memory_option + cmp al,0Dh + je bad_params + or al,al + jz bad_params + dec esi + call get_option_value + or edx,edx + jz bad_params + cmp edx,1 shl (32-10) + jae bad_params + mov [memory_setting],edx + jmp find_param + passes_option: + lodsb + cmp al,20h + je passes_option + cmp al,0Dh + je bad_params + or al,al + jz bad_params + dec esi + call get_option_value + or edx,edx + jz bad_params + cmp edx,10000h + ja bad_params + mov [passes_limit],dx + jmp find_param + symbols_option: + mov [symbols_file],edi + find_symbols_file_name: + lodsb + cmp al,20h + jne process_param + jmp find_symbols_file_name + param_end: + dec esi + string_param_end: + xor al,al + stosb + jmp find_param + all_params: + cmp [input_file],0 + je bad_params + clc + ret + +include 'system.inc' + +include '..\errors.inc' +include '..\symbdump.inc' +include '..\preproce.inc' +include '..\parser.inc' +include '..\exprpars.inc' +include '..\assemble.inc' +include '..\exprcalc.inc' +include '..\formats.inc' +include '..\x86_64.inc' +include '..\avx.inc' + +include '..\tables.inc' +include '..\messages.inc' + +section '.data' data readable writeable + +include '..\version.inc' + +_copyright db 'Copyright (c) 1999-2014, Tomasz Grysztar',0Dh,0Ah,0 + +_logo db 'flat assembler version ',VERSION_STRING,0 +_usage db 0Dh,0Ah + db 'usage: fasm [output]',0Dh,0Ah + db 'optional settings:',0Dh,0Ah + db ' -m set the limit in kilobytes for the available memory',0Dh,0Ah + db ' -p set the maximum allowed number of passes',0Dh,0Ah + db ' -s dump symbolic information for debugging',0Dh,0Ah + db 0 +_memory_prefix db ' (',0 +_memory_suffix db ' kilobytes memory)',0Dh,0Ah,0 +_passes_suffix db ' passes, ',0 +_seconds_suffix db ' seconds, ',0 +_bytes_suffix db ' bytes.',0Dh,0Ah,0 + +align 4 + +include '..\variable.inc' + +con_handle dd ? +memory_setting dd ? +start_time dd ? +bytes_count dd ? +displayed_count dd ? +character db ? +last_displayed rb 2 + +params rb 1000h +options rb 1000h +buffer rb 4000h + +stack 10000h + +section '.idata' import data readable writeable + + dd 0,0,0,rva kernel_name,rva kernel_table + dd 0,0,0,0,0 + + kernel_table: + ExitProcess dd rva _ExitProcess + CreateFile dd rva _CreateFileA + ReadFile dd rva _ReadFile + WriteFile dd rva _WriteFile + CloseHandle dd rva _CloseHandle + SetFilePointer dd rva _SetFilePointer + GetCommandLine dd rva _GetCommandLineA + GetEnvironmentVariable dd rva _GetEnvironmentVariable + GetStdHandle dd rva _GetStdHandle + VirtualAlloc dd rva _VirtualAlloc + VirtualFree dd rva _VirtualFree + GetTickCount dd rva _GetTickCount + GetSystemTime dd rva _GetSystemTime + GlobalMemoryStatus dd rva _GlobalMemoryStatus + dd 0 + + kernel_name db 'KERNEL32.DLL',0 + + _ExitProcess dw 0 + db 'ExitProcess',0 + _CreateFileA dw 0 + db 'CreateFileA',0 + _ReadFile dw 0 + db 'ReadFile',0 + _WriteFile dw 0 + db 'WriteFile',0 + _CloseHandle dw 0 + db 'CloseHandle',0 + _SetFilePointer dw 0 + db 'SetFilePointer',0 + _GetCommandLineA dw 0 + db 'GetCommandLineA',0 + _GetEnvironmentVariable dw 0 + db 'GetEnvironmentVariableA',0 + _GetStdHandle dw 0 + db 'GetStdHandle',0 + _VirtualAlloc dw 0 + db 'VirtualAlloc',0 + _VirtualFree dw 0 + db 'VirtualFree',0 + _GetTickCount dw 0 + db 'GetTickCount',0 + _GetSystemTime dw 0 + db 'GetSystemTime',0 + _GlobalMemoryStatus dw 0 + db 'GlobalMemoryStatus',0 + +section '.reloc' fixups data readable discardable diff --git a/samples/Assembly/SYSTEM.inc b/samples/Assembly/SYSTEM.inc new file mode 100644 index 00000000..77a61d29 --- /dev/null +++ b/samples/Assembly/SYSTEM.inc @@ -0,0 +1,503 @@ + +; flat assembler interface for Win32 +; Copyright (c) 1999-2014, Tomasz Grysztar. +; All rights reserved. + +CREATE_NEW = 1 +CREATE_ALWAYS = 2 +OPEN_EXISTING = 3 +OPEN_ALWAYS = 4 +TRUNCATE_EXISTING = 5 + +FILE_SHARE_READ = 1 +FILE_SHARE_WRITE = 2 +FILE_SHARE_DELETE = 4 + +GENERIC_READ = 80000000h +GENERIC_WRITE = 40000000h + +STD_INPUT_HANDLE = 0FFFFFFF6h +STD_OUTPUT_HANDLE = 0FFFFFFF5h +STD_ERROR_HANDLE = 0FFFFFFF4h + +MEM_COMMIT = 1000h +MEM_RESERVE = 2000h +MEM_DECOMMIT = 4000h +MEM_RELEASE = 8000h +MEM_FREE = 10000h +MEM_PRIVATE = 20000h +MEM_MAPPED = 40000h +MEM_RESET = 80000h +MEM_TOP_DOWN = 100000h + +PAGE_NOACCESS = 1 +PAGE_READONLY = 2 +PAGE_READWRITE = 4 +PAGE_WRITECOPY = 8 +PAGE_EXECUTE = 10h +PAGE_EXECUTE_READ = 20h +PAGE_EXECUTE_READWRITE = 40h +PAGE_EXECUTE_WRITECOPY = 80h +PAGE_GUARD = 100h +PAGE_NOCACHE = 200h + +init_memory: + xor eax,eax + mov [memory_start],eax + mov eax,esp + and eax,not 0FFFh + add eax,1000h-10000h + mov [stack_limit],eax + mov eax,[memory_setting] + shl eax,10 + jnz allocate_memory + push buffer + call [GlobalMemoryStatus] + mov eax,dword [buffer+20] + mov edx,dword [buffer+12] + cmp eax,0 + jl large_memory + cmp edx,0 + jl large_memory + shr eax,2 + add eax,edx + jmp allocate_memory + large_memory: + mov eax,80000000h + allocate_memory: + mov edx,eax + shr edx,2 + mov ecx,eax + sub ecx,edx + mov [memory_end],ecx + mov [additional_memory_end],edx + push PAGE_READWRITE + push MEM_COMMIT + push eax + push 0 + call [VirtualAlloc] + or eax,eax + jz not_enough_memory + mov [memory_start],eax + add eax,[memory_end] + mov [memory_end],eax + mov [additional_memory],eax + add [additional_memory_end],eax + ret + not_enough_memory: + mov eax,[additional_memory_end] + shl eax,1 + cmp eax,4000h + jb out_of_memory + jmp allocate_memory + +exit_program: + movzx eax,al + push eax + mov eax,[memory_start] + test eax,eax + jz do_exit + push MEM_RELEASE + push 0 + push eax + call [VirtualFree] + do_exit: + call [ExitProcess] + +get_environment_variable: + mov ecx,[memory_end] + sub ecx,edi + cmp ecx,4000h + jbe buffer_for_variable_ok + mov ecx,4000h + buffer_for_variable_ok: + push ecx + push edi + push esi + call [GetEnvironmentVariable] + add edi,eax + cmp edi,[memory_end] + jae out_of_memory + ret + +open: + push 0 + push 0 + push OPEN_EXISTING + push 0 + push FILE_SHARE_READ + push GENERIC_READ + push edx + call [CreateFile] + cmp eax,-1 + je file_error + mov ebx,eax + clc + ret + file_error: + stc + ret +create: + push 0 + push 0 + push CREATE_ALWAYS + push 0 + push FILE_SHARE_READ + push GENERIC_WRITE + push edx + call [CreateFile] + cmp eax,-1 + je file_error + mov ebx,eax + clc + ret +write: + push 0 + push bytes_count + push ecx + push edx + push ebx + call [WriteFile] + or eax,eax + jz file_error + clc + ret +read: + mov ebp,ecx + push 0 + push bytes_count + push ecx + push edx + push ebx + call [ReadFile] + or eax,eax + jz file_error + cmp ebp,[bytes_count] + jne file_error + clc + ret +close: + push ebx + call [CloseHandle] + ret +lseek: + movzx eax,al + push eax + push 0 + push edx + push ebx + call [SetFilePointer] + ret + +display_string: + push [con_handle] + call [GetStdHandle] + mov ebp,eax + mov edi,esi + or ecx,-1 + xor al,al + repne scasb + neg ecx + sub ecx,2 + push 0 + push bytes_count + push ecx + push esi + push ebp + call [WriteFile] + ret +display_character: + push ebx + mov [character],dl + push [con_handle] + call [GetStdHandle] + mov ebx,eax + push 0 + push bytes_count + push 1 + push character + push ebx + call [WriteFile] + pop ebx + 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 ecx + call display_character + pop ecx + 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: + mov [displayed_count],0 + call show_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 word [buffer],0A0Dh + push [con_handle] + call [GetStdHandle] + push 0 + push bytes_count + push 2 + push buffer + push eax + call [WriteFile] + line_break_ok: + ret +display_block: + add [displayed_count],ecx + cmp ecx,1 + ja take_last_two_characters + jb block_displayed + mov al,[last_displayed+1] + mov ah,[esi] + mov word [last_displayed],ax + jmp block_ok + take_last_two_characters: + mov ax,[esi+ecx-2] + mov word [last_displayed],ax + block_ok: + push ecx + push [con_handle] + call [GetStdHandle] + pop ecx + push 0 + push bytes_count + push ecx + push esi + push eax + call [WriteFile] + block_displayed: + ret + +fatal_error: + mov [con_handle],STD_ERROR_HANDLE + mov esi,error_prefix + call display_string + pop esi + call display_string + mov esi,error_suffix + call display_string + mov al,0FFh + jmp exit_program +assembler_error: + mov [con_handle],STD_ERROR_HANDLE + call display_user_messages + push dword 0 + mov ebx,[current_line] + get_error_lines: + mov eax,[ebx] + cmp byte [eax],0 + je get_next_error_line + push ebx + test byte [ebx+7],80h + jz display_error_line + mov edx,ebx + find_definition_origin: + mov edx,[edx+12] + test byte [edx+7],80h + jnz find_definition_origin + push edx + get_next_error_line: + mov ebx,[ebx+8] + jmp get_error_lines + display_error_line: + mov esi,[ebx] + call display_string + mov esi,line_number_start + call display_string + mov eax,[ebx+4] + and eax,7FFFFFFFh + call display_number + mov dl,']' + call display_character + pop esi + cmp ebx,esi + je line_number_ok + mov dl,20h + call display_character + push esi + mov esi,[esi] + movzx ecx,byte [esi] + inc esi + call display_block + mov esi,line_number_start + call display_string + pop esi + mov eax,[esi+4] + and eax,7FFFFFFFh + call display_number + mov dl,']' + call display_character + line_number_ok: + mov esi,line_data_start + call display_string + mov esi,ebx + mov edx,[esi] + call open + mov al,2 + xor edx,edx + call lseek + mov edx,[esi+8] + sub eax,edx + jz line_data_displayed + push eax + xor al,al + call lseek + mov ecx,[esp] + mov edx,[additional_memory] + lea eax,[edx+ecx] + cmp eax,[additional_memory_end] + ja out_of_memory + call read + call close + pop ecx + mov esi,[additional_memory] + get_line_data: + mov al,[esi] + cmp al,0Ah + je display_line_data + cmp al,0Dh + je display_line_data + cmp al,1Ah + je display_line_data + or al,al + jz display_line_data + inc esi + loop get_line_data + display_line_data: + mov ecx,esi + mov esi,[additional_memory] + sub ecx,esi + call display_block + line_data_displayed: + mov esi,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 + mov al,2 + jmp exit_program + +make_timestamp: + push buffer + call [GetSystemTime] + movzx ecx,word [buffer] + mov eax,ecx + sub eax,1970 + mov ebx,365 + mul ebx + mov ebp,eax + mov eax,ecx + sub eax,1969 + shr eax,2 + add ebp,eax + mov eax,ecx + sub eax,1901 + mov ebx,100 + div ebx + sub ebp,eax + mov eax,ecx + xor edx,edx + sub eax,1601 + mov ebx,400 + div ebx + add ebp,eax + movzx ecx,word [buffer+2] + mov eax,ecx + dec eax + mov ebx,30 + mul ebx + add ebp,eax + cmp ecx,8 + jbe months_correction + mov eax,ecx + sub eax,7 + shr eax,1 + add ebp,eax + mov ecx,8 + months_correction: + mov eax,ecx + shr eax,1 + add ebp,eax + cmp ecx,2 + jbe day_correction_ok + sub ebp,2 + movzx ecx,word [buffer] + test ecx,11b + jnz day_correction_ok + xor edx,edx + mov eax,ecx + mov ebx,100 + div ebx + or edx,edx + jnz day_correction + mov eax,ecx + mov ebx,400 + div ebx + or edx,edx + jnz day_correction_ok + day_correction: + inc ebp + day_correction_ok: + movzx eax,word [buffer+6] + dec eax + add eax,ebp + mov ebx,24 + mul ebx + movzx ecx,word [buffer+8] + add eax,ecx + mov ebx,60 + mul ebx + movzx ecx,word [buffer+10] + add eax,ecx + mov ebx,60 + mul ebx + movzx ecx,word [buffer+12] + add eax,ecx + adc edx,0 + ret + +error_prefix db 'error: ',0 +error_suffix db '.' +cr_lf db 0Dh,0Ah,0 +line_number_start db ' [',0 +line_data_start db ':',0Dh,0Ah,0 diff --git a/samples/Assembly/X86_64.inc b/samples/Assembly/X86_64.inc new file mode 100644 index 00000000..28413065 --- /dev/null +++ b/samples/Assembly/X86_64.inc @@ -0,0 +1,7060 @@ + +; flat assembler core +; Copyright (c) 1999-2014, 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 +iret_instruction: + cmp [code_type],64 + jne simple_instruction +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_64bit: + cmp [code_type],64 + jne illegal_instruction + mov byte [edi],48h + inc edi +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 + test eax,eax + jns int_imm_ok + call recoverable_overflow + int_imm_ok: + mov ah,al + mov al,0CDh + stos word [edi] + jmp instruction_assembled +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 ebx ecx + 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 ecx ebx edx + mov al,ah + cmp al,1 + je instruction_ready + call operand_autodetect + inc [base_code] + instruction_ready: + call store_instruction + jmp instruction_assembled + basic_mem_imm: + mov al,[operand_size] + cmp al,1 + jb basic_mem_imm_nosize + je basic_mem_imm_8bit + cmp al,2 + je basic_mem_imm_16bit + cmp al,4 + je basic_mem_imm_32bit + cmp al,8 + jne invalid_operand_size + 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 + basic_mem_imm_nosize: + call recoverable_unknown_size + basic_mem_imm_8bit: + call get_byte_value + mov byte [value],al + mov al,[base_code] + shr al,3 + mov [postbyte_register],al + pop ecx ebx 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 ecx ebx 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 ecx ebx 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 + get_simm32: + call get_qword_value + mov ecx,edx + cdq + cmp ecx,edx + jne value_out_of_range + cmp [value_type],4 + jne get_simm32_ok + mov [value_type],2 + get_simm32_ok: + 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 + jmp instruction_ready + basic_reg_mem_8bit: + add [base_code],2 + jmp instruction_ready + basic_reg_reg: + lods byte [esi] + call convert_register + mov bl,[postbyte_register] + mov [postbyte_register],al + mov al,ah + cmp al,1 + je nomem_instruction_ready + call operand_autodetect + inc [base_code] + nomem_instruction_ready: + 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 + jne invalid_operand_size + 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 + 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 + basic_store_imm_16bit: + 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 + jmp basic_store_imm_16bit + 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 + basic_store_imm_32bit: + mov eax,edx + call mark_relocation + stos dword [edi] + jmp instruction_assembled + basic_eax_imm: + add [base_code],5 + call store_instruction_code + jmp basic_store_imm_32bit + recoverable_unknown_size: + cmp [error_line],0 + jne ignore_unknown_size + push [current_line] + pop [error_line] + mov [error],operand_size_not_specified + ignore_unknown_size: + ret +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] + jmp instruction_ready + single_mem_nosize: + call recoverable_unknown_size + single_mem_8bit: + jmp instruction_ready + 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: + jmp nomem_instruction_ready +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 ebx ecx + 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 ecx ebx 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] + jmp instruction_ready + mov_mem_reg_8bit: + or al,bl + or al,bh + jnz instruction_ready + 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 + call store_address_32bit_value + jmp instruction_assembled + 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 + call store_address_64bit_value + jmp instruction_assembled + 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 ecx ebx 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 + jmp instruction_ready + mov_mem_imm: + mov al,[operand_size] + cmp al,1 + jb mov_mem_imm_nosize + je mov_mem_imm_8bit + cmp al,2 + je mov_mem_imm_16bit + cmp al,4 + je mov_mem_imm_32bit + cmp al,8 + jne invalid_operand_size + 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_mem_imm_8bit: + call get_byte_value + mov byte [value],al + mov [postbyte_register],0 + mov [base_code],0C6h + pop ecx ebx 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 ecx ebx edx + call store_instruction_with_imm16 + jmp instruction_assembled + mov_mem_imm_nosize: + call recoverable_unknown_size + 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 ecx ebx edx + call store_instruction_with_imm32 + jmp instruction_assembled + 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: + jmp nomem_instruction_ready + 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 + jmp nomem_instruction_ready + 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 + cmp [postbyte_register],8 + jne mov_reg_xrx_store + cmp [extended_code],20h + jne mov_reg_xrx_store + mov al,0F0h + stos byte [edi] + mov [postbyte_register],0 + mov_reg_xrx_store: + jmp nomem_instruction_ready + mov_reg_xrx_64bit: + cmp [operand_size],8 + jne invalid_operand_size + jmp nomem_instruction_ready + 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 + jmp instruction_ready + mov_reg_mem_8bit: + mov al,[postbyte_register] + or al,bl + or al,bh + jz mov_al_mem + add [base_code],2 + jmp instruction_ready + 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 + call address_16bit_prefix + 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 + jne invalid_operand_size + 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 + 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_store_imm_32bit: + mov eax,edx + call mark_relocation + 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 + jmp mov_store_imm_32bit + mov_sreg: + mov ah,al + and al,1111b + 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 + jmp nomem_instruction_ready + 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 + jmp instruction_ready + 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 + cmp [postbyte_register],8 + jne mov_xrx_store + cmp [extended_code],22h + jne mov_xrx_store + mov al,0F0h + stos byte [edi] + mov [postbyte_register],0 + mov_xrx_store: + jmp nomem_instruction_ready + mov_xrx_64bit: + cmp ah,8 + je mov_xrx_store + jmp invalid_operand_size +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 ebx ecx + 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 ecx ebx edx + mov al,ah + cmp al,1 + je test_mem_reg_8bit + call operand_autodetect + inc [base_code] + test_mem_reg_8bit: + jmp instruction_ready + test_mem_imm: + mov al,[operand_size] + cmp al,1 + jb test_mem_imm_nosize + je test_mem_imm_8bit + cmp al,2 + je test_mem_imm_16bit + cmp al,4 + je test_mem_imm_32bit + cmp al,8 + jne invalid_operand_size + 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_mem_imm_8bit: + call get_byte_value + mov byte [value],al + mov [postbyte_register],0 + mov [base_code],0F6h + pop ecx ebx 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 ecx ebx edx + call store_instruction_with_imm16 + jmp instruction_assembled + test_mem_imm_nosize: + call recoverable_unknown_size + 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 ecx ebx edx + call store_instruction_with_imm32 + jmp instruction_assembled + 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: + jmp nomem_instruction_ready + 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 + jne invalid_operand_size + 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_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_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: + jmp instruction_ready +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 ebx ecx + 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: + jmp nomem_instruction_ready +push_instruction: + mov [push_size],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,[push_size] + 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 + call recoverable_unknown_size + 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,[push_size] + 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,[push_size] + 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 + jc invalid_operand + 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,[push_size] + 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 + call operand_32bit + 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_16bit: + call get_word_value + mov dx,ax + call operand_16bit + 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 + push_imm_8bit: + mov ah,al + mov [base_code],6Ah + call store_instruction_code + mov al,ah + stos byte [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 [push_size],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,[push_size] + 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 + call recoverable_unknown_size + 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,[push_size] + 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 dl,[operand_size] + mov dh,[push_size] + cmp al,62h + je pop_cs + mov bl,al + 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 + jc invalid_operand + 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_cs: + cmp [code_type],16 + jne illegal_instruction + cmp dl,2 + je pop_cs_store + or dl,dl + jnz invalid_operand_size + cmp dh,2 + je pop_cs_store + or dh,dh + jnz illegal_instruction + pop_cs_store: + test dh,not 2 + jnz invalid_operand_size + mov al,0Fh + stos byte [edi] + jmp pop_done + 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 + jmp instruction_ready + inc_mem_nosize: + call recoverable_unknown_size + inc_mem_8bit: + mov al,0FEh + xchg al,[base_code] + mov [postbyte_register],al + jmp instruction_ready + 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: + jmp nomem_instruction_ready +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 + jmp instruction_ready + set_reg: + lods byte [esi] + call convert_register + cmp ah,1 + jne invalid_operand_size + mov bl,al + mov [postbyte_register],0 + jmp nomem_instruction_ready +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 + jmp instruction_ready + 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 + mov [postbyte_register],al + jmp nomem_instruction_ready +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_store + cmp al,4 + jne invalid_operand_size + bound_store: + call operand_autodetect + mov [base_code],62h + jmp instruction_ready +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 + test eax,eax + js value_out_of_range + 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 + cmp [next_pass_needed],0 + jne enter_imm8_ok + test eax,eax + js value_out_of_range + enter_imm8_ok: + 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 + test eax,eax + js value_out_of_range + ret_imm_ok: + cmp [size_declared],0 + jne ret_imm_store + or ax,ax + jz simple_ret + ret_imm_store: + 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 + mov [size_override],-1 + call get_address + pop eax + mov [operand_size],al + call operand_autodetect + jmp instruction_ready +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 + jmp instruction_ready + ls_32bit: + call operand_32bit + jmp instruction_ready + ls_64bit: + call operand_64bit + jmp instruction_ready +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 ebx ecx + 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 ecx ebx edx + cmp al,1 + je sh_mem_cl_8bit + jb sh_mem_cl_nosize + call operand_autodetect + mov [base_code],0D3h + jmp instruction_ready + sh_mem_cl_nosize: + call recoverable_unknown_size + sh_mem_cl_8bit: + mov [base_code],0D2h + jmp instruction_ready + 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 ecx ebx 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 + jmp instruction_ready + sh_mem_imm_nosize: + call recoverable_unknown_size + 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 + jmp instruction_ready + 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 + jmp nomem_instruction_ready + sh_reg_cl_8bit: + mov [base_code],0D2h + jmp nomem_instruction_ready + 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 + jmp nomem_instruction_ready + 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 + jmp nomem_instruction_ready +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 ebx ecx + 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 ecx ebx edx + call operand_autodetect + inc [extended_code] + jmp instruction_ready + 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 ecx ebx 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] + jmp nomem_instruction_ready + 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] + or ah,ah + jz movx_unknown_size + cmp ah,al + jae invalid_operand_size + cmp ah,1 + je movx_mem_store + cmp ah,2 + jne invalid_operand_size + inc [extended_code] + movx_mem_store: + call operand_autodetect + jmp instruction_ready + movx_unknown_size: + call recoverable_unknown_size + jmp movx_mem_store + 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 + jmp nomem_instruction_ready + movx_reg_16bit: + call operand_autodetect + inc [extended_code] + jmp nomem_instruction_ready +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 + jmp instruction_ready + movsxd_reg: + lods byte [esi] + call convert_register + cmp ah,4 + jne invalid_operand_size + mov bl,al + call operand_64bit + jmp nomem_instruction_ready +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 ebx ecx + 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 ecx ebx edx + mov al,ah + call operand_autodetect + jmp instruction_ready + 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 ecx ebx edx + mov [extended_code],0BAh + call store_instruction_with_imm8 + jmp instruction_assembled + bt_mem_imm_nosize: + call recoverable_unknown_size + 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 + jmp nomem_instruction_ready + bt_reg_imm: + xor al,al + xchg al,[operand_size] + push eax ebx + 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 ebx 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 + call get_reg_mem + jc bs_reg_reg + mov al,[operand_size] + call operand_autodetect + jmp instruction_ready + bs_reg_reg: + mov al,ah + call operand_autodetect + jmp nomem_instruction_ready + get_reg_mem: + 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 get_reg_reg + cmp al,'[' + jne invalid_argument + call get_address + clc + ret + get_reg_reg: + lods byte [esi] + call convert_register + mov bl,al + stc + ret + +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] + jmp instruction_ready + imul_mem_nosize: + call recoverable_unknown_size + imul_mem_8bit: + jmp instruction_ready + 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] + imul_reg_8bit: + jmp nomem_instruction_ready + 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 ebx ecx + cmp byte [esi],',' + je imul_reg_mem_imm + mov al,[operand_size] + call operand_autodetect + pop ecx ebx edx + mov [base_code],0Fh + mov [extended_code],0AFh + jmp instruction_ready + 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 + jne invalid_operand_size + 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_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 ecx ebx 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 ecx ebx edx + mov [base_code],69h + call store_instruction_with_imm32 + jmp instruction_assembled + imul_reg_mem_imm_8bit_store: + pop ecx ebx 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 + jmp nomem_instruction_ready + 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 + jne invalid_operand_size + 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_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_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 + jne invalid_operand_size + in_ax_dx: + call operand_autodetect + mov [base_code],0EDh + call store_instruction_code + jmp instruction_assembled + in_al_dx: + mov al,0ECh + stos byte [edi] + 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 + jne invalid_operand_size + in_ax_imm: + call operand_autodetect + mov [base_code],0E5h + call store_instruction_code + mov al,dl + stos byte [edi] + jmp instruction_assembled + in_al_imm: + mov al,0E4h + stos byte [edi] + 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 + jne invalid_operand_size + out_dx_ax: + call operand_autodetect + mov [base_code],0EFh + call store_instruction_code + jmp instruction_assembled + out_dx_al: + mov al,0EEh + stos byte [edi] + 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 + jne invalid_operand_size + out_imm_ax: + call operand_autodetect + mov [base_code],0E7h + call store_instruction_code + mov al,dl + stos byte [edi] + jmp instruction_assembled + out_imm_al: + mov al,0E6h + stos byte [edi] + mov al,dl + stos byte [edi] + 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: + cmp [jump_type],1 + je illegal_instruction + 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],3 + je jmp_mem_far + cmp [jump_type],2 + je jmp_mem_near + call recoverable_unknown_size + 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],3 + je invalid_operand_size + cmp [code_type],64 + jne illegal_instruction + jmp instruction_ready + 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],2 + je invalid_operand_size + inc [postbyte_register] + jmp instruction_ready + 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],3 + je jmp_mem_far_32bit + cmp [jump_type],2 + 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 + jmp instruction_ready + jmp_mem_16bit: + cmp [jump_type],3 + je invalid_operand_size + call operand_16bit + jmp instruction_ready + jmp_reg: + test [jump_type],1 + jnz 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 + jmp nomem_instruction_ready + jmp_reg_32bit: + cmp [code_type],64 + je illegal_instruction + call operand_32bit + jmp nomem_instruction_ready + jmp_reg_16bit: + call operand_16bit + jmp nomem_instruction_ready + 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 + cmp [jump_type],3 + je invalid_operand + jmp_near: + mov al,[operand_size] + cmp al,2 + je jmp_imm_16bit + cmp al,4 + je jmp_imm_32bit + cmp al,8 + je jmp_imm_64bit + or al,al + jnz invalid_operand_size + cmp [code_type],16 + je jmp_imm_16bit + cmp [code_type],64 + je jmp_imm_64bit + jmp_imm_32bit: + cmp [code_type],64 + je invalid_operand_size + call get_address_dword_value + cmp [code_type],16 + jne jmp_imm_32bit_prefix_ok + mov byte [edi],66h + inc edi + jmp_imm_32bit_prefix_ok: + call calculate_jump_offset + cdq + call check_for_short_jump + jc jmp_short + jmp_imm_32bit_store: + mov edx,eax + sub edx,3 + jno jmp_imm_32bit_ok + cmp [code_type],64 + je relative_jump_out_of_range + jmp_imm_32bit_ok: + mov al,[base_code] + stos byte [edi] + mov eax,edx + call mark_relocation + stos dword [edi] + jmp instruction_assembled + jmp_imm_64bit: + cmp [code_type],64 + jne invalid_operand_size + call get_address_qword_value + call calculate_jump_offset + mov ecx,edx + cdq + cmp edx,ecx + jne relative_jump_out_of_range + call check_for_short_jump + jnc jmp_imm_32bit_store + jmp_short: + mov ah,al + mov al,0EBh + stos word [edi] + jmp instruction_assembled + jmp_imm_16bit: + call get_address_word_value + cmp [code_type],16 + je jmp_imm_16bit_prefix_ok + mov byte [edi],66h + inc edi + jmp_imm_16bit_prefix_ok: + call calculate_jump_offset + cwde + cdq + call check_for_short_jump + jc jmp_short + cmp [value_type],0 + jne invalid_use_of_symbol + mov edx,eax + dec edx + mov al,[base_code] + stos byte [edi] + mov eax,edx + stos word [edi] + jmp instruction_assembled + calculate_jump_offset: + add edi,2 + mov ebp,[addressing_space] + call calculate_relative_offset + sub edi,2 + ret + check_for_short_jump: + cmp [jump_type],1 + je forced_short + ja no_short_jump + cmp [base_code],0E8h + je no_short_jump + cmp [value_type],0 + jne no_short_jump + cmp eax,80h + jb short_jump + cmp eax,-80h + jae short_jump + no_short_jump: + clc + ret + forced_short: + cmp [base_code],0E8h + je illegal_instruction + cmp [next_pass_needed],0 + jne jmp_short_value_type_ok + cmp [value_type],0 + jne invalid_use_of_symbol + jmp_short_value_type_ok: + cmp eax,-80h + jae short_jump + cmp eax,80h + jae jump_out_of_range + short_jump: + stc + ret + 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 + jmp_far: + cmp [jump_type],2 + 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 +conditional_jump: + mov [base_code],al + lods byte [esi] + call get_jump_operator + cmp [jump_type],3 + je invalid_operand + call get_size_operator + cmp al,'(' + jne invalid_operand + cmp byte [esi],'.' + je invalid_value + mov al,[operand_size] + cmp al,2 + je conditional_jump_16bit + cmp al,4 + je conditional_jump_32bit + cmp al,8 + je conditional_jump_64bit + or al,al + jnz invalid_operand_size + cmp [code_type],16 + je conditional_jump_16bit + cmp [code_type],64 + je conditional_jump_64bit + conditional_jump_32bit: + cmp [code_type],64 + je invalid_operand_size + call get_address_dword_value + cmp [code_type],16 + jne conditional_jump_32bit_prefix_ok + mov byte [edi],66h + inc edi + conditional_jump_32bit_prefix_ok: + call calculate_jump_offset + cdq + call check_for_short_jump + jc conditional_jump_short + conditional_jump_32bit_store: + mov edx,eax + sub edx,4 + jno conditional_jump_32bit_range_ok + cmp [code_type],64 + je relative_jump_out_of_range + conditional_jump_32bit_range_ok: + mov ah,[base_code] + add ah,10h + mov al,0Fh + stos word [edi] + mov eax,edx + call mark_relocation + stos dword [edi] + jmp instruction_assembled + conditional_jump_64bit: + cmp [code_type],64 + jne invalid_operand_size + call get_address_qword_value + call calculate_jump_offset + mov ecx,edx + cdq + cmp edx,ecx + jne relative_jump_out_of_range + call check_for_short_jump + jnc conditional_jump_32bit_store + conditional_jump_short: + mov ah,al + mov al,[base_code] + stos word [edi] + jmp instruction_assembled + conditional_jump_16bit: + call get_address_word_value + cmp [code_type],16 + je conditional_jump_16bit_prefix_ok + mov byte [edi],66h + inc edi + conditional_jump_16bit_prefix_ok: + call calculate_jump_offset + cwde + cdq + call check_for_short_jump + jc conditional_jump_short + cmp [value_type],0 + jne invalid_use_of_symbol + mov edx,eax + sub dx,2 + mov ah,[base_code] + add ah,10h + mov al,0Fh + stos word [edi] + mov eax,edx + stos word [edi] + jmp instruction_assembled +loop_instruction_16bit: + cmp [code_type],64 + je illegal_instruction + cmp [code_type],16 + je loop_instruction + mov [operand_prefix],67h + jmp loop_instruction +loop_instruction_32bit: + cmp [code_type],32 + je loop_instruction + mov [operand_prefix],67h + 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],1 + ja invalid_operand + call get_size_operator + cmp al,'(' + jne invalid_operand + cmp byte [esi],'.' + je invalid_value + mov al,[operand_size] + cmp al,2 + je loop_jump_16bit + cmp al,4 + je loop_jump_32bit + cmp al,8 + je loop_jump_64bit + or al,al + jnz invalid_operand_size + cmp [code_type],16 + je loop_jump_16bit + cmp [code_type],64 + je loop_jump_64bit + loop_jump_32bit: + cmp [code_type],64 + je invalid_operand_size + call get_address_dword_value + cmp [code_type],16 + jne loop_jump_32bit_prefix_ok + mov byte [edi],66h + inc edi + loop_jump_32bit_prefix_ok: + call loop_counter_size + call calculate_jump_offset + cdq + make_loop_jump: + call check_for_short_jump + jc conditional_jump_short + scas word [edi] + jmp jump_out_of_range + loop_counter_size: + cmp [operand_prefix],0 + je loop_counter_size_ok + push eax + mov al,[operand_prefix] + stos byte [edi] + pop eax + loop_counter_size_ok: + ret + loop_jump_64bit: + cmp [code_type],64 + jne invalid_operand_size + call get_address_qword_value + call loop_counter_size + call calculate_jump_offset + mov ecx,edx + cdq + cmp edx,ecx + jne relative_jump_out_of_range + jmp make_loop_jump + loop_jump_16bit: + call get_address_word_value + cmp [code_type],16 + je loop_jump_16bit_prefix_ok + mov byte [edi],66h + inc edi + loop_jump_16bit_prefix_ok: + call loop_counter_size + call calculate_jump_offset + cwde + cdq + jmp make_loop_jump + +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: + xor ebx,ebx + call store_segment_prefix_if_necessary + mov al,0A4h + movs_check_size: + 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 + jnz invalid_operand_size + call recoverable_unknown_size + jmp simple_instruction +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: + xor ebx,ebx + call store_segment_prefix_if_necessary + mov al,0ACh + jmp movs_check_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] + jmp movs_check_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 eax ebx + 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 edx eax + 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: + xor ebx,ebx + call store_segment_prefix_if_necessary + mov al,0A6h + jmp movs_check_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 + ins_check_size: + cmp [operand_size],8 + jne movs_check_size + 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: + xor ebx,ebx + call store_segment_prefix_if_necessary + mov al,6Eh + jmp ins_check_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: + jmp instruction_ready + pm_reg: + lods byte [esi] + call convert_register + mov bl,al + cmp ah,2 + jne invalid_operand_size + jmp nomem_instruction_ready +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 + jmp nomem_instruction_ready +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 + jmp lgdt_mem_store + lgdt_mem_80bit: + cmp [code_type],64 + jne illegal_instruction + jmp lgdt_mem_store + lgdt_mem_48bit: + cmp [code_type],64 + je illegal_instruction + cmp [postbyte_register],2 + jb lgdt_mem_store + call operand_32bit + lgdt_mem_store: + jmp instruction_ready +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: + jmp instruction_ready + lar_reg_reg: + lods byte [esi] + call convert_register + cmp ah,2 + jne invalid_operand_size + mov bl,al + jmp nomem_instruction_ready +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 + jmp instruction_ready +swapgs_instruction: + cmp [code_type],64 + jne illegal_instruction +rdtscp_instruction: + mov [base_code],0Fh + mov [extended_code],1 + mov [postbyte_register],7 + mov bl,al + jmp nomem_instruction_ready + +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 ebx ecx + 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 ecx ebx edx + mov al,ah + cmp al,1 + je basic_486_mem_reg_8bit + call operand_autodetect + inc [extended_code] + basic_486_mem_reg_8bit: + jmp instruction_ready + 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: + jmp nomem_instruction_ready +bswap_instruction: + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_register + test al,1000b + jz bswap_reg_code_ok + or [rex_prefix],41h + and al,111b + bswap_reg_code_ok: + 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: + jmp instruction_ready +nop_instruction: + mov ah,[esi] + cmp ah,10h + je extended_nop + cmp ah,11h + je extended_nop + cmp ah,'[' + je extended_nop + stos byte [edi] + jmp instruction_assembled + extended_nop: + mov [base_code],0Fh + mov [extended_code],1Fh + mov [postbyte_register],0 + lods byte [esi] + call get_size_operator + cmp al,10h + je extended_nop_reg + cmp al,'[' + jne invalid_operand + call get_address + mov al,[operand_size] + or al,al + jz extended_nop_store + call operand_autodetect + extended_nop_store: + jmp instruction_ready + extended_nop_reg: + lods byte [esi] + call convert_register + mov bl,al + mov al,ah + call operand_autodetect + jmp nomem_instruction_ready + +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 + jmp nomem_instruction_ready + 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 + call recoverable_unknown_size + basic_fpu_mem_32bit: + jmp instruction_ready + basic_fpu_mem_64bit: + mov [base_code],0DCh + jmp instruction_ready + 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 + jmp nomem_instruction_ready + 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 + jmp nomem_instruction_ready +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 + call recoverable_unknown_size + fi_mem_32bit: + mov [base_code],0DAh + jmp instruction_ready + fi_mem_16bit: + mov [base_code],0DEh + jmp instruction_ready +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 + call recoverable_unknown_size + fld_mem_32bit: + mov [base_code],0D9h + jmp instruction_ready + fld_mem_64bit: + mov [base_code],0DDh + jmp instruction_ready + 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 + jmp instruction_ready + fld_streg: + lods byte [esi] + call convert_fpu_register + mov bl,al + cmp [postbyte_register],2 + jae fst_streg + mov [base_code],0D9h + jmp nomem_instruction_ready + fst_streg: + mov [base_code],0DDh + jmp nomem_instruction_ready +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 + call recoverable_unknown_size + fild_mem_32bit: + mov [base_code],0DBh + jmp instruction_ready + fild_mem_16bit: + mov [base_code],0DFh + jmp instruction_ready + 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 + jmp instruction_ready + fisttp_64bit_store: + mov [base_code],0DDh + jmp instruction_ready +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 + jmp instruction_ready +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 + jmp nomem_instruction_ready + 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 + jmp nomem_instruction_ready +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 +fstenv_instruction_16bit: + mov byte [edi],9Bh + inc edi +fldenv_instruction_16bit: + call operand_16bit + jmp fldenv_instruction +fstenv_instruction_32bit: + mov byte [edi],9Bh + inc edi +fldenv_instruction_32bit: + call operand_32bit + jmp fldenv_instruction +fsave_instruction_32bit: + mov byte [edi],9Bh + inc edi +fnsave_instruction_32bit: + call operand_32bit + jmp fnsave_instruction +fsave_instruction_16bit: + mov byte [edi],9Bh + inc edi +fnsave_instruction_16bit: + call operand_16bit + jmp fnsave_instruction +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 + jmp instruction_ready +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: + jmp instruction_ready +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: + jmp instruction_ready + 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 + +basic_mmx_instruction: + mov [base_code],0Fh + mov [extended_code],al + mmx_instruction: + 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 + jmp instruction_ready + mmx_mmreg_mmreg: + lods byte [esi] + call convert_mmx_register + mov bl,al + jmp nomem_instruction_ready +mmx_bit_shift_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 +pmovmskb_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 + je pmovmskb_reg_size_ok + cmp [code_type],64 + jne invalid_operand_size + cmp ah,8 + jnz invalid_operand_size + pmovmskb_reg_size_ok: + 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 + jmp nomem_instruction_ready + mmx_imm8: + push ebx ecx edx + xor cl,cl + xchg cl,[operand_size] + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + test ah,not 1 + jnz invalid_operand_size + mov [operand_size],cl + cmp al,'(' + jne invalid_operand + call get_byte_value + mov byte [value],al + pop edx ecx ebx + call store_instruction_with_imm8 + jmp instruction_assembled + mmx_nomem_imm8: + call store_nomem_instruction + call append_imm8 + jmp instruction_assembled + append_imm8: + 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 + ret +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 [opcode_prefix],al + jmp pshuf_instruction +pshufd_instruction: + mov [mmx_size],16 + mov [opcode_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 + jmp instruction_ready + 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 + jmp nomem_instruction_ready + 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 + jmp instruction_ready + movd_mmreg_reg: + lods byte [esi] + call convert_register + cmp ah,4 + jne invalid_operand_size + mov bl,al + jmp nomem_instruction_ready + make_mmx_prefix: + cmp [vex_required],0 + jne mmx_prefix_for_vex + cmp [operand_size],16 + jne no_mmx_prefix + mov [operand_prefix],66h + no_mmx_prefix: + ret + mmx_prefix_for_vex: + cmp [operand_size],16 + jne invalid_operand + mov [opcode_prefix],66h + 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 + jmp instruction_ready + movq_mem_xmmreg: + mov [extended_code],0D6h + mov [opcode_prefix],66h + jmp instruction_ready + movq_reg: + lods byte [esi] + cmp al,0B0h + jae movq_mmreg + call convert_register + cmp ah,8 + jne invalid_operand_size + mov bl,al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + mov [operand_size],0 + lods byte [esi] + call convert_mmx_register + mov [postbyte_register],al + call make_mmx_prefix + mov [extended_code],7Eh + call operand_64bit + jmp nomem_instruction_ready + movq_mmreg: + call convert_mmx_register + mov [postbyte_register],al + mov [extended_code],6Fh + mov [mmx_size],ah + cmp ah,16 + jne movq_mmreg_ + mov [extended_code],7Eh + mov [opcode_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 + jmp instruction_ready + 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 [opcode_prefix],0 + mov bl,al + cmp [mmx_size],16 + jne movq_mmreg_reg_store + mov [opcode_prefix],66h + movq_mmreg_reg_store: + call operand_64bit + jmp nomem_instruction_ready + movq_mmreg_mmreg: + call convert_mmx_register + cmp ah,[mmx_size] + jne invalid_operand_size + mov bl,al + jmp nomem_instruction_ready +movdq_instruction: + mov [opcode_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_xmm_register + mov [postbyte_register],al + mov [extended_code],7Fh + jmp instruction_ready + movdq_mmreg: + lods byte [esi] + call convert_xmm_register + 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 + jmp instruction_ready + movdq_mmreg_mmreg: + lods byte [esi] + call convert_xmm_register + mov bl,al + jmp nomem_instruction_ready +lddqu_instruction: + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + 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 [opcode_prefix],0F2h + mov [base_code],0Fh + mov [extended_code],0F0h + jmp instruction_ready + +movdq2q_instruction: + mov [opcode_prefix],0F2h + mov [mmx_size],8 + jmp movq2dq_ +movq2dq_instruction: + mov [opcode_prefix],0F3h + mov [mmx_size],16 + movq2dq_: + 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 + 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 + xor [mmx_size],8+16 + cmp ah,[mmx_size] + jne invalid_operand_size + mov bl,al + mov [base_code],0Fh + mov [extended_code],0D6h + jmp nomem_instruction_ready + +sse_ps_instruction_imm8: + mov [immediate_size],1 +sse_ps_instruction: + mov [mmx_size],16 + jmp sse_instruction +sse_pd_instruction_imm8: + mov [immediate_size],1 +sse_pd_instruction: + mov [mmx_size],16 + mov [opcode_prefix],66h + jmp sse_instruction +sse_ss_instruction: + mov [mmx_size],4 + mov [opcode_prefix],0F3h + jmp sse_instruction +sse_sd_instruction: + mov [mmx_size],8 + mov [opcode_prefix],0F2h + jmp sse_instruction +cmp_pd_instruction: + mov [opcode_prefix],66h +cmp_ps_instruction: + mov [mmx_size],16 + mov byte [value],al + mov al,0C2h + jmp sse_instruction +cmp_ss_instruction: + mov [mmx_size],4 + mov [opcode_prefix],0F3h + jmp cmp_sx_instruction +cmpsd_instruction: + mov al,0A7h + mov ah,[esi] + or ah,ah + jz simple_instruction_32bit + cmp ah,0Fh + je simple_instruction_32bit + mov al,-1 +cmp_sd_instruction: + mov [mmx_size],8 + mov [opcode_prefix],0F2h + cmp_sx_instruction: + mov byte [value],al + mov al,0C2h + jmp sse_instruction +comiss_instruction: + mov [mmx_size],4 + jmp sse_instruction +comisd_instruction: + mov [mmx_size],8 + mov [opcode_prefix],66h + jmp sse_instruction +cvtdq2pd_instruction: + mov [opcode_prefix],0F3h +cvtps2pd_instruction: + mov [mmx_size],8 + jmp sse_instruction +cvtpd2dq_instruction: + mov [mmx_size],16 + mov [opcode_prefix],0F2h + jmp sse_instruction +movshdup_instruction: + mov [mmx_size],16 + mov [opcode_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_xmm_register + 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: + mov al,[extended_code] + mov ah,[supplemental_code] + cmp al,0C2h + je sse_cmp_mem_ok + cmp ax,443Ah + je sse_cmp_mem_ok + cmp [immediate_size],1 + je mmx_imm8 + cmp [immediate_size],-1 + jne sse_ok + call take_additional_xmm0 + mov [immediate_size],0 + sse_ok: + jmp instruction_ready + sse_cmp_mem_ok: + cmp byte [value],-1 + je mmx_imm8 + call store_instruction_with_imm8 + 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_xmm_register + mov bl,al + mov al,[extended_code] + mov ah,[supplemental_code] + cmp al,0C2h + je sse_cmp_nomem_ok + cmp ax,443Ah + je sse_cmp_nomem_ok + cmp [immediate_size],1 + je mmx_nomem_imm8 + cmp [immediate_size],-1 + jne sse_nomem_ok + call take_additional_xmm0 + mov [immediate_size],0 + sse_nomem_ok: + jmp nomem_instruction_ready + sse_cmp_nomem_ok: + cmp byte [value],-1 + je mmx_nomem_imm8 + call store_nomem_instruction + mov al,byte [value] + stosb + jmp instruction_assembled + take_additional_xmm0: + cmp byte [esi],',' + jne additional_xmm0_ok + inc esi + lods byte [esi] + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + test al,al + jnz invalid_operand + additional_xmm0_ok: + ret + +pslldq_instruction: + mov [postbyte_register],al + mov [opcode_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_xmm_register + mov bl,al + jmp mmx_nomem_imm8 +movpd_instruction: + mov [opcode_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 [opcode_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 [opcode_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_xmm_register + mov [postbyte_register],al + jmp instruction_ready +movlpd_instruction: + mov [opcode_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_xmm_register + 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_xmm_register + 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 [opcode_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 + jmp nomem_instruction_ready +movmskpd_instruction: + mov [opcode_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 + mov [postbyte_register],al + cmp ah,4 + je movmskps_reg_ok + cmp ah,8 + jne invalid_operand_size + cmp [code_type],64 + jne invalid_operand + movmskps_reg_ok: + 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_ok + jmp invalid_operand + +cvtpi2pd_instruction: + mov [opcode_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_xmm_register + 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: + jmp instruction_ready + cvtpi_xmmreg_xmmreg: + lods byte [esi] + call convert_mmx_register + cmp ah,8 + jne invalid_operand_size + mov bl,al + jmp nomem_instruction_ready +cvtsi2ss_instruction: + mov [opcode_prefix],0F3h + jmp cvtsi_instruction +cvtsi2sd_instruction: + mov [opcode_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_xmm_register + mov [postbyte_register],al + cvtsi_xmmreg: + 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 + je cvtsi_size_ok + cmp [operand_size],8 + jne invalid_operand_size + call operand_64bit + cvtsi_size_ok: + jmp instruction_ready + 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 + jmp nomem_instruction_ready +cvtps2pi_instruction: + mov [mmx_size],8 + jmp cvtpd_instruction +cvtpd2pi_instruction: + mov [opcode_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 [opcode_prefix],0F3h + mov [mmx_size],4 + jmp cvt2si_instruction +cvtsd2si_instruction: + mov [opcode_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 + +ssse3_instruction: + mov [base_code],0Fh + mov [extended_code],38h + mov [supplemental_code],al + jmp mmx_instruction +palignr_instruction: + mov [base_code],0Fh + mov [extended_code],3Ah + mov [supplemental_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 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je palignr_mmreg_mmreg + cmp al,'[' + jne invalid_operand + call get_address + jmp mmx_imm8 + palignr_mmreg_mmreg: + lods byte [esi] + call convert_mmx_register + mov bl,al + jmp mmx_nomem_imm8 +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 + +sse4_instruction_38_xmm0: + mov [immediate_size],-1 +sse4_instruction_38: + mov [mmx_size],16 + mov [opcode_prefix],66h + mov [supplemental_code],al + mov al,38h + jmp sse_instruction +sse4_ss_instruction_3a_imm8: + mov [immediate_size],1 + mov [mmx_size],4 + jmp sse4_instruction_3a_setup +sse4_sd_instruction_3a_imm8: + mov [immediate_size],1 + mov [mmx_size],8 + jmp sse4_instruction_3a_setup +sse4_instruction_3a_imm8: + mov [immediate_size],1 + mov [mmx_size],16 + sse4_instruction_3a_setup: + mov [opcode_prefix],66h + mov [supplemental_code],al + mov al,3Ah + jmp sse_instruction +pclmulqdq_instruction: + mov byte [value],al + mov [mmx_size],16 + mov al,44h + jmp sse4_instruction_3a_setup +extractps_instruction: + mov [opcode_prefix],66h + mov [base_code],0Fh + mov [extended_code],3Ah + mov [supplemental_code],17h + lods byte [esi] + call get_size_operator + cmp al,10h + je extractps_reg + cmp al,'[' + jne invalid_operand + call get_address + cmp [operand_size],4 + je extractps_size_ok + cmp [operand_size],0 + jne invalid_operand_size + extractps_size_ok: + push edx ebx ecx + 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_xmm_register + mov [postbyte_register],al + pop ecx ebx edx + jmp mmx_imm8 + extractps_reg: + lods byte [esi] + call convert_register + push eax + 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_xmm_register + mov [postbyte_register],al + pop ebx + mov al,bh + cmp al,4 + je mmx_nomem_imm8 + cmp al,8 + jne invalid_operand_size + call operand_64bit + jmp mmx_nomem_imm8 +insertps_instruction: + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + mov [postbyte_register],al + insertps_xmmreg: + mov [opcode_prefix],66h + mov [base_code],0Fh + mov [extended_code],3Ah + mov [supplemental_code],21h + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je insertps_xmmreg_reg + cmp al,'[' + jne invalid_operand + call get_address + cmp [operand_size],4 + je insertps_size_ok + cmp [operand_size],0 + jne invalid_operand_size + insertps_size_ok: + jmp mmx_imm8 + insertps_xmmreg_reg: + lods byte [esi] + call convert_mmx_register + mov bl,al + jmp mmx_nomem_imm8 +pextrq_instruction: + mov [mmx_size],8 + jmp pextr_instruction +pextrd_instruction: + mov [mmx_size],4 + jmp pextr_instruction +pextrw_instruction: + mov [mmx_size],2 + jmp pextr_instruction +pextrb_instruction: + mov [mmx_size],1 + pextr_instruction: + mov [opcode_prefix],66h + mov [base_code],0Fh + mov [extended_code],3Ah + mov [supplemental_code],al + lods byte [esi] + call get_size_operator + cmp al,10h + je pextr_reg + cmp al,'[' + jne invalid_operand + call get_address + mov al,[mmx_size] + cmp al,[operand_size] + je pextr_size_ok + cmp [operand_size],0 + jne invalid_operand_size + pextr_size_ok: + cmp al,8 + jne pextr_prefix_ok + call operand_64bit + pextr_prefix_ok: + push edx ebx ecx + 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_xmm_register + mov [postbyte_register],al + pop ecx ebx edx + jmp mmx_imm8 + pextr_reg: + lods byte [esi] + call convert_register + cmp [mmx_size],4 + ja pextrq_reg + cmp ah,4 + je pextr_reg_size_ok + cmp [code_type],64 + jne pextr_invalid_size + cmp ah,8 + je pextr_reg_size_ok + pextr_invalid_size: + jmp invalid_operand_size + pextrq_reg: + cmp ah,8 + jne pextr_invalid_size + call operand_64bit + pextr_reg_size_ok: + mov [operand_size],0 + push eax + 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 ebx,eax + pop eax + mov [postbyte_register],al + mov al,ah + cmp [mmx_size],2 + jne pextr_reg_store + mov [opcode_prefix],0 + mov [extended_code],0C5h + call make_mmx_prefix + jmp mmx_nomem_imm8 + pextr_reg_store: + cmp bh,16 + jne invalid_operand_size + xchg bl,[postbyte_register] + call operand_autodetect + jmp mmx_nomem_imm8 +pinsrb_instruction: + mov [mmx_size],1 + jmp pinsr_instruction +pinsrd_instruction: + mov [mmx_size],4 + jmp pinsr_instruction +pinsrq_instruction: + mov [mmx_size],8 + call operand_64bit + pinsr_instruction: + mov [opcode_prefix],66h + mov [base_code],0Fh + mov [extended_code],3Ah + mov [supplemental_code],al + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + mov [postbyte_register],al + pinsr_xmmreg: + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je pinsr_xmmreg_reg + cmp al,'[' + jne invalid_operand + call get_address + cmp [operand_size],0 + je mmx_imm8 + mov al,[mmx_size] + cmp al,[operand_size] + je mmx_imm8 + jmp invalid_operand_size + pinsr_xmmreg_reg: + lods byte [esi] + call convert_register + mov bl,al + cmp [mmx_size],8 + je pinsrq_xmmreg_reg + cmp ah,4 + je mmx_nomem_imm8 + jmp invalid_operand_size + pinsrq_xmmreg_reg: + cmp ah,8 + je mmx_nomem_imm8 + jmp invalid_operand_size +pmovsxbw_instruction: + mov [mmx_size],8 + jmp pmovsx_instruction +pmovsxbd_instruction: + mov [mmx_size],4 + jmp pmovsx_instruction +pmovsxbq_instruction: + mov [mmx_size],2 + jmp pmovsx_instruction +pmovsxwd_instruction: + mov [mmx_size],8 + jmp pmovsx_instruction +pmovsxwq_instruction: + mov [mmx_size],4 + jmp pmovsx_instruction +pmovsxdq_instruction: + mov [mmx_size],8 + pmovsx_instruction: + mov [opcode_prefix],66h + mov [base_code],0Fh + mov [extended_code],38h + mov [supplemental_code],al + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + 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 pmovsx_xmmreg_reg + cmp al,'[' + jne invalid_operand + call get_address + cmp [operand_size],0 + je instruction_ready + mov al,[mmx_size] + cmp al,[operand_size] + jne invalid_operand_size + jmp instruction_ready + pmovsx_xmmreg_reg: + lods byte [esi] + call convert_xmm_register + mov bl,al + jmp nomem_instruction_ready + +fxsave_instruction_64bit: + call operand_64bit +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: + jmp instruction_ready +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 + jmp instruction_ready +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 +movntpd_instruction: + mov [opcode_prefix],66h +movntps_instruction: + 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 + jmp instruction_ready + +movntsd_instruction: + mov [opcode_prefix],0F2h + mov [mmx_size],8 + jmp movnts_instruction +movntss_instruction: + mov [opcode_prefix],0F3h + mov [mmx_size],4 + movnts_instruction: + mov [extended_code],al + mov [base_code],0Fh + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + mov al,[operand_size] + cmp al,[mmx_size] + je movnts_size_ok + test al,al + jnz invalid_operand_size + movnts_size_ok: + 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_xmm_register + mov [postbyte_register],al + jmp instruction_ready + +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 + jmp instruction_ready +monitor_instruction: + mov [postbyte_register],al + cmp byte [esi],0 + je monitor_instruction_store + cmp byte [esi],0Fh + je monitor_instruction_store + 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 +movntdqa_instruction: + mov [opcode_prefix],66h + mov [base_code],0Fh + mov [extended_code],38h + mov [supplemental_code],al + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_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 instruction_ready + +extrq_instruction: + mov [opcode_prefix],66h + mov [base_code],0Fh + mov [extended_code],78h + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + 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 extrq_xmmreg_xmmreg + test ah,not 1 + jnz invalid_operand_size + cmp al,'(' + jne invalid_operand + xor bl,bl + xchg bl,[postbyte_register] + call store_nomem_instruction + call get_byte_value + stosb + call append_imm8 + jmp instruction_assembled + extrq_xmmreg_xmmreg: + inc [extended_code] + lods byte [esi] + call convert_xmm_register + mov bl,al + jmp nomem_instruction_ready +insertq_instruction: + mov [opcode_prefix],0F2h + mov [base_code],0Fh + mov [extended_code],78h + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + 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_xmm_register + mov bl,al + cmp byte [esi],',' + je insertq_with_imm + inc [extended_code] + jmp nomem_instruction_ready + insertq_with_imm: + call store_nomem_instruction + call append_imm8 + call append_imm8 + jmp instruction_assembled + +crc32_instruction: + mov [opcode_prefix],0F2h + mov [base_code],0Fh + mov [extended_code],38h + mov [supplemental_code],0F0h + 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 + je crc32_reg64 + cmp ah,4 + 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 + je crc32_reg32_reg + cmp al,'[' + jne invalid_operand + call get_address + mov al,[operand_size] + test al,al + jz crc32_unknown_size + cmp al,1 + je crc32_reg32_mem_store + cmp al,4 + ja invalid_operand_size + inc [supplemental_code] + call operand_autodetect + crc32_reg32_mem_store: + jmp instruction_ready + crc32_unknown_size: + call recoverable_unknown_size + jmp crc32_reg32_mem_store + crc32_reg32_reg: + lods byte [esi] + call convert_register + mov bl,al + mov al,ah + cmp al,1 + je crc32_reg32_reg_store + cmp al,4 + ja invalid_operand_size + inc [supplemental_code] + call operand_autodetect + crc32_reg32_reg_store: + jmp nomem_instruction_ready + crc32_reg64: + lods byte [esi] + cmp al,',' + jne invalid_operand + mov [operand_size],0 + call operand_64bit + lods byte [esi] + call get_size_operator + cmp al,10h + je crc32_reg64_reg + cmp al,'[' + jne invalid_operand + call get_address + mov ah,[operand_size] + mov al,8 + test ah,ah + jz crc32_unknown_size + cmp ah,1 + je crc32_reg32_mem_store + cmp ah,al + jne invalid_operand_size + inc [supplemental_code] + jmp crc32_reg32_mem_store + crc32_reg64_reg: + lods byte [esi] + call convert_register + mov bl,al + mov al,8 + cmp ah,1 + je crc32_reg32_reg_store + cmp ah,al + jne invalid_operand_size + inc [supplemental_code] + jmp crc32_reg32_reg_store +popcnt_instruction: + mov [opcode_prefix],0F3h + jmp bs_instruction +movbe_instruction: + mov [supplemental_code],al + mov [extended_code],38h + mov [base_code],0Fh + lods byte [esi] + call get_size_operator + cmp al,'[' + je movbe_mem + 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_argument + call get_address + mov al,[operand_size] + call operand_autodetect + jmp instruction_ready + movbe_mem: + inc [supplemental_code] + call get_address + push edx ebx ecx + 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 ecx ebx edx + mov al,[operand_size] + call operand_autodetect + jmp instruction_ready +adx_instruction: + mov [base_code],0Fh + mov [extended_code],38h + mov [supplemental_code],0F6h + mov [operand_prefix],al + call get_reg_mem + jc adx_reg_reg + mov al,[operand_size] + cmp al,4 + je instruction_ready + cmp al,8 + jne invalid_operand_size + call operand_64bit + jmp instruction_ready + adx_reg_reg: + cmp ah,4 + je nomem_instruction_ready + cmp ah,8 + jne invalid_operand_size + call operand_64bit + jmp nomem_instruction_ready + +simple_vmx_instruction: + mov ah,al + mov al,0Fh + stos byte [edi] + mov al,1 + stos word [edi] + jmp instruction_assembled +vmclear_instruction: + mov [opcode_prefix],66h + jmp vmx_instruction +vmxon_instruction: + mov [opcode_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 + jmp instruction_ready +vmread_instruction: + mov [extended_code],78h + lods byte [esi] + call get_size_operator + cmp al,10h + je vmread_nomem + 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 + call vmread_check_size + jmp vmx_size_ok + vmread_nomem: + lods byte [esi] + call convert_register + push eax + call vmread_check_size + 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 + call vmread_check_size + pop ebx + mov [base_code],0Fh + jmp nomem_instruction_ready + vmread_check_size: + cmp [code_type],64 + je vmread_long + cmp [operand_size],4 + jne invalid_operand_size + ret + vmread_long: + cmp [operand_size],8 + jne invalid_operand_size + ret +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,10h + je vmwrite_nomem + cmp al,'[' + jne invalid_operand + call get_address + call vmread_check_size + jmp vmx_size_ok + vmwrite_nomem: + lods byte [esi] + call convert_register + mov bl,al + mov [base_code],0Fh + jmp nomem_instruction_ready +vmx_inv_instruction: + mov [opcode_prefix],66h + mov [extended_code],38h + mov [supplemental_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 + call vmread_check_size + mov [operand_size],0 + 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] + or al,al + jz vmx_size_ok + cmp al,16 + jne invalid_operand_size + jmp vmx_size_ok +simple_svm_instruction: + push eax + mov [base_code],0Fh + mov [extended_code],1 + 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 + simple_svm_detect_size: + cmp ah,2 + je simple_svm_16bit + cmp ah,4 + je simple_svm_32bit + cmp [code_type],64 + jne invalid_operand_size + jmp simple_svm_store + simple_svm_16bit: + cmp [code_type],16 + je simple_svm_store + cmp [code_type],64 + je invalid_operand_size + jmp prefixed_svm_store + simple_svm_32bit: + cmp [code_type],32 + je simple_svm_store + prefixed_svm_store: + mov al,67h + stos byte [edi] + simple_svm_store: + call store_instruction_code + pop eax + stos byte [edi] + jmp instruction_assembled +skinit_instruction: + 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 + mov al,0DEh + jmp simple_vmx_instruction +invlpga_instruction: + push eax + mov [base_code],0Fh + mov [extended_code],1 + 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 bl,ah + 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_register + cmp ax,0401h + jne invalid_operand + mov ah,bl + jmp simple_svm_detect_size + +rdrand_instruction: + mov [base_code],0Fh + mov [extended_code],0C7h + mov [postbyte_register],al + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_register + mov bl,al + mov al,ah + call operand_autodetect + jmp nomem_instruction_ready +rdfsbase_instruction: + cmp [code_type],64 + jne illegal_instruction + mov [opcode_prefix],0F3h + mov [base_code],0Fh + mov [extended_code],0AEh + mov [postbyte_register],al + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_register + mov bl,al + mov al,ah + cmp ah,2 + je invalid_operand_size + call operand_autodetect + jmp nomem_instruction_ready + +xabort_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 dl,al + mov ax,0F8C6h + stos word [edi] + mov al,dl + stos byte [edi] + jmp instruction_assembled +xbegin_instruction: + lods byte [esi] + cmp al,'(' + jne invalid_operand + mov al,[code_type] + cmp al,64 + je xbegin_64bit + cmp al,32 + je xbegin_32bit + xbegin_16bit: + call get_address_word_value + add edi,4 + mov ebp,[addressing_space] + call calculate_relative_offset + sub edi,4 + shl eax,16 + mov ax,0F8C7h + stos dword [edi] + jmp instruction_assembled + xbegin_32bit: + call get_address_dword_value + jmp xbegin_address_ok + xbegin_64bit: + call get_address_qword_value + xbegin_address_ok: + add edi,5 + mov ebp,[addressing_space] + call calculate_relative_offset + sub edi,5 + mov edx,eax + cwde + cmp eax,edx + jne xbegin_rel32 + mov al,66h + stos byte [edi] + mov eax,edx + shl eax,16 + mov ax,0F8C7h + stos dword [edi] + jmp instruction_assembled + xbegin_rel32: + sub edx,1 + jno xbegin_rel32_ok + cmp [code_type],64 + je relative_jump_out_of_range + xbegin_rel32_ok: + mov ax,0F8C7h + stos word [edi] + mov eax,edx + stos dword [edi] + jmp instruction_assembled + +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 + cmp [vex_required],0 + jne invalid_operand + 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 +convert_xmm_register: + mov ah,al + shr ah,4 + cmp ah,0Ch + je xmm_register + jmp invalid_operand +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 [free_address_range],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 + cmp byte [esi-1],']' + jne invalid_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: + mov edx,[address_symbol] + mov [symbol_identifier],edx + mov edx,[address_high] + mov ebp,[addressing_space] + call calculate_relative_offset + mov [address_high],edx + cdq + cmp edx,[address_high] + je address_high_ok + call recoverable_overflow + address_high_ok: + mov edx,eax + ror ecx,16 + mov cl,[value_type] + rol ecx,16 + mov bx,0FF00h + 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 illegal_instruction + 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,4 + ja segment_prefix_386 + cmp [code_type],64 + je segment_prefix_ok + cmp al,3 + je ss_prefix + 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: + cmp [vex_required],0 + jne store_vex_instruction_code + mov al,[operand_prefix] + or al,al + jz operand_prefix_ok + stos byte [edi] + operand_prefix_ok: + mov al,[opcode_prefix] + or al,al + jz opcode_prefix_ok + stos byte [edi] + opcode_prefix_ok: + mov al,[rex_prefix] + test al,40h + jz rex_prefix_ok + cmp [code_type],64 + jne invalid_operand + test al,0B0h + jnz disallowed_combination_of_registers + 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] + cmp al,38h + je store_supplemental_code + cmp al,3Ah + je store_supplemental_code + instruction_code_ok: + ret + store_supplemental_code: + mov al,[supplemental_code] + stos byte [edi] + 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: + cmp [code_type],64 + jne address_value_ok + xor eax,eax + bt edx,31 + sbb eax,[address_high] + jz address_value_ok + cmp [address_high],0 + jne address_value_out_of_range + test ch,44h + jnz address_value_ok + test bx,8080h + jz address_value_ok + address_value_out_of_range: + call recoverable_overflow + address_value_ok: + call store_segment_prefix_if_necessary + test [vex_required],4 + jnz address_vsib + or bx,bx + jz address_immediate + cmp bx,0F800h + je address_rip_based + cmp bx,0F400h + je address_eip_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 bl,bh + jbe determine_16bit_address + xchg bl,bh + determine_16bit_address: + cmp bx,2600h + je address_si + cmp bx,2700h + je address_di + cmp bx,2300h + je address_bx + cmp bx,2500h + je address_bp + cmp bx,2625h + je address_bp_si + cmp bx,2725h + je address_bp_di + cmp bx,2723h + je address_bx_di + cmp bx,2623h + jne 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 + address_vsib: + mov al,bl + shr al,4 + cmp al,0Ch + je vector_index_ok + cmp al,0Dh + jne invalid_address + vector_index_ok: + mov al,bh + shr al,4 + cmp al,4 + je postbyte_32bit + cmp [code_type],64 + je address_prefix_ok + test al,al + jnz invalid_address + postbyte_32bit: + call address_32bit_prefix + jmp address_prefix_ok + postbyte_64bit: + cmp [code_type],64 + jne invalid_address_size + address_prefix_ok: + cmp bl,44h + je invalid_address + cmp bl,84h + je invalid_address + 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 + sib_ready: + test ch,44h + jnz sib_address_32bit_value + test ch,88h + 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 + test ch,88h + 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 + test ch,88h + 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,88h + 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 eax,ecx + shr eax,16 + cmp al,4 + jne address_32bit_relocation + mov al,2 + address_32bit_relocation: + 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 eax,ecx + shr eax,16 + 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,44h + jnz address_immediate_sib_32bit + test ch,not 88h + jnz invalid_address_size + address_immediate_sib_store: + 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_immediate_sib_32bit: + test ecx,0FF0000h + jnz address_immediate_sib_nosignextend + test edx,80000000h + jz address_immediate_sib_store + address_immediate_sib_nosignextend: + call address_32bit_prefix + jmp address_immediate_sib_store + address_eip_based: + mov al,67h + stos byte [edi] + 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] + shr ecx,16 + xchg [value_type],cl + mov ebx,[address_symbol] + xchg ebx,[symbol_identifier] + mov eax,edx + call mark_relocation + mov [value_type],cl + 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