mirror of
				https://github.com/sampletext32/ParkanPlayground.git
				synced 2025-10-31 05:29:43 +03:00 
			
		
		
		
	Fixed instruction handlers and tests for Group1, Group3, and XOR instructions
This commit is contained in:
		| @@ -57,15 +57,26 @@ public class AddImmToRm8Handler : Group1BaseHandler | |||||||
|          |          | ||||||
|         // Read the ModR/M byte |         // Read the ModR/M byte | ||||||
|         byte modRM = CodeBuffer[position++]; |         byte modRM = CodeBuffer[position++]; | ||||||
|         Decoder.SetPosition(position); |  | ||||||
|          |          | ||||||
|         // Extract the fields from the ModR/M byte |         // Extract the fields from the ModR/M byte | ||||||
|         byte mod = (byte)((modRM & 0xC0) >> 6); |         byte mod = (byte)((modRM & 0xC0) >> 6); | ||||||
|         byte reg = (byte)((modRM & 0x38) >> 3); // Should be 0 for ADD |         byte reg = (byte)((modRM & 0x38) >> 3); // Should be 0 for ADD | ||||||
|         byte rm = (byte)(modRM & 0x07); |         byte rm = (byte)(modRM & 0x07); | ||||||
|          |          | ||||||
|         // Decode the destination operand |         // For direct register addressing (mod == 3), use 8-bit register names | ||||||
|         string destOperand = _modRMDecoder.DecodeModRM(mod, rm, false); |         string destOperand; | ||||||
|  |         if (mod == 3) | ||||||
|  |         { | ||||||
|  |             // Use 8-bit register names for direct register addressing | ||||||
|  |             destOperand = GetRegister8(rm); | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             // Use ModR/M decoder for memory addressing | ||||||
|  |             destOperand = _modRMDecoder.DecodeModRM(mod, rm, false); | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         Decoder.SetPosition(position); | ||||||
|          |          | ||||||
|         // Read the immediate value |         // Read the immediate value | ||||||
|         if (position >= Length) |         if (position >= Length) | ||||||
|   | |||||||
| @@ -57,15 +57,26 @@ public class OrImmToRm8Handler : Group1BaseHandler | |||||||
|          |          | ||||||
|         // Read the ModR/M byte |         // Read the ModR/M byte | ||||||
|         byte modRM = CodeBuffer[position++]; |         byte modRM = CodeBuffer[position++]; | ||||||
|         Decoder.SetPosition(position); |  | ||||||
|          |          | ||||||
|         // Extract the fields from the ModR/M byte |         // Extract the fields from the ModR/M byte | ||||||
|         byte mod = (byte)((modRM & 0xC0) >> 6); |         byte mod = (byte)((modRM & 0xC0) >> 6); | ||||||
|         byte reg = (byte)((modRM & 0x38) >> 3); // Should be 1 for OR |         byte reg = (byte)((modRM & 0x38) >> 3); // Should be 1 for OR | ||||||
|         byte rm = (byte)(modRM & 0x07); |         byte rm = (byte)(modRM & 0x07); | ||||||
|          |          | ||||||
|         // Decode the destination operand |         // For direct register addressing (mod == 3), use 8-bit register names | ||||||
|         string destOperand = _modRMDecoder.DecodeModRM(mod, rm, false); |         string destOperand; | ||||||
|  |         if (mod == 3) | ||||||
|  |         { | ||||||
|  |             // Use 8-bit register names for direct register addressing | ||||||
|  |             destOperand = GetRegister8(rm); | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             // Use ModR/M decoder for memory addressing | ||||||
|  |             destOperand = _modRMDecoder.DecodeModRM(mod, rm, false); | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         Decoder.SetPosition(position); | ||||||
|          |          | ||||||
|         // Read the immediate value |         // Read the immediate value | ||||||
|         if (position >= Length) |         if (position >= Length) | ||||||
|   | |||||||
| @@ -23,6 +23,7 @@ public class NotRm32Handler : Group3BaseHandler | |||||||
|     /// <returns>True if this handler can decode the opcode</returns> |     /// <returns>True if this handler can decode the opcode</returns> | ||||||
|     public override bool CanHandle(byte opcode) |     public override bool CanHandle(byte opcode) | ||||||
|     { |     { | ||||||
|  |         // This handler only handles opcode 0xF7 | ||||||
|         if (opcode != 0xF7) |         if (opcode != 0xF7) | ||||||
|             return false; |             return false; | ||||||
|              |              | ||||||
| @@ -45,9 +46,6 @@ public class NotRm32Handler : Group3BaseHandler | |||||||
|     /// <returns>True if the instruction was successfully decoded</returns> |     /// <returns>True if the instruction was successfully decoded</returns> | ||||||
|     public override bool Decode(byte opcode, Instruction instruction) |     public override bool Decode(byte opcode, Instruction instruction) | ||||||
|     { |     { | ||||||
|         // Set the mnemonic |  | ||||||
|         instruction.Mnemonic = "not"; |  | ||||||
|          |  | ||||||
|         int position = Decoder.GetPosition(); |         int position = Decoder.GetPosition(); | ||||||
|          |          | ||||||
|         if (position >= Length) |         if (position >= Length) | ||||||
| @@ -57,15 +55,34 @@ public class NotRm32Handler : Group3BaseHandler | |||||||
|          |          | ||||||
|         // Read the ModR/M byte |         // Read the ModR/M byte | ||||||
|         byte modRM = CodeBuffer[position++]; |         byte modRM = CodeBuffer[position++]; | ||||||
|         Decoder.SetPosition(position); |  | ||||||
|          |          | ||||||
|         // Extract the fields from the ModR/M byte |         // Extract the fields from the ModR/M byte | ||||||
|         byte mod = (byte)((modRM & 0xC0) >> 6); |         byte mod = (byte)((modRM & 0xC0) >> 6); | ||||||
|         byte reg = (byte)((modRM & 0x38) >> 3); // Should be 2 for NOT |         byte reg = (byte)((modRM & 0x38) >> 3); // Should be 2 for NOT | ||||||
|         byte rm = (byte)(modRM & 0x07); |         byte rm = (byte)(modRM & 0x07); | ||||||
|          |          | ||||||
|         // Decode the operand |         // Verify this is a NOT instruction | ||||||
|         string operand = _modRMDecoder.DecodeModRM(mod, rm, false); |         if (reg != 2) | ||||||
|  |         { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         // Set the mnemonic | ||||||
|  |         instruction.Mnemonic = "not"; | ||||||
|  |          | ||||||
|  |         Decoder.SetPosition(position); | ||||||
|  |          | ||||||
|  |         // For direct register addressing (mod == 3), the r/m field specifies a register | ||||||
|  |         string operand; | ||||||
|  |         if (mod == 3) | ||||||
|  |         { | ||||||
|  |             operand = GetRegister32(rm); | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             // Use the ModR/M decoder for memory addressing | ||||||
|  |             operand = _modRMDecoder.DecodeModRM(mod, rm, false); | ||||||
|  |         } | ||||||
|          |          | ||||||
|         // Set the operands |         // Set the operands | ||||||
|         instruction.Operands = operand; |         instruction.Operands = operand; | ||||||
|   | |||||||
| @@ -37,11 +37,24 @@ public class InstructionHandlerFactory | |||||||
|     /// </summary> |     /// </summary> | ||||||
|     private void RegisterHandlers() |     private void RegisterHandlers() | ||||||
|     { |     { | ||||||
|  |         // Register Group3 handlers first to ensure they take precedence | ||||||
|  |         // over generic handlers for the same opcodes | ||||||
|  |         RegisterGroup3Handlers(); | ||||||
|  |          | ||||||
|  |         // Register Group1 handlers | ||||||
|  |         RegisterGroup1Handlers(); | ||||||
|  |          | ||||||
|         // Register specific instruction handlers |         // Register specific instruction handlers | ||||||
|         _handlers.Add(new RetHandler(_codeBuffer, _decoder, _length)); |         _handlers.Add(new RetHandler(_codeBuffer, _decoder, _length)); | ||||||
|         _handlers.Add(new RetImmHandler(_codeBuffer, _decoder, _length)); |         _handlers.Add(new RetImmHandler(_codeBuffer, _decoder, _length)); | ||||||
|         _handlers.Add(new CallRel32Handler(_codeBuffer, _decoder, _length)); |         _handlers.Add(new CallRel32Handler(_codeBuffer, _decoder, _length)); | ||||||
|  |          | ||||||
|  |         // XOR handlers | ||||||
|         _handlers.Add(new XorRegMemHandler(_codeBuffer, _decoder, _length)); |         _handlers.Add(new XorRegMemHandler(_codeBuffer, _decoder, _length)); | ||||||
|  |         _handlers.Add(new XorMemRegHandler(_codeBuffer, _decoder, _length)); | ||||||
|  |         _handlers.Add(new XorAlImmHandler(_codeBuffer, _decoder, _length)); | ||||||
|  |         _handlers.Add(new XorEaxImmHandler(_codeBuffer, _decoder, _length)); | ||||||
|  |  | ||||||
|         _handlers.Add(new FnstswHandler(_codeBuffer, _decoder, _length)); |         _handlers.Add(new FnstswHandler(_codeBuffer, _decoder, _length)); | ||||||
|  |  | ||||||
|         // TEST handlers |         // TEST handlers | ||||||
| @@ -58,12 +71,6 @@ public class InstructionHandlerFactory | |||||||
|         _handlers.Add(new ConditionalJumpHandler(_codeBuffer, _decoder, _length)); |         _handlers.Add(new ConditionalJumpHandler(_codeBuffer, _decoder, _length)); | ||||||
|         _handlers.Add(new TwoByteConditionalJumpHandler(_codeBuffer, _decoder, _length)); |         _handlers.Add(new TwoByteConditionalJumpHandler(_codeBuffer, _decoder, _length)); | ||||||
|          |          | ||||||
|         // Register Group1 handlers |  | ||||||
|         RegisterGroup1Handlers(); |  | ||||||
|          |  | ||||||
|         // Register Group3 handlers |  | ||||||
|         RegisterGroup3Handlers(); |  | ||||||
|          |  | ||||||
|         // Register group handlers for instructions that share similar decoding logic |         // Register group handlers for instructions that share similar decoding logic | ||||||
|         _handlers.Add(new FloatingPointHandler(_codeBuffer, _decoder, _length)); |         _handlers.Add(new FloatingPointHandler(_codeBuffer, _decoder, _length)); | ||||||
|         _handlers.Add(new DataTransferHandler(_codeBuffer, _decoder, _length)); |         _handlers.Add(new DataTransferHandler(_codeBuffer, _decoder, _length)); | ||||||
|   | |||||||
| @@ -127,9 +127,17 @@ public class InstructionDecoder | |||||||
|         // Get a handler for the opcode |         // Get a handler for the opcode | ||||||
|         var handler = _handlerFactory.GetHandler(opcode); |         var handler = _handlerFactory.GetHandler(opcode); | ||||||
|          |          | ||||||
|         if (handler == null || !handler.Decode(opcode, instruction)) |         bool handlerSuccess = false; | ||||||
|  |          | ||||||
|  |         // Try to decode with a handler first | ||||||
|  |         if (handler != null) | ||||||
|         { |         { | ||||||
|  |             handlerSuccess = handler.Decode(opcode, instruction); | ||||||
|  |         } | ||||||
|  |          | ||||||
|         // If no handler is found or decoding fails, create a default instruction |         // If no handler is found or decoding fails, create a default instruction | ||||||
|  |         if (!handlerSuccess) | ||||||
|  |         { | ||||||
|             instruction.Mnemonic = OpcodeMap.GetMnemonic(opcode); |             instruction.Mnemonic = OpcodeMap.GetMnemonic(opcode); | ||||||
|             instruction.Operands = "??"; |             instruction.Operands = "??"; | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -72,13 +72,14 @@ public class JumpInstructionTests | |||||||
|     } |     } | ||||||
|      |      | ||||||
|     /// <summary> |     /// <summary> | ||||||
|     /// Tests the TwoByteConditionalJumpHandler for decoding JNE rel32 instruction |     /// Tests the TwoByteConditionalJumpHandler for decoding JNZ rel32 instruction | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     [Fact] |     [Fact] | ||||||
|     public void TwoByteConditionalJumpHandler_DecodesJneRel32_Correctly() |     public void TwoByteConditionalJumpHandler_DecodesJnzRel32_Correctly() | ||||||
|     { |     { | ||||||
|         // Arrange |         // Arrange | ||||||
|         // JNE +0x12345678 (0F 85 78 56 34 12) - Jump 0x12345678 bytes forward if not equal |         // JNZ +0x12345678 (0F 85 78 56 34 12) - Jump 0x12345678 bytes forward if not zero/not equal | ||||||
|  |         // Note: JNZ and JNE are equivalent in x86 | ||||||
|         byte[] codeBuffer = new byte[] { 0x0F, 0x85, 0x78, 0x56, 0x34, 0x12 }; |         byte[] codeBuffer = new byte[] { 0x0F, 0x85, 0x78, 0x56, 0x34, 0x12 }; | ||||||
|         var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length); |         var decoder = new InstructionDecoder(codeBuffer, codeBuffer.Length); | ||||||
|          |          | ||||||
| @@ -87,7 +88,7 @@ public class JumpInstructionTests | |||||||
|          |          | ||||||
|         // Assert |         // Assert | ||||||
|         Assert.NotNull(instruction); |         Assert.NotNull(instruction); | ||||||
|         Assert.Equal("jne", instruction.Mnemonic); |         Assert.Equal("jnz", instruction.Mnemonic); | ||||||
|         Assert.Equal("0x1234567E", instruction.Operands); // Current position (6) + offset (0x12345678) = 0x1234567E |         Assert.Equal("0x1234567E", instruction.Operands); // Current position (6) + offset (0x12345678) = 0x1234567E | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 bird_egop
					bird_egop