Index: /trunk/include/VBox/dis.h
===================================================================
--- /trunk/include/VBox/dis.h	(revision 21186)
+++ /trunk/include/VBox/dis.h	(revision 21187)
@@ -124,4 +124,6 @@
 #define OPTYPE_FORCED_64_OP_SIZE        RT_BIT(22)  /**< Forced 64 bits operand size; regardless of prefix bytes */
 #define OPTYPE_REXB_EXTENDS_OPREG       RT_BIT(23)  /**< REX.B extends the register field in the opcode byte */
+#define OPTYPE_MOD_FIXED_11             RT_BIT(24)  /**< modrm.mod is always 11b */
+#define OPTYPE_FORCED_32_OP_SIZE_X86    RT_BIT(25)  /**< Forced 32 bits operand size; regardless of prefix bytes (only in 16 & 32 bits mode!) */
 #define OPTYPE_ALL                      (0xffffffff)
 
Index: /trunk/src/VBox/Disassembler/DisasmCore.cpp
===================================================================
--- /trunk/src/VBox/Disassembler/DisasmCore.cpp	(revision 21186)
+++ /trunk/src/VBox/Disassembler/DisasmCore.cpp	(revision 21187)
@@ -415,4 +415,6 @@
     bool fFiltered = false;
 
+    Assert(lpszCodeBlock && pOp && pCpu);
+
     // Store the opcode format string for disasmPrintf
 #ifndef DIS_CORE_ONLY
@@ -450,4 +452,11 @@
             &&  !(pCpu->prefix & PREFIX_OPSIZE))
             pCpu->opmode = CPUMODE_64BIT;
+    }
+    else
+    if (pOp->optype & OPTYPE_FORCED_32_OP_SIZE_X86)
+    {
+        /* Forced 32 bits operand size for certain instructions (mov crx, mov drx). */
+        Assert(pCpu->mode != CPUMODE_64BIT);
+        pCpu->opmode = CPUMODE_32BIT;
     }
 
@@ -1105,4 +1114,13 @@
     pCpu->ModRM.Bits.Reg = MODRM_REG(ModRM);
 
+    /* Disregard the mod bits for certain instructions (mov crx, mov drx).
+     *
+     * From the AMD manual:
+     * This instruction is always treated as a register-to-register (MOD = 11) instruction, regardless of the
+     * encoding of the MOD field in the MODR/M byte.
+     */
+    if (pOp->optype & OPTYPE_MOD_FIXED_11)
+        pCpu->ModRM.Bits.Mod = 3;
+
     if (pCpu->prefix & PREFIX_REX)
     {
@@ -1141,4 +1159,13 @@
     pCpu->ModRM.Bits.Mod = MODRM_MOD(ModRM);
     pCpu->ModRM.Bits.Reg = MODRM_REG(ModRM);
+
+    /* Disregard the mod bits for certain instructions (mov crx, mov drx).
+     *
+     * From the AMD manual:
+     * This instruction is always treated as a register-to-register (MOD = 11) instruction, regardless of the
+     * encoding of the MOD field in the MODR/M byte.
+     */
+    if (pOp->optype & OPTYPE_MOD_FIXED_11)
+        pCpu->ModRM.Bits.Mod = 3;
 
     if (pCpu->prefix & PREFIX_REX)
Index: /trunk/src/VBox/Disassembler/DisasmTables.cpp
===================================================================
--- /trunk/src/VBox/Disassembler/DisasmTables.cpp	(revision 21186)
+++ /trunk/src/VBox/Disassembler/DisasmTables.cpp	(revision 21187)
@@ -430,8 +430,8 @@
 
     /* 2 */
-    OP("mov %Rd,%Cd",        IDX_ParseModRM,     IDX_UseModRM,   0,          OP_MOV_CR,  OP_PARM_Rd,         OP_PARM_Cd,     OP_PARM_NONE,   OPTYPE_DANGEROUS | OPTYPE_PRIVILEGED),
-    OP("mov %Rd,%Dd",        IDX_ParseModRM,     IDX_UseModRM,   0,          OP_MOV_DR,  OP_PARM_Rd,         OP_PARM_Dd,     OP_PARM_NONE,   OPTYPE_DANGEROUS | OPTYPE_PRIVILEGED),
-    OP("mov %Cd,%Rd",        IDX_ParseModRM,     IDX_UseModRM,   0,          OP_MOV_CR,  OP_PARM_Cd,         OP_PARM_Rd,     OP_PARM_NONE,   OPTYPE_DANGEROUS | OPTYPE_PRIVILEGED),
-    OP("mov %Dd,%Rd",        IDX_ParseModRM,     IDX_UseModRM,   0,          OP_MOV_DR,  OP_PARM_Dd,         OP_PARM_Rd,     OP_PARM_NONE,   OPTYPE_DANGEROUS | OPTYPE_PRIVILEGED),
+    OP("mov %Rd,%Cd",        IDX_ParseModRM,     IDX_UseModRM,   0,          OP_MOV_CR,  OP_PARM_Rd,         OP_PARM_Cd,     OP_PARM_NONE,   OPTYPE_DANGEROUS | OPTYPE_PRIVILEGED | OPTYPE_MOD_FIXED_11 | OPTYPE_FORCED_32_OP_SIZE_X86),
+    OP("mov %Rd,%Dd",        IDX_ParseModRM,     IDX_UseModRM,   0,          OP_MOV_DR,  OP_PARM_Rd,         OP_PARM_Dd,     OP_PARM_NONE,   OPTYPE_DANGEROUS | OPTYPE_PRIVILEGED | OPTYPE_MOD_FIXED_11 | OPTYPE_FORCED_32_OP_SIZE_X86),
+    OP("mov %Cd,%Rd",        IDX_ParseModRM,     IDX_UseModRM,   0,          OP_MOV_CR,  OP_PARM_Cd,         OP_PARM_Rd,     OP_PARM_NONE,   OPTYPE_DANGEROUS | OPTYPE_PRIVILEGED | OPTYPE_MOD_FIXED_11 | OPTYPE_FORCED_32_OP_SIZE_X86),
+    OP("mov %Dd,%Rd",        IDX_ParseModRM,     IDX_UseModRM,   0,          OP_MOV_DR,  OP_PARM_Dd,         OP_PARM_Rd,     OP_PARM_NONE,   OPTYPE_DANGEROUS | OPTYPE_PRIVILEGED | OPTYPE_MOD_FIXED_11 | OPTYPE_FORCED_32_OP_SIZE_X86),
     /* only valid for Pentium Pro & Pentium II */
     OP("mov %Rd,%Td",        IDX_ParseModRM,     IDX_UseModRM,   0,          OP_MOV_TR,  OP_PARM_Rd,         OP_PARM_Td,     OP_PARM_NONE,   OPTYPE_PRIVILEGED),
Index: /trunk/src/VBox/Disassembler/DisasmTestA.asm
===================================================================
--- /trunk/src/VBox/Disassembler/DisasmTestA.asm	(revision 21186)
+++ /trunk/src/VBox/Disassembler/DisasmTestA.asm	(revision 21187)
@@ -34,4 +34,16 @@
 align 16
 BEGINPROC   TestProc
+    xor eax, eax
+    mov al, 4
+    lea edx, [4]
+    mov edx, 4
+    mov eax, 4
+    shl eax, 4
+    shl edx, 4
+    shr edx, 4
+    mov eax, edx
+    mov eax, ecx
+    mov edx, eax
+    mov ecx, eax
     DB 0xF0, 0x0F, 0x22, 0xC0
     DB 0xF0, 0x0F, 0x20, 0xC0
