aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2019-11-30 12:12:40 -0800
committeriximeow <me@iximeow.net>2020-01-12 16:10:13 -0800
commit7561575f135e0ba72f0a90a5859d19f7b02a31e8 (patch)
tree77f1f9edddc5eec033d6ac442abbc1f851dc6c7a
parent2b9f85fed5c720725748417a2d91b6bb38ca2747 (diff)
fix 0x98 and 0x99 opcodes, lss/lfs/lgs decodes
also remove unnecessary variants in unlikely_operands and adjust expectations of several tests
-rw-r--r--src/display.rs16
-rw-r--r--src/lib.rs66
-rw-r--r--test/test.rs6
3 files changed, 44 insertions, 44 deletions
diff --git a/src/display.rs b/src/display.rs
index 3e058df..5e42cef 100644
--- a/src/display.rs
+++ b/src/display.rs
@@ -331,8 +331,6 @@ impl fmt::Display for Opcode {
&Opcode::RETURN => write!(f, "{}", "ret"),
&Opcode::PUSHF => write!(f, "{}", "pushf"),
&Opcode::WAIT => write!(f, "{}", "wait"),
- &Opcode::CBW => write!(f, "{}", "cbw"),
- &Opcode::CDW => write!(f, "{}", "cdw"),
&Opcode::LODS => write!(f, "{}", "lods"),
&Opcode::STOS => write!(f, "{}", "stos"),
&Opcode::LAHF => write!(f, "{}", "lahf"),
@@ -523,6 +521,12 @@ impl fmt::Display for Opcode {
&Opcode::VMREAD => write!(f, "{}", "vmread"),
&Opcode::VMWRITE => write!(f, "{}", "vmwrite"),
&Opcode::XORPS => write!(f, "{}", "xorps"),
+ &Opcode::CBW => write!(f, "{}", "cbw"),
+ &Opcode::CWDE => write!(f, "{}", "cwde"),
+ &Opcode::CDQE => write!(f, "{}", "cdqe"),
+ &Opcode::CBD => write!(f, "{}", "cbd"),
+ &Opcode::CDQ => write!(f, "{}", "cdq"),
+ &Opcode::CQO => write!(f, "{}", "cqo"),
&Opcode::Invalid => write!(f, "{}", "invalid"),
}
}
@@ -720,6 +724,12 @@ impl <T: std::fmt::Write> Colorize<T> for Opcode {
Opcode::STC |
Opcode::STI |
Opcode::STD |
+ Opcode::CBW |
+ Opcode::CWDE |
+ Opcode::CDQE |
+ Opcode::CBD |
+ Opcode::CDQ |
+ Opcode::CQO |
Opcode::MOVDDUP |
Opcode::MOVSLDUP |
Opcode::MOVDQ2Q |
@@ -731,8 +741,6 @@ impl <T: std::fmt::Write> Colorize<T> for Opcode {
Opcode::PEXTRW |
Opcode::PINSRW |
Opcode::MOV |
- Opcode::CBW |
- Opcode::CDW |
Opcode::LODS |
Opcode::STOS |
Opcode::LAHF |
diff --git a/src/lib.rs b/src/lib.rs
index 5f1e9ff..2c1791f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -466,7 +466,11 @@ pub enum Opcode {
PUSHF,
WAIT,
CBW,
- CDW,
+ CWDE,
+ CDQE,
+ CBD,
+ CDQ,
+ CQO,
LODS,
STOS,
LAHF,
@@ -1088,6 +1092,8 @@ pub enum OperandCode {
ModRM_0x0fba,
ModRM_0xf238,
ModRM_0xf30fc7,
+ CVT_AA,
+ CVT_DA,
Rq_Cq_0,
Rq_Dq_0,
Cq_Rq_0,
@@ -2310,10 +2316,10 @@ const OPCODE_0F_MAP: [OpcodeRecord; 256] = [
// 0xb0
OpcodeRecord(Interpretation::Instruction(Opcode::CMPXCHG), OperandCode::Eb_Gb),
OpcodeRecord(Interpretation::Instruction(Opcode::CMPXCHG), OperandCode::Ev_Gv),
- OpcodeRecord(Interpretation::Instruction(Opcode::LSS), OperandCode::G_M_q),
+ OpcodeRecord(Interpretation::Instruction(Opcode::LSS), OperandCode::Gv_M),
OpcodeRecord(Interpretation::Instruction(Opcode::BTR), OperandCode::E_G_q),
- OpcodeRecord(Interpretation::Instruction(Opcode::LFS), OperandCode::G_M_q),
- OpcodeRecord(Interpretation::Instruction(Opcode::LGS), OperandCode::G_M_q),
+ OpcodeRecord(Interpretation::Instruction(Opcode::LFS), OperandCode::Gv_M),
+ OpcodeRecord(Interpretation::Instruction(Opcode::LGS), OperandCode::Gv_M),
OpcodeRecord(Interpretation::Instruction(Opcode::MOVZX_b), OperandCode::Gv_Eb),
OpcodeRecord(Interpretation::Instruction(Opcode::MOVZX_w), OperandCode::Gv_Ew),
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), // JMPE, ITANIUM
@@ -2578,8 +2584,8 @@ const OPCODES: [OpcodeRecord; 256] = [
OpcodeRecord(Interpretation::Instruction(Opcode::XCHG), OperandCode::Zv_AX_R5),
OpcodeRecord(Interpretation::Instruction(Opcode::XCHG), OperandCode::Zv_AX_R6),
OpcodeRecord(Interpretation::Instruction(Opcode::XCHG), OperandCode::Zv_AX_R7),
- OpcodeRecord(Interpretation::Instruction(Opcode::CBW), OperandCode::AX_AL),
- OpcodeRecord(Interpretation::Instruction(Opcode::CBW), OperandCode::DX_AX),
+ OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::CVT_AA),
+ OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::CVT_DA),
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
OpcodeRecord(Interpretation::Prefix, OperandCode::Nothing),
OpcodeRecord(Interpretation::Instruction(Opcode::PUSHF), OperandCode::Nothing),
@@ -3511,23 +3517,6 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
fn unlikely_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut Instruction, operand_code: OperandCode, length: &mut u8) -> Result<(), ()> {
let mut bytes_read = 0;
match operand_code {
- OperandCode::Gb_Eb_Ib => {
- let mut ext = vec![Operand::Nothing; 2];
-
- // TODO
- panic!("oh no, a mul!");
-// read_E(&mut bytes_iter, instruction, modrm, opwidth, &mut ext[0])?;
- /*
- instruction.operands[0] =
- RegSpec::gp_from_parts(r, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present());
- read_imm_signed(&mut bytes_iter, 1, 1).map(|imm| {
- ext[1] = imm;
- instruction.operands[1] = Operand::Many(ext);
- })?
-
- instruction.operand_count = 3;
- */
- }
OperandCode::Ew_Sw => {
let opwidth = 2;
let modrm = read_modrm(&mut bytes_iter, instruction, length)?;
@@ -3575,20 +3564,23 @@ fn unlikely_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
instruction.operands[1] = read_M(&mut bytes_iter, instruction, modrm, length)?;
}
},
- OperandCode::Gv_Ev_Iv => {
- let mut ext = vec![Operand::Nothing; 2];
-
- // TODO
- panic!("oh no, a mul!");
-// read_E(&mut bytes_iter, instruction, modrm, opwidth, &mut ext[0])?;
- /*
- instruction.operands[0] =
- RegSpec::gp_from_parts(r, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present());
- read_imm_signed(&mut bytes_iter, if opwidth == 8 { 4 } else { opwidth }, opwidth).map(|imm| {
- ext[1] = imm;
- instruction.operands[1] = Operand::Many(ext);
- })?
- */
+ OperandCode::CVT_AA => {
+ let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes);
+ instruction.opcode = match opwidth {
+ 2 => { Opcode::CBW },
+ 4 => { Opcode::CWDE },
+ 8 => { Opcode::CDQE },
+ _ => { unreachable!("invalid operation width"); },
+ }
+ }
+ OperandCode::CVT_DA => {
+ let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes);
+ instruction.opcode = match opwidth {
+ 2 => { Opcode::CBD },
+ 4 => { Opcode::CDQ },
+ 8 => { Opcode::CQO },
+ _ => { unreachable!("invalid operation width"); },
+ }
}
OperandCode::Iw => {
instruction.imm =
diff --git a/test/test.rs b/test/test.rs
index 634dd54..479faef 100644
--- a/test/test.rs
+++ b/test/test.rs
@@ -232,15 +232,15 @@ fn test_bitwise() {
fn test_misc() {
test_display(&[0x9c], "pushf");
test_display(&[0x48, 0x98], "cdqe");
- test_display(&[0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00], "nop cs:[rax + rax]");
- test_display(&[0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00], "nop cs:[rax + rax]");
+ test_display(&[0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00], "nop cs:[rax + rax * 1]");
+ test_display(&[0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00], "nop [rax + rax * 1]");
test_display(&[0x48, 0x8d, 0xa4, 0xc7, 0x20, 0x00, 0x00, 0x12], "lea rsp, [rdi + rax * 8 + 0x12000020]");
test_display(&[0x33, 0xc0], "xor eax, eax");
test_display(&[0x48, 0x8d, 0x53, 0x08], "lea rdx, [rbx + 0x8]");
test_display(&[0x31, 0xc9], "xor ecx, ecx");
test_display(&[0x48, 0x29, 0xc8], "sub rax, rcx");
test_display(&[0x48, 0x03, 0x0b], "add rcx, [rbx]");
- test_display(&[0x48, 0x8d, 0x0c, 0x12], "lea rcx, [rdx + rdx]");
+ test_display(&[0x48, 0x8d, 0x0c, 0x12], "lea rcx, [rdx + rdx * 1]");
test_display(&[0xf6, 0xc2, 0x18], "test dl, 0x18");
test_display(&[0xf3, 0x48, 0xab], "rep stosq");
test_display(&[0xf3, 0x48, 0xa5], "rep movsq");