aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2019-12-01 15:38:00 -0800
committeriximeow <me@iximeow.net>2020-01-12 16:10:13 -0800
commitff636d091f911f0467f8bd2ece0c771a26c88729 (patch)
tree972f630cea71dd286d524cb8ed9556c3eaf89d24
parent071dbfd2f1407842a6487a67e6ce83e80fedb99c (diff)
proper movs operand support
-rw-r--r--src/lib.rs34
-rw-r--r--test/test.rs4
2 files changed, 24 insertions, 14 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 84e71ed..0f019d1 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -228,6 +228,8 @@ impl OperandSpec {
OperandSpec::DispU32 |
OperandSpec::DispU64 |
OperandSpec::Deref |
+ OperandSpec::Deref_rsi |
+ OperandSpec::Deref_rdi |
OperandSpec::RegDisp |
OperandSpec::RegScale |
OperandSpec::RegIndexBase |
@@ -247,6 +249,7 @@ impl OperandSpec {
OperandSpec::ImmU64 |
OperandSpec::RegRRR |
OperandSpec::RegMMM |
+ OperandSpec::AL |
OperandSpec::CL |
OperandSpec::Nothing => {
false
@@ -268,6 +271,9 @@ impl Operand {
OperandSpec::RegMMM => {
Operand::Register(inst.modrm_mmm)
}
+ OperandSpec::AL => {
+ Operand::Register(RegSpec::al())
+ }
OperandSpec::CL => {
Operand::Register(RegSpec::cl())
}
@@ -284,6 +290,12 @@ impl Operand {
OperandSpec::Deref => {
Operand::RegDeref(inst.modrm_mmm)
}
+ OperandSpec::Deref_rsi => {
+ Operand::RegDeref(RegSpec::rsi())
+ }
+ OperandSpec::Deref_rdi => {
+ Operand::RegDeref(RegSpec::rdi())
+ }
OperandSpec::RegDisp => {
Operand::RegDisp(inst.modrm_mmm, inst.disp as i32)
}
@@ -737,6 +749,8 @@ enum OperandSpec {
RegRRR,
// the register in modrm_mmm (eg modrm mod bits were 11)
RegMMM,
+ // the register `al`. Used for MOVS.
+ AL,
// the register `cl`. Used for SHLD and SHRD.
CL,
ImmI8,
@@ -750,6 +764,8 @@ enum OperandSpec {
DispU32,
DispU64,
Deref,
+ Deref_rsi,
+ Deref_rdi,
RegDisp,
RegScale,
RegIndexBase,
@@ -3793,23 +3809,17 @@ fn unlikely_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
},
// sure hope these aren't backwards huh
OperandCode::AL_Xb => {
- instruction.modrm_rrr = RegSpec::al();
- instruction.modrm_mmm = RegSpec::rsi();
- instruction.operands[0] = OperandSpec::RegRRR;
- instruction.operands[1] = OperandSpec::Deref;
+ instruction.operands[0] = OperandSpec::AL;
+ instruction.operands[1] = OperandSpec::Deref_rsi;
}
// TODO: two memory operands! this is wrong!!!
OperandCode::Yb_Xb => {
- instruction.modrm_rrr = RegSpec::rdi();
- instruction.modrm_mmm = RegSpec::rsi();
- instruction.operands[0] = OperandSpec::Deref;
- instruction.operands[1] = OperandSpec::Deref;
+ instruction.operands[0] = OperandSpec::Deref_rdi;
+ instruction.operands[1] = OperandSpec::Deref_rsi;
}
OperandCode::Yb_AL => {
- instruction.modrm_rrr = RegSpec::al();
- instruction.modrm_mmm = RegSpec::rdi();
- instruction.operands[0] = OperandSpec::Deref;
- instruction.operands[1] = OperandSpec::RegRRR;
+ instruction.operands[0] = OperandSpec::Deref_rdi;
+ instruction.operands[1] = OperandSpec::AL;
}
OperandCode::AX_Xv => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes);
diff --git a/test/test.rs b/test/test.rs
index 2d9c95e..cc865d9 100644
--- a/test/test.rs
+++ b/test/test.rs
@@ -252,8 +252,8 @@ fn test_misc() {
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 stos es:[rdi], rax");
-// test_display(&[0xf3, 0x48, 0xa5], "rep movs es:[rdi], ds:[rsi]");
-// test_display(&[0xf3, 0x45, 0x0f, 0xbc, 0xd7], "tzcnt r10d, r15d");
+ test_display(&[0xf3, 0x48, 0xa5], "rep movs es:[rdi], ds:[rsi]");
+ test_display(&[0xf3, 0x45, 0x0f, 0xbc, 0xd7], "tzcnt r10d, r15d");
}
#[test]