diff --git a/ParkanPlayground.sln.DotSettings.user b/ParkanPlayground.sln.DotSettings.user
index 780c784..00da491 100644
--- a/ParkanPlayground.sln.DotSettings.user
+++ b/ParkanPlayground.sln.DotSettings.user
@@ -8,4 +8,12 @@
ForceIncluded
ForceIncluded
ForceIncluded
- ForceIncluded
\ No newline at end of file
+ ForceIncluded
+ C:\Users\Admin\AppData\Local\JetBrains\Rider2024.3\resharper-host\temp\Rider\vAny\CoverageData\_ParkanPlayground.1073341822\Snapshot\snapshot.utdcvr
+
+ <SessionState ContinuousTestingMode="0" IsActive="True" Name="Session" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
+ <And>
+ <Namespace>X86DisassemblerTests</Namespace>
+ <Project Location="C:\Projects\CSharp\ParkanPlayground\X86DisassemblerTests" Presentation="<X86DisassemblerTests>" />
+ </And>
+</SessionState>
\ No newline at end of file
diff --git a/X86Disassembler/X86/Handlers/DataTransferHandler.cs b/X86Disassembler/X86/Handlers/DataTransferHandler.cs
index e2226b5..b62f610 100644
--- a/X86Disassembler/X86/Handlers/DataTransferHandler.cs
+++ b/X86Disassembler/X86/Handlers/DataTransferHandler.cs
@@ -316,6 +316,14 @@ public class DataTransferHandler : InstructionHandler
///
private bool DecodeXCHGEAXReg(byte opcode, Instruction instruction)
{
+ // Special case for NOP (XCHG EAX, EAX)
+ if (opcode == 0x90)
+ {
+ instruction.Mnemonic = "nop";
+ instruction.Operands = "";
+ return true;
+ }
+
// Register is encoded in the low 3 bits of the opcode
int reg = opcode & 0x07;
string regName = ModRMDecoder.GetRegisterName(reg, 32);
diff --git a/X86DisassemblerTests/DataTransferInstructionTests.cs b/X86DisassemblerTests/DataTransferInstructionTests.cs
index a90b2fc..376f087 100644
--- a/X86DisassemblerTests/DataTransferInstructionTests.cs
+++ b/X86DisassemblerTests/DataTransferInstructionTests.cs
@@ -72,6 +72,26 @@ public class DataTransferInstructionTests
Assert.Equal("eax, 0x12345678", instruction.Operands);
}
+ ///
+ /// Tests the DataTransferHandler for decoding MOV r8, imm8 instruction (DecodeMOVRegImm8)
+ ///
+ [Fact]
+ public void DataTransferHandler_DecodesMovR8Imm8_Correctly()
+ {
+ // Arrange
+ // MOV AL, 0x42 (B0 42) - Register is encoded in the low 3 bits of the opcode
+ byte[] codeBuffer = new byte[] { 0xB0, 0x42 };
+ var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length);
+
+ // Act
+ var instruction = decoder.DecodeInstruction();
+
+ // Assert
+ Assert.NotNull(instruction);
+ Assert.Equal("mov", instruction.Mnemonic);
+ Assert.Equal("al, 0x42", instruction.Operands);
+ }
+
///
/// Tests the DataTransferHandler for decoding MOV EAX, moffs32 instruction
///
@@ -153,6 +173,46 @@ public class DataTransferInstructionTests
Assert.Equal("eax", instruction.Operands);
}
+ ///
+ /// Tests the DataTransferHandler for decoding PUSH imm32 instruction (DecodePUSHImm32)
+ ///
+ [Fact]
+ public void DataTransferHandler_DecodesPushImm32_Correctly()
+ {
+ // Arrange
+ // PUSH 0x12345678 (68 78 56 34 12)
+ byte[] codeBuffer = new byte[] { 0x68, 0x78, 0x56, 0x34, 0x12 };
+ var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length);
+
+ // Act
+ var instruction = decoder.DecodeInstruction();
+
+ // Assert
+ Assert.NotNull(instruction);
+ Assert.Equal("push", instruction.Mnemonic);
+ Assert.Equal("0x12345678", instruction.Operands);
+ }
+
+ ///
+ /// Tests the DataTransferHandler for decoding PUSH imm8 instruction (DecodePUSHImm8)
+ ///
+ [Fact]
+ public void DataTransferHandler_DecodesPushImm8_Correctly()
+ {
+ // Arrange
+ // PUSH 0x42 (6A 42)
+ byte[] codeBuffer = new byte[] { 0x6A, 0x42 };
+ var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length);
+
+ // Act
+ var instruction = decoder.DecodeInstruction();
+
+ // Assert
+ Assert.NotNull(instruction);
+ Assert.Equal("push", instruction.Mnemonic);
+ Assert.Equal("0x42", instruction.Operands);
+ }
+
///
/// Tests the DataTransferHandler for decoding POP r32 instruction
///
@@ -172,4 +232,44 @@ public class DataTransferInstructionTests
Assert.Equal("pop", instruction.Mnemonic);
Assert.Equal("ecx", instruction.Operands);
}
+
+ ///
+ /// Tests the DataTransferHandler for decoding XCHG EAX, r32 instruction (DecodeXCHGEAXReg)
+ ///
+ [Fact]
+ public void DataTransferHandler_DecodesXchgEaxReg_Correctly()
+ {
+ // Arrange
+ // XCHG EAX, ECX (91) - Register is encoded in the low 3 bits of the opcode
+ byte[] codeBuffer = new byte[] { 0x91 };
+ var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length);
+
+ // Act
+ var instruction = decoder.DecodeInstruction();
+
+ // Assert
+ Assert.NotNull(instruction);
+ Assert.Equal("xchg", instruction.Mnemonic);
+ Assert.Equal("eax, ecx", instruction.Operands);
+ }
+
+ ///
+ /// Tests the DataTransferHandler for decoding NOP instruction (special case of XCHG EAX, EAX)
+ ///
+ [Fact]
+ public void DataTransferHandler_DecodesNop_Correctly()
+ {
+ // Arrange
+ // NOP (90) - This is actually XCHG EAX, EAX which is treated as NOP
+ byte[] codeBuffer = new byte[] { 0x90 };
+ var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length);
+
+ // Act
+ var instruction = decoder.DecodeInstruction();
+
+ // Assert
+ Assert.NotNull(instruction);
+ Assert.Equal("nop", instruction.Mnemonic);
+ Assert.Equal("", instruction.Operands);
+ }
}