aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG6
-rw-r--r--src/long_mode/mod.rs2
-rw-r--r--test/long_mode/mod.rs10
3 files changed, 17 insertions, 1 deletions
diff --git a/CHANGELOG b/CHANGELOG
index a1ef883..8cdc8d3 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -10,6 +10,12 @@
* push-immediate, pushf, popf, leave, and xlat now all report a correct memory
access size, fixing the prior behavior of reporting to memory access size at
all
+* 64-bit mode: mov seg-to-reg uses 32-bit GPRs for the destination rather than 16-bit.
+ * this is more accurate to the semantic of the instruction, which is why other disassemblers
+ report it this way; for register destinations specifically the segment selector is
+ zero-extended to 64 bits for storage. writing to "eax" in this way implies the 32->64 bit
+ zero-extend, whereas writing to "ax" does not imply any zero-extension. mov reg-to-seg
+ is unchanged and uses a 16-bit form for source GPR.
## 2.0.0
diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs
index d6ad7df..117643a 100644
--- a/src/long_mode/mod.rs
+++ b/src/long_mode/mod.rs
@@ -8109,7 +8109,7 @@ fn read_operands<
instruction.operand_count = 2;
if mem_oper == OperandSpec::RegMMM {
- instruction.regs[1].bank = RegisterBank::W;
+ instruction.regs[1].bank = RegisterBank::D;
} else {
instruction.mem_size = 2;
}
diff --git a/test/long_mode/mod.rs b/test/long_mode/mod.rs
index 73ca7f3..dd19b55 100644
--- a/test/long_mode/mod.rs
+++ b/test/long_mode/mod.rs
@@ -1254,12 +1254,22 @@ fn test_mov() {
test_display(&[0x0f, 0x97, 0x08], "seta byte [rax]");
// test_display(&[0xd6], "salc");
test_display(&[0x8e, 0x00], "mov es, word [rax]");
+ test_display(&[0x8e, 0xc0], "mov es, ax");
+ test_display(&[0x8c, 0xc0], "mov eax, es");
// cs is not an allowed destination
test_invalid(&[0x8e, 0x08]);
test_display(&[0x8e, 0x10], "mov ss, word [rax]");
+ test_display(&[0x8e, 0xd0], "mov ss, ax");
+ test_display(&[0x8c, 0xd0], "mov eax, ss");
test_display(&[0x8e, 0x18], "mov ds, word [rax]");
+ test_display(&[0x8e, 0xd8], "mov ds, ax");
+ test_display(&[0x8c, 0xd8], "mov eax, ds");
test_display(&[0x8e, 0x20], "mov fs, word [rax]");
+ test_display(&[0x8e, 0xe0], "mov fs, ax");
+ test_display(&[0x8c, 0xe0], "mov eax, fs");
test_display(&[0x8e, 0x28], "mov gs, word [rax]");
+ test_display(&[0x8e, 0xe8], "mov gs, ax");
+ test_display(&[0x8c, 0xe8], "mov eax, gs");
test_invalid(&[0x8e, 0x30]);
test_invalid(&[0x8e, 0x38]);
}