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="&lt;X86DisassemblerTests&gt;" /> + </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); + } }