From 336a8e5cb9a14043e3e49b6b6ac524722633410d Mon Sep 17 00:00:00 2001 From: tuz358 Date: Fri, 16 Mar 2018 14:51:47 +0900 Subject: [PATCH] Add template_rm32_r32(int calc_type) function --- include/instructions.h | 2 ++ instructions.cpp | 75 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/include/instructions.h b/include/instructions.h index fb18e93..7b80612 100644 --- a/include/instructions.h +++ b/include/instructions.h @@ -44,6 +44,8 @@ public: void execute_opcode(uint8_t opcode); // templates + void template_rm32_r32(int calc_type); + void calc_rm32_r32_case0to2(uint32_t addr, uint32_t dst, int calc_type); void template_r32_rm32(int calc_type); void calc_r32_rm32(uint32_t *src, uint32_t *dst, int calc_type); void template_eax_imm32(int calc_type); diff --git a/instructions.cpp b/instructions.cpp index 987824a..e44e18e 100644 --- a/instructions.cpp +++ b/instructions.cpp @@ -125,6 +125,79 @@ void Instructions::execute_opcode(uint8_t opcode){ (this->*instructions[opcode])(); } +void Instructions::template_rm32_r32(int calc_type){ + //printf("template_rm32_r32 called.\n"); + uint32_t addr, dst, imm32; + uint8_t imm8; + + this->modrm = memory.read_uint8(this->eip); + this->calc_modrm(); + + switch (this->mod) { + case 0: + // operation [M], R + // addr : M + this->eip++; + addr = this->registers[this->M]; + // dst : data of [M] + dst = memory.read_uint32(addr); + calc_rm32_r32_case0to2(addr, dst, calc_type); + break; + case 1: + // operation [M+imm8], R + this->eip++; + imm8 = memory.read_uint8(this->eip); + // addr : M + addr = this->registers[this->M]; + // dst : data of [M+imm8] + dst = memory.read_uint32(addr + imm8); + calc_rm32_r32_case0to2(addr + imm8, dst, calc_type); + this->eip++; + break; + case 2: + // operation [M+imm32], R + this->eip++; + imm32 = memory.read_uint32(this->eip); + imm32 = swap_endian32(imm32); + // addr : M + addr = this->registers[this->M]; + // dst : data of [M+imm32] + dst = memory.read_uint32(addr + imm32); + calc_rm32_r32_case0to2(addr + imm32, dst, calc_type); + this->eip += 4; + break; + default: + // case mod == 3 + // operation M, R + this->eip++; + calc_r32_rm32(&this->registers[this->M], &this->registers[this->R], calc_type); + break; + } +} + +void Instructions::calc_rm32_r32_case0to2(uint32_t addr, uint32_t dst, int calc_type){ + switch (calc_type) { + case ADD: + memory.write_uint32(addr, dst + this->registers[this->R]); break; + case OR: + memory.write_uint32(addr, dst | this->registers[this->R]); break; + case ADC: + memory.write_uint32(addr, dst + this->registers[this->R] + get_flag(CF)); break; + case SBB: + memory.write_uint32(addr, dst - (this->registers[this->R] + get_flag(CF))); break; + case AND: + memory.write_uint32(addr, dst & this->registers[this->R]); break; + case SUB: + memory.write_uint32(addr, dst - this->registers[this->R]); break; + case XOR: + memory.write_uint32(addr, dst ^ this->registers[this->R]); break; + case CMP: + // TODO: implement + break; + default: break; + } +} + void Instructions::template_r32_rm32(int calc_type){ uint32_t addr, dst, imm32; uint8_t imm8; @@ -169,7 +242,7 @@ void Instructions::template_r32_rm32(int calc_type){ // case mod == 3 // operation R, M this->eip++; - calc_r32_rm32(&this->registers[this->R], &dst, calc_type); + calc_r32_rm32(&this->registers[this->R], &this->registers[this->M], calc_type); break; } }