fix(interpreter): correctly sign extend cmp byte
This commit is contained in:
@@ -668,7 +668,7 @@ impl Disassembler {
|
||||
// byte extended version
|
||||
let (target, reg) = self.parse_modrm_byte(Some(InstructionWidth::Word))?;
|
||||
let imm = self.parse_byte()?;
|
||||
Self::modrm_reg_to_grp1(reg, target, ImmediateOperand::Byte(imm))?
|
||||
Self::modrm_reg_to_grp1(reg, target, ImmediateOperand::Byte(imm).sign_extend())?
|
||||
}
|
||||
|
||||
0x84 => modrm_8b_register!(self, TEST),
|
||||
|
||||
@@ -239,7 +239,25 @@ impl Computer {
|
||||
dest: ModRmTarget,
|
||||
src: ArithmeticOperand,
|
||||
) -> Result<(), InterpreterError> {
|
||||
let op: fn(Lhs, Rhs) -> ArithmeticResult = |lhs, rhs| lhs - rhs;
|
||||
let op: fn(Lhs, Rhs) -> ArithmeticResult = |lhs, rhs| {
|
||||
// 0x80, with modrm byte selecting mem read from [%bx] is the only
|
||||
// grp1 instruction, which does not state sign-extension, meaning
|
||||
// that rhs really is just a byte, which means only the low byte
|
||||
// of lhs should be compared to.
|
||||
// With out this match here, the sub logic would sign extend the
|
||||
// rhs to a word, which is not the desired logic.
|
||||
match lhs {
|
||||
ImmediateOperand::Word(lhsw) => match rhs {
|
||||
ImmediateOperand::Byte(_) => {
|
||||
let [low, _] = lhsw.to_be_bytes();
|
||||
return ImmediateOperand::Byte(low) - rhs;
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
lhs - rhs
|
||||
};
|
||||
let flag_set: fn(&mut Flags, ArithmeticResult, Lhs, Rhs) = |flags, result, lhs, rhs| {
|
||||
// log::info!("{:?} {:?} {}", lhs, rhs, lhs < rhs);
|
||||
flags.cf = lhs < rhs;
|
||||
|
||||
Reference in New Issue
Block a user