diff options
| author | 0x221E <0x221E@0xinfinity.dev> | 2026-04-12 16:59:40 +0200 |
|---|---|---|
| committer | 0x221E <0x221E@0xinfinity.dev> | 2026-04-12 16:59:40 +0200 |
| commit | a66c7433c2c11b8b6c99142277ed4e16b1a2a465 (patch) | |
| tree | e54bcfb59c303acf6118fd11f06d5c0bd5f24e5d /src/Instruction.h | |
Diffstat (limited to 'src/Instruction.h')
| -rw-r--r-- | src/Instruction.h | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/src/Instruction.h b/src/Instruction.h new file mode 100644 index 0000000..c80d2ca --- /dev/null +++ b/src/Instruction.h @@ -0,0 +1,110 @@ +#pragma once + +#include <string> +#include <cstdint> + +#include "ExecutorCases.h" +#include "Exceptions.h" + +namespace x86 { + enum Register : uint8_t { + EAX = 0, ECX = 1, EDX = 2, EBX = 3, + ESP = 4, EBP = 5, ESI = 6, EDI = 7, + + SIB_DISP = 254, + SIB_NONE = 255, + }; + + enum class ModRMState : uint8_t + { + INVALID = 0, + LR = 1, + LR_DISP8 = 2, + LR_DISP32 = 3, + DISP32 = 4, + R = 5 + }; + + struct ModRM { + ModRMState m_State; + x86::Register m_Reg; + uint8_t m_Rm; + bool m_SIB; + }; + + struct SIB { + uint8_t m_Scale; + x86::Register m_Index; + x86::Register m_Base; + }; + + constexpr ModRM ProcessMODRM(uint8_t modrm) { + uint8_t mod_mask = 0b11000000; + uint8_t reg_mask = 0b00111000; + uint8_t rm_mask = 0b00000111; + + uint8_t mod = modrm & mod_mask; + uint8_t reg = (modrm & reg_mask) >> 3; + uint8_t rm = modrm & rm_mask; + + ModRMState state = ModRMState::INVALID; + bool SIB = false; + + switch(mod) { + case 0b00000000: + state = ModRMState::LR; + if(rm == 0b00000101) + state = ModRMState::DISP32; + else if(rm == 0b00000100) + SIB = true; + break; + case 0b01000000: + state = ModRMState::LR_DISP8; + if(rm == 0b00000100) + SIB = true; + break; + case 0b10000000: + state = ModRMState::LR_DISP32; + if(rm == 0b00000100) + SIB = true; + break; + case 0b11000000: + state = ModRMState::R; + break; + default: + throw CPUException("Mod R/M Unknown exception!"); + } + + return {.m_State = state, .m_Reg = (x86::Register)reg, .m_Rm = rm, .m_SIB = SIB}; + } + + SIB ProcessSIB(uint8_t sib); + + // Helpers + std::string Register2Str(x86::Register reg); +} + +enum Opcode : uint8_t { + INVALID = 0, + NOP = 0x90, + HLT = 0xF4, + MOV_R32_IMM32 = 0xB8, + MOV_RM32_R32 = 0x89, + ADD_RM32_R32 = 0x01, + ADD_R32_RM32 = 0x03, +}; + +std::string Opcode2Str(Opcode op); + +struct Instruction{ + ExecutorCase m_Func; + uint8_t m_Prefix; + Opcode m_Opcode; + size_t m_Length; + uint32_t m_Operand1; + uint32_t m_Operand2; + x86::ModRM m_ModRM; + x86::SIB m_SIB; + uint8_t m_Displacement[4]; + uint8_t m_DisplacementSize; +}; |
