diff --git a/include/instructions.h b/include/instructions.h index 2ce183e..c7616b4 100644 --- a/include/instructions.h +++ b/include/instructions.h @@ -42,6 +42,7 @@ public: void xor_rm32_r32(); // 0x31 void xor_r32_rm32(); // 0x33 void xor_eax_imm32(); // 0x35 + void cmp_rm32_r32(); // 0x39 void inc_eax(); // 0x40 void inc_ecx(); // 0x41 void inc_edx(); // 0x42 diff --git a/instructions.cpp b/instructions.cpp index 9855719..5018d21 100644 --- a/instructions.cpp +++ b/instructions.cpp @@ -35,6 +35,7 @@ void Instructions::init_instructions(){ this->instructions[0x31] = &Instructions::xor_rm32_r32; this->instructions[0x33] = &Instructions::xor_r32_rm32; this->instructions[0x35] = &Instructions::xor_eax_imm32; + this->instructions[0x39] = &Instructions::cmp_rm32_r32; this->instructions[0x40] = &Instructions::inc_eax; this->instructions[0x41] = &Instructions::inc_ecx; this->instructions[0x42] = &Instructions::inc_edx; @@ -640,6 +641,59 @@ void Instructions::xor_eax_imm32(){ this->registers[0] ^= imm32; } +void Instructions::cmp_rm32_r32(){ + //printf("cmp_rm32_r32 called.\n"); + uint32_t addr, dst, imm32, result; + uint8_t imm8; + + this->modrm = memory.read_uint8(this->eip); + this->calc_modrm(); + + switch (this->mod) { + case 0: + // cmp [M], R + // addr : M + this->eip++; + addr = this->registers[this->M]; + // dst : data of [M] + dst = memory.read_uint32(addr); + result = dst - this->registers[this->R]; + set_flag(!result, ZF); + break; + case 1: + // cmp [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); + result = dst - this->registers[this->R]; + set_flag(!result, ZF); + break; + case 2: + // cmp [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); + result = dst - this->registers[this->R]; + set_flag(!result, ZF); + this->eip += 4; + break; + default: + // case mod == 3 + // cmp M, R + this->eip++; + result = this->registers[this->M] - this->registers[this->R]; + set_flag(!result, ZF); + break; + } +} + void Instructions::inc_eax(){ //printf("inc_eax called.\n"); this->registers[0]++;