Skip to content

Commit fd1a30f

Browse files
committed
CMPXCHG8B and CMPXCHG16B fix
1 parent c810712 commit fd1a30f

File tree

2 files changed

+27
-15
lines changed

2 files changed

+27
-15
lines changed

crates/libmwemu/src/engine/instructions/cmpxchg16b.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,32 @@ use iced_x86::Instruction;
55
pub fn execute(emu: &mut Emu, ins: &Instruction, instruction_sz: usize, _rep_step: bool) -> bool {
66
emu.show_instruction(color!("Orange"), ins);
77

8-
let value0 = match emu.get_operand_value(ins, 0, true) {
8+
let addr = match emu.get_operand_value(ins, 0, false) {
99
Some(v) => v,
1010
None => return false,
1111
};
1212

13-
let value1 = match emu.get_operand_value(ins, 1, true) {
13+
let mem_val = match emu.maps.read_128bits_le(addr) {
1414
Some(v) => v,
1515
None => return false,
1616
};
1717

18-
if value0 as u16 == (emu.regs().get_ax() as u16) {
18+
let rdx = emu.regs().rdx;
19+
let rax = emu.regs().rax;
20+
let rdx_rax = ((rdx as u128) << 64) | (rax as u128);
21+
22+
if mem_val == rdx_rax {
1923
emu.flags_mut().f_zf = true;
20-
if !emu.set_operand_value(ins, 0, value1) {
21-
return false;
22-
}
24+
let rcx = emu.regs().rcx;
25+
let rbx = emu.regs().rbx;
26+
let rcx_rbx = ((rcx as u128) << 64) | (rbx as u128);
27+
28+
emu.maps.write_bytes(addr, rcx_rbx.to_le_bytes().to_vec());
2329
} else {
2430
emu.flags_mut().f_zf = false;
25-
emu.regs_mut().set_ax(value1 & 0xffff);
31+
32+
emu.regs_mut().rax = (mem_val & 0xffffffff_ffffffff) as u64;
33+
emu.regs_mut().rdx = (mem_val >> 64) as u64;
2634
}
2735
true
2836
}

crates/libmwemu/src/engine/instructions/cmpxchg8b.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,28 @@ use iced_x86::Instruction;
55
pub fn execute(emu: &mut Emu, ins: &Instruction, instruction_sz: usize, _rep_step: bool) -> bool {
66
emu.show_instruction(color!("Orange"), ins);
77

8-
let value0 = match emu.get_operand_value(ins, 0, true) {
8+
let mem_val = match emu.get_operand_value(ins, 0, true) {
99
Some(v) => v,
1010
None => return false,
1111
};
1212

13-
let value1 = match emu.get_operand_value(ins, 1, true) {
14-
Some(v) => v,
15-
None => return false,
16-
};
13+
let edx = emu.regs().rdx & 0xffffffff;
14+
let eax = emu.regs().rax & 0xffffffff;
15+
let edx_eax = (edx << 32) | eax;
1716

18-
if value0 as u8 == (emu.regs().get_al() as u8) {
17+
if mem_val == edx_eax {
1918
emu.flags_mut().f_zf = true;
20-
if !emu.set_operand_value(ins, 0, value1) {
19+
let ecx = emu.regs().rcx & 0xffffffff;
20+
let ebx = emu.regs().rbx & 0xffffffff;
21+
let ecx_ebx = (ecx << 32) | ebx;
22+
23+
if !emu.set_operand_value(ins, 0, ecx_ebx) {
2124
return false;
2225
}
2326
} else {
2427
emu.flags_mut().f_zf = false;
25-
emu.regs_mut().set_al(value1 & 0xff);
28+
emu.regs_mut().rax = mem_val & 0xffffffff;
29+
emu.regs_mut().rdx = (mem_val >> 32) & 0xffffffff;
2630
}
2731
true
2832
}

0 commit comments

Comments
 (0)