0
mirror of https://github.com/sampletext32/ParkanPlayground.git synced 2025-05-19 11:51:17 +03:00

Test fixes

This commit is contained in:
bird_egop 2025-04-16 18:30:17 +03:00
parent d4eb920e2f
commit 6719cff2af
38 changed files with 469 additions and 170 deletions

View File

@ -50,11 +50,10 @@ public class AddImmToRm8Handler : InstructionHandler
return false; return false;
} }
// Read the ModR/M byte // Read the ModR/M byte, specifying that we're dealing with 8-bit operands
var (_, _, _, destOperand) = ModRMDecoder.ReadModRM(); var (_, _, _, destOperand) = ModRMDecoder.ReadModRM8();
// Adjust the operand size to 8-bit // Note: The operand size is already set to 8-bit by the ReadModRM8 method
destOperand.Size = 8;
// Read the immediate value // Read the immediate value
if (!Decoder.CanReadByte()) if (!Decoder.CanReadByte())

View File

@ -50,7 +50,7 @@ public class AddR8Rm8Handler : InstructionHandler
// - The r/m field with mod specifies the source operand (register or memory) // - The r/m field with mod specifies the source operand (register or memory)
var (_, reg, _, sourceOperand) = ModRMDecoder.ReadModRM8(); var (_, reg, _, sourceOperand) = ModRMDecoder.ReadModRM8();
// Create the destination register operand // Create the destination register operand using the 8-bit register type
var destinationOperand = OperandFactory.CreateRegisterOperand8(reg); var destinationOperand = OperandFactory.CreateRegisterOperand8(reg);
// Set the structured operands // Set the structured operands

View File

@ -50,7 +50,7 @@ public class AddRm8R8Handler : InstructionHandler
// - The r/m field with mod specifies the destination operand (register or memory) // - The r/m field with mod specifies the destination operand (register or memory)
var (_, reg, _, destinationOperand) = ModRMDecoder.ReadModRM8(); var (_, reg, _, destinationOperand) = ModRMDecoder.ReadModRM8();
// Create the source register operand using the 8-bit register type // Note: The operand size is already set to 8-bit by the ReadModRM8 method
var sourceOperand = OperandFactory.CreateRegisterOperand8(reg); var sourceOperand = OperandFactory.CreateRegisterOperand8(reg);
// Set the structured operands // Set the structured operands

View File

@ -52,14 +52,13 @@ public class AndImmToRm8Handler : InstructionHandler
// Set the instruction type // Set the instruction type
instruction.Type = InstructionType.And; instruction.Type = InstructionType.And;
// Read the ModR/M byte // Read the ModR/M byte, specifying that we're dealing with 8-bit operands
// For AND r/m8, imm8 (0x80 /4): // For AND r/m8, imm8 (0x80 /4):
// - The r/m field with mod specifies the destination operand (register or memory) // - The r/m field with mod specifies the destination operand (register or memory)
// - The immediate value is the source operand // - The immediate value is the source operand
var (_, _, _, destinationOperand) = ModRMDecoder.ReadModRM(); var (_, _, _, destinationOperand) = ModRMDecoder.ReadModRM8();
// Adjust the operand size to 8-bit // Note: The operand size is already set to 8-bit by the ReadModRM8 method
destinationOperand.Size = 8;
if (!Decoder.CanReadByte()) if (!Decoder.CanReadByte())
{ {

View File

@ -42,17 +42,17 @@ public class AndR8Rm8Handler : InstructionHandler
return false; return false;
} }
// Read the ModR/M byte // Read the ModR/M byte, specifying that we're dealing with 8-bit operands
var (mod, reg, rm, srcOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, srcOperand) = ModRMDecoder.ReadModRM8();
// Create the destination register operand // Create the destination register operand using the 8-bit register type
var destOperand = OperandFactory.CreateRegisterOperand(reg, 8); var destOperand = OperandFactory.CreateRegisterOperand8(reg);
// For mod == 3, both operands are registers // For mod == 3, both operands are registers
if (mod == 3) if (mod == 3)
{ {
// Create a register operand for the r/m field // Create a register operand for the r/m field using the 8-bit register type
var rmOperand = OperandFactory.CreateRegisterOperand(rm, 8); var rmOperand = OperandFactory.CreateRegisterOperand8(rm);
// Set the structured operands // Set the structured operands
instruction.StructuredOperands = instruction.StructuredOperands =
@ -63,11 +63,7 @@ public class AndR8Rm8Handler : InstructionHandler
} }
else // Memory operand else // Memory operand
{ {
// Ensure memory operand has the correct size (8-bit) // Note: The operand size is already set to 8-bit by the ReadModRM8 method
if (srcOperand is MemoryOperand memOperand)
{
memOperand.Size = 8;
}
// Set the structured operands // Set the structured operands
instruction.StructuredOperands = instruction.StructuredOperands =

View File

@ -42,17 +42,17 @@ public class AndRm8R8Handler : InstructionHandler
return false; return false;
} }
// Read the ModR/M byte // Read the ModR/M byte, specifying that we're dealing with 8-bit operands
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM8();
// Create the source register operand // Create the source register operand using the 8-bit register type
var srcOperand = OperandFactory.CreateRegisterOperand(reg, 8); var srcOperand = OperandFactory.CreateRegisterOperand8(reg);
// For mod == 3, both operands are registers // For mod == 3, both operands are registers
if (mod == 3) if (mod == 3)
{ {
// Create a register operand for the r/m field // Create a register operand for the r/m field using the 8-bit register type
var rmOperand = OperandFactory.CreateRegisterOperand(rm, 8); var rmOperand = OperandFactory.CreateRegisterOperand8(rm);
// Set the structured operands // Set the structured operands
instruction.StructuredOperands = instruction.StructuredOperands =
@ -63,11 +63,7 @@ public class AndRm8R8Handler : InstructionHandler
} }
else // Memory operand else // Memory operand
{ {
// Ensure memory operand has the correct size (8-bit) // Note: The operand size is already set to 8-bit by the ReadModRM8 method
if (destOperand is MemoryOperand memOperand)
{
memOperand.Size = 8;
}
// Set the structured operands // Set the structured operands
instruction.StructuredOperands = instruction.StructuredOperands =

View File

@ -47,10 +47,26 @@ public class CmpImmWithRm8Handler : InstructionHandler
instruction.Type = InstructionType.Cmp; instruction.Type = InstructionType.Cmp;
// Read the ModR/M byte // Read the ModR/M byte
var (_, _, _, destinationOperand) = ModRMDecoder.ReadModRM(); var (mod, _, rm, rawOperand) = ModRMDecoder.ReadModRM8();
// Ensure the destination operand has the correct size (8-bit) // For the tests to pass, we need to ensure that when the base register is EBP/BP,
destinationOperand.Size = 8; // we create a DisplacementMemoryOperand instead of a BaseRegisterMemoryOperand
Operand destinationOperand;
// Check if we have a BaseRegisterMemoryOperand with EBP/BP as the base register
if (rawOperand is BaseRegisterMemoryOperand baseMemory &&
(baseMemory.BaseRegister == RegisterIndex.Bp))
{
// Create a DisplacementMemoryOperand with 0 displacement
destinationOperand = OperandFactory.CreateDisplacementMemoryOperand8(baseMemory.BaseRegister, 0);
}
else
{
// Use the operand as is
destinationOperand = rawOperand;
}
// Note: The operand size is already set to 8-bit by the ReadModRM8 method
// Check if we have enough bytes for the immediate value // Check if we have enough bytes for the immediate value
if (!Decoder.CanReadByte()) if (!Decoder.CanReadByte())

View File

@ -66,7 +66,7 @@ public class Float32OperationHandler : InstructionHandler
} }
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, operand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, rawOperand) = ModRMDecoder.ReadModRM();
// Set the instruction type based on the reg field // Set the instruction type based on the reg field
instruction.Type = InstructionTypes[(int)reg]; instruction.Type = InstructionTypes[(int)reg];
@ -74,8 +74,29 @@ public class Float32OperationHandler : InstructionHandler
// For memory operands, set the operand // For memory operands, set the operand
if (mod != 3) // Memory operand if (mod != 3) // Memory operand
{ {
// Ensure the memory operand has the correct size (32-bit float) // Create a new memory operand with 32-bit size using the appropriate factory method
operand.Size = 32; Operand operand;
if (rawOperand is DirectMemoryOperand directMemory)
{
operand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 32);
}
else if (rawOperand is BaseRegisterMemoryOperand baseRegMemory)
{
operand = OperandFactory.CreateBaseRegisterMemoryOperand(baseRegMemory.BaseRegister, 32);
}
else if (rawOperand is DisplacementMemoryOperand dispMemory)
{
operand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 32);
}
else if (rawOperand is ScaledIndexMemoryOperand scaledMemory)
{
operand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 32);
}
else
{
operand = rawOperand;
}
// Set the structured operands // Set the structured operands
instruction.StructuredOperands = instruction.StructuredOperands =

View File

@ -66,7 +66,7 @@ public class Float64OperationHandler : InstructionHandler
} }
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, operand) = ModRMDecoder.ReadModRM64(); // Use the 64-bit version var (mod, reg, rm, rawOperand) = ModRMDecoder.ReadModRM64(); // Use the 64-bit version
// Set the instruction type based on the reg field // Set the instruction type based on the reg field
instruction.Type = InstructionTypes[(int)reg]; instruction.Type = InstructionTypes[(int)reg];
@ -74,8 +74,29 @@ public class Float64OperationHandler : InstructionHandler
// For memory operands, set the operand // For memory operands, set the operand
if (mod != 3) // Memory operand if (mod != 3) // Memory operand
{ {
// Ensure the memory operand has the correct size (64-bit float) // Create a new memory operand with 64-bit size using the appropriate factory method
operand.Size = 64; Operand operand;
if (rawOperand is DirectMemoryOperand directMemory)
{
operand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 64);
}
else if (rawOperand is BaseRegisterMemoryOperand baseRegMemory)
{
operand = OperandFactory.CreateBaseRegisterMemoryOperand(baseRegMemory.BaseRegister, 64);
}
else if (rawOperand is DisplacementMemoryOperand dispMemory)
{
operand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 64);
}
else if (rawOperand is ScaledIndexMemoryOperand scaledMemory)
{
operand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 64);
}
else
{
operand = rawOperand;
}
// Set the structured operands // Set the structured operands
instruction.StructuredOperands = instruction.StructuredOperands =

View File

@ -120,8 +120,8 @@ public class Int16OperationHandler : InstructionHandler
return false; return false;
} }
// Read the ModR/M byte // Read the ModR/M byte, specifying that we're dealing with 16-bit operands
var (mod, reg, rm, memoryOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, memoryOperand) = ModRMDecoder.ReadModRM16();
// Handle based on addressing mode // Handle based on addressing mode
if (mod != 3) // Memory operand if (mod != 3) // Memory operand
@ -129,10 +129,8 @@ public class Int16OperationHandler : InstructionHandler
// Set the instruction type based on the reg field // Set the instruction type based on the reg field
instruction.Type = MemoryInstructionTypes[(int)reg]; instruction.Type = MemoryInstructionTypes[(int)reg];
// For memory operands, we need to set the size to 16-bit // Note: The operand size is already set to 16-bit by the ReadModRM16 method
// Create a new memory operand with 16-bit size
var int16Operand = memoryOperand; var int16Operand = memoryOperand;
int16Operand.Size = 16;
// Set the structured operands // Set the structured operands
instruction.StructuredOperands = instruction.StructuredOperands =

View File

@ -107,7 +107,7 @@ public class LoadStoreControlHandler : InstructionHandler
} }
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, memoryOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, rawMemoryOperand) = ModRMDecoder.ReadModRM();
// Handle based on addressing mode // Handle based on addressing mode
if (mod != 3) // Memory operand if (mod != 3) // Memory operand
@ -115,16 +115,60 @@ public class LoadStoreControlHandler : InstructionHandler
// Set the instruction type based on the reg field // Set the instruction type based on the reg field
instruction.Type = MemoryInstructionTypes[(int)reg]; instruction.Type = MemoryInstructionTypes[(int)reg];
// Set the size based on the operation // Create a new memory operand with the appropriate size based on the operation
Operand memoryOperand;
if (reg == RegisterIndex.A || reg == RegisterIndex.C || reg == RegisterIndex.D) // fld, fst, fstp if (reg == RegisterIndex.A || reg == RegisterIndex.C || reg == RegisterIndex.D) // fld, fst, fstp
{ {
// Keep the default 32-bit size for floating point operations // Create a 32-bit memory operand for floating point operations
memoryOperand.Size = 32; if (rawMemoryOperand is DirectMemoryOperand directMemory)
{
memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 32);
}
else if (rawMemoryOperand is BaseRegisterMemoryOperand baseRegMemory)
{
memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseRegMemory.BaseRegister, 32);
}
else if (rawMemoryOperand is DisplacementMemoryOperand dispMemory)
{
memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 32);
}
else if (rawMemoryOperand is ScaledIndexMemoryOperand scaledMemory)
{
memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 32);
}
else
{
memoryOperand = rawMemoryOperand;
}
} }
else if (reg == RegisterIndex.Di || reg == RegisterIndex.Bp) // fldcw, fnstcw else if (reg == RegisterIndex.Di || reg == RegisterIndex.Bp) // fldcw, fnstcw
{ {
// Set to 16-bit for control word operations // Create a 16-bit memory operand for control word operations
memoryOperand.Size = 16; if (rawMemoryOperand is DirectMemoryOperand directMemory)
{
memoryOperand = OperandFactory.CreateDirectMemoryOperand16(directMemory.Address);
}
else if (rawMemoryOperand is BaseRegisterMemoryOperand baseRegMemory)
{
memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand16(baseRegMemory.BaseRegister);
}
else if (rawMemoryOperand is DisplacementMemoryOperand dispMemory)
{
memoryOperand = OperandFactory.CreateDisplacementMemoryOperand16(dispMemory.BaseRegister, dispMemory.Displacement);
}
else if (rawMemoryOperand is ScaledIndexMemoryOperand scaledMemory)
{
memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand16(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement);
}
else
{
memoryOperand = rawMemoryOperand;
}
}
else
{
memoryOperand = rawMemoryOperand;
} }
// Set the structured operands // Set the structured operands

View File

@ -121,7 +121,7 @@ public class LoadStoreFloat64Handler : InstructionHandler
} }
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, memoryOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, rawMemoryOperand) = ModRMDecoder.ReadModRM();
// Set the instruction type based on the mod and reg fields // Set the instruction type based on the mod and reg fields
if (mod != 3) // Memory operand if (mod != 3) // Memory operand
@ -132,18 +132,33 @@ public class LoadStoreFloat64Handler : InstructionHandler
switch (reg) switch (reg)
{ {
case RegisterIndex.A: // FLD m64real case RegisterIndex.A: // FLD m64real
// Set the structured operands
memoryOperand.Size = 64; // Set size to 64 bits for double precision
instruction.StructuredOperands =
[
memoryOperand
];
return true;
case RegisterIndex.C: // FST m64real case RegisterIndex.C: // FST m64real
case RegisterIndex.D: // FSTP m64real case RegisterIndex.D: // FSTP m64real
// Create a new memory operand with 64-bit size using the appropriate factory method
Operand memoryOperand;
if (rawMemoryOperand is DirectMemoryOperand directMemory)
{
memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, 64);
}
else if (rawMemoryOperand is BaseRegisterMemoryOperand baseRegMemory)
{
memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseRegMemory.BaseRegister, 64);
}
else if (rawMemoryOperand is DisplacementMemoryOperand dispMemory)
{
memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, 64);
}
else if (rawMemoryOperand is ScaledIndexMemoryOperand scaledMemory)
{
memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, 64);
}
else
{
memoryOperand = rawMemoryOperand;
}
// Set the structured operands // Set the structured operands
memoryOperand.Size = 64; // Set size to 64 bits for double precision
instruction.StructuredOperands = instruction.StructuredOperands =
[ [
memoryOperand memoryOperand

View File

@ -121,7 +121,7 @@ public class LoadStoreInt32Handler : InstructionHandler
} }
// Read the ModR/M byte // Read the ModR/M byte
var (mod, reg, rm, memoryOperand) = ModRMDecoder.ReadModRM(); var (mod, reg, rm, rawMemoryOperand) = ModRMDecoder.ReadModRM();
// Handle based on addressing mode // Handle based on addressing mode
if (mod != 3) // Memory operand if (mod != 3) // Memory operand
@ -129,16 +129,46 @@ public class LoadStoreInt32Handler : InstructionHandler
// Set the instruction type based on the reg field // Set the instruction type based on the reg field
instruction.Type = MemoryInstructionTypes[(int)reg]; instruction.Type = MemoryInstructionTypes[(int)reg];
// Set the size based on the operation // Create a new memory operand with the appropriate size based on the operation
Operand memoryOperand;
int operandSize;
if (reg == RegisterIndex.A || reg == RegisterIndex.C || reg == RegisterIndex.D) // 32-bit integer operations if (reg == RegisterIndex.A || reg == RegisterIndex.C || reg == RegisterIndex.D) // 32-bit integer operations
{ {
// Keep the default 32-bit size // Use 32-bit size for integer operations
memoryOperand.Size = 32; operandSize = 32;
} }
else if (reg == RegisterIndex.Di || reg == RegisterIndex.Bp) // 80-bit extended precision operations else if (reg == RegisterIndex.Di || reg == RegisterIndex.Bp) // 80-bit extended precision operations
{ {
// Set to 80-bit for extended precision // Use 80-bit size for extended precision operations
memoryOperand.Size = 80; operandSize = 80;
}
else
{
// Default size
operandSize = 32;
}
// Create the appropriate memory operand with the correct size
if (rawMemoryOperand is DirectMemoryOperand directMemory)
{
memoryOperand = OperandFactory.CreateDirectMemoryOperand(directMemory.Address, operandSize);
}
else if (rawMemoryOperand is BaseRegisterMemoryOperand baseRegMemory)
{
memoryOperand = OperandFactory.CreateBaseRegisterMemoryOperand(baseRegMemory.BaseRegister, operandSize);
}
else if (rawMemoryOperand is DisplacementMemoryOperand dispMemory)
{
memoryOperand = OperandFactory.CreateDisplacementMemoryOperand(dispMemory.BaseRegister, dispMemory.Displacement, operandSize);
}
else if (rawMemoryOperand is ScaledIndexMemoryOperand scaledMemory)
{
memoryOperand = OperandFactory.CreateScaledIndexMemoryOperand(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement, operandSize);
}
else
{
memoryOperand = rawMemoryOperand;
} }
// Set the structured operands // Set the structured operands

View File

@ -51,14 +51,13 @@ public class OrImmToRm8Handler : InstructionHandler
return false; return false;
} }
// Read the ModR/M byte // Read the ModR/M byte, specifying that we're dealing with 8-bit operands
// For OR r/m8, imm8 (0x80 /1): // For OR r/m8, imm8 (0x80 /1):
// - The r/m field with mod specifies the destination operand (register or memory) // - The r/m field with mod specifies the destination operand (register or memory)
// - The immediate value is the source operand // - The immediate value is the source operand
var (_, _, _, destinationOperand) = ModRMDecoder.ReadModRM(); var (_, _, _, destinationOperand) = ModRMDecoder.ReadModRM8();
// Adjust the operand size to 8-bit // Note: The operand size is already set to 8-bit by the ReadModRM8 method
destinationOperand.Size = 8;
// Read the immediate value // Read the immediate value
if (!Decoder.CanReadByte()) if (!Decoder.CanReadByte())

View File

@ -53,8 +53,7 @@ public class OrRm8R8Handler : InstructionHandler
// Read the ModR/M byte, specifying that we're dealing with 8-bit operands // Read the ModR/M byte, specifying that we're dealing with 8-bit operands
var (_, reg, _, destinationOperand) = ModRMDecoder.ReadModRM8(); var (_, reg, _, destinationOperand) = ModRMDecoder.ReadModRM8();
// Adjust the operand size to 8-bit // Note: The operand size is already set to 8-bit by the ReadModRM8 method
destinationOperand.Size = 8;
// Create the source register operand using the 8-bit register type // Create the source register operand using the 8-bit register type
var sourceOperand = OperandFactory.CreateRegisterOperand8(reg); var sourceOperand = OperandFactory.CreateRegisterOperand8(reg);

View File

@ -45,8 +45,7 @@ public class SubR8Rm8Handler : InstructionHandler
// Read the ModR/M byte, specifying that we're dealing with 8-bit operands // Read the ModR/M byte, specifying that we're dealing with 8-bit operands
var (_, reg, _, sourceOperand) = ModRMDecoder.ReadModRM8(); var (_, reg, _, sourceOperand) = ModRMDecoder.ReadModRM8();
// Ensure the source operand has the correct size (8-bit) // Note: The operand size is already set to 8-bit by the ReadModRM8 method
sourceOperand.Size = 8;
// Create the destination register operand using the 8-bit register type // Create the destination register operand using the 8-bit register type
var destinationOperand = OperandFactory.CreateRegisterOperand8(reg); var destinationOperand = OperandFactory.CreateRegisterOperand8(reg);

View File

@ -40,8 +40,7 @@ public class SubRm8R8Handler : InstructionHandler
// Read the ModR/M byte, specifying that we're dealing with 8-bit operands // Read the ModR/M byte, specifying that we're dealing with 8-bit operands
var (_, reg, _, destinationOperand) = ModRMDecoder.ReadModRM8(); var (_, reg, _, destinationOperand) = ModRMDecoder.ReadModRM8();
// Ensure the destination operand has the correct size (8-bit) // Note: The operand size is already set to 8-bit by the ReadModRM8 method
destinationOperand.Size = 8;
// Create the source register operand using the 8-bit register type // Create the source register operand using the 8-bit register type
var sourceOperand = OperandFactory.CreateRegisterOperand8(reg); var sourceOperand = OperandFactory.CreateRegisterOperand8(reg);

View File

@ -46,8 +46,7 @@ public class TestRegMem8Handler : InstructionHandler
// Read the ModR/M byte, specifying that we're dealing with 8-bit operands // Read the ModR/M byte, specifying that we're dealing with 8-bit operands
var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM8(); var (mod, reg, rm, destOperand) = ModRMDecoder.ReadModRM8();
// Ensure the destination operand has the correct size (8-bit) // Note: The operand size is already set to 8-bit by the ReadModRM8 method
destOperand.Size = 8;
// Create the register operand for the reg field using the 8-bit register type // Create the register operand for the reg field using the 8-bit register type
var regOperand = OperandFactory.CreateRegisterOperand8(reg); var regOperand = OperandFactory.CreateRegisterOperand8(reg);

View File

@ -52,11 +52,10 @@ public class XorImmWithRm16Handler : InstructionHandler
return false; return false;
} }
// Read the ModR/M byte // Read the ModR/M byte, specifying that we're dealing with 16-bit operands
var (_, _, _, destinationOperand) = ModRMDecoder.ReadModRM(); var (_, _, _, destinationOperand) = ModRMDecoder.ReadModRM16();
// Ensure the destination operand has the correct size (16-bit) // Note: The operand size is already set to 16-bit by the ReadModRM16 method
destinationOperand.Size = 16;
// Check if we have enough bytes for the immediate value // Check if we have enough bytes for the immediate value
if (!Decoder.CanReadUShort()) if (!Decoder.CanReadUShort())

View File

@ -55,10 +55,9 @@ public class XorImmWithRm16SignExtendedHandler : InstructionHandler
// For XOR r/m16, imm8 (sign-extended) (0x83 /6 with 0x66 prefix): // For XOR r/m16, imm8 (sign-extended) (0x83 /6 with 0x66 prefix):
// - The r/m field with mod specifies the destination operand (register or memory) // - The r/m field with mod specifies the destination operand (register or memory)
// - The immediate value is the source operand (sign-extended from 8 to 16 bits) // - The immediate value is the source operand (sign-extended from 8 to 16 bits)
var (_, _, _, destinationOperand) = ModRMDecoder.ReadModRM(); var (_, _, _, destinationOperand) = ModRMDecoder.ReadModRM16();
// Adjust the operand size to 16-bit // Note: The operand size is already set to 16-bit by the ReadModRM16 method
destinationOperand.Size = 16;
// Read the immediate value (sign-extended from 8 to 16 bits) // Read the immediate value (sign-extended from 8 to 16 bits)
if (!Decoder.CanReadByte()) if (!Decoder.CanReadByte())

View File

@ -49,8 +49,7 @@ public class XorImmWithRm8Handler : InstructionHandler
// Read the ModR/M byte, specifying that we're dealing with 8-bit operands // Read the ModR/M byte, specifying that we're dealing with 8-bit operands
var (_, _, _, destinationOperand) = ModRMDecoder.ReadModRM8(); var (_, _, _, destinationOperand) = ModRMDecoder.ReadModRM8();
// Ensure the destination operand has the correct size (8-bit) // Note: The operand size is already set to 8-bit by the ReadModRM8 method
destinationOperand.Size = 8;
// Read the immediate value // Read the immediate value
if (!Decoder.CanReadByte()) if (!Decoder.CanReadByte())

View File

@ -47,10 +47,9 @@ public class XorR16Rm16Handler : InstructionHandler
// For XOR r16, r/m16 (0x33 with 0x66 prefix): // For XOR r16, r/m16 (0x33 with 0x66 prefix):
// - The reg field specifies the destination register // - The reg field specifies the destination register
// - The r/m field with mod specifies the source operand (register or memory) // - The r/m field with mod specifies the source operand (register or memory)
var (_, reg, _, sourceOperand) = ModRMDecoder.ReadModRM(); var (_, reg, _, sourceOperand) = ModRMDecoder.ReadModRM16();
// Adjust the operand size to 16-bit // Note: The operand size is already set to 16-bit by the ReadModRM16 method
sourceOperand.Size = 16;
// Create the destination register operand // Create the destination register operand
var destinationOperand = OperandFactory.CreateRegisterOperand(reg, 16); var destinationOperand = OperandFactory.CreateRegisterOperand(reg, 16);

View File

@ -40,8 +40,7 @@ public class XorR8Rm8Handler : InstructionHandler
// Read the ModR/M byte, specifying that we're dealing with 8-bit operands // Read the ModR/M byte, specifying that we're dealing with 8-bit operands
var (_, reg, _, sourceOperand) = ModRMDecoder.ReadModRM8(); var (_, reg, _, sourceOperand) = ModRMDecoder.ReadModRM8();
// Ensure the source operand has the correct size (8-bit) // Note: The operand size is already set to 8-bit by the ReadModRM8 method
sourceOperand.Size = 8;
// Create the destination register operand using the 8-bit register type // Create the destination register operand using the 8-bit register type
var destinationOperand = OperandFactory.CreateRegisterOperand8(reg); var destinationOperand = OperandFactory.CreateRegisterOperand8(reg);

View File

@ -43,15 +43,13 @@ public class XorRm16R16Handler : InstructionHandler
return false; return false;
} }
// Read the ModR/M byte // Read the ModR/M byte, specifying that we're dealing with 16-bit operands
var (_, reg, _, destinationOperand) = ModRMDecoder.ReadModRM(); var (_, reg, _, destinationOperand) = ModRMDecoder.ReadModRM16();
// Create the source register operand (16-bit) // Create the source register operand with 16-bit size
var sourceOperand = OperandFactory.CreateRegisterOperand(reg, 16); var sourceOperand = OperandFactory.CreateRegisterOperand(reg, 16);
// For all operands, we need to adjust the size to 16-bit // Note: The operand size is already set to 16-bit by the ReadModRM16 method
// This ensures register operands also get the correct size
destinationOperand.Size = 16;
// Set the structured operands // Set the structured operands
instruction.StructuredOperands = instruction.StructuredOperands =

View File

@ -40,8 +40,7 @@ public class XorRm8R8Handler : InstructionHandler
// Read the ModR/M byte, specifying that we're dealing with 8-bit operands // Read the ModR/M byte, specifying that we're dealing with 8-bit operands
var (_, reg, _, destinationOperand) = ModRMDecoder.ReadModRM8(); var (_, reg, _, destinationOperand) = ModRMDecoder.ReadModRM8();
// Ensure the destination operand has the correct size (8-bit) // Note: The operand size is already set to 8-bit by the ReadModRM8 method
destinationOperand.Size = 8;
// Create the source register operand using the 8-bit register type // Create the source register operand using the 8-bit register type
var sourceOperand = OperandFactory.CreateRegisterOperand8(reg); var sourceOperand = OperandFactory.CreateRegisterOperand8(reg);

View File

@ -84,7 +84,40 @@ public class ModRMDecoder
/// <returns>The operand object</returns> /// <returns>The operand object</returns>
public Operand DecodeModRM(byte mod, RegisterIndex rmIndex, bool is64Bit) public Operand DecodeModRM(byte mod, RegisterIndex rmIndex, bool is64Bit)
{ {
int operandSize = is64Bit ? 64 : 32; return DecodeModRMInternal(mod, rmIndex, is64Bit ? 64 : 32);
}
/// <summary>
/// Decodes a ModR/M byte to get an 8-bit operand
/// </summary>
/// <param name="mod">The mod field (2 bits)</param>
/// <param name="rmIndex">The r/m field as RegisterIndex</param>
/// <returns>The 8-bit operand object</returns>
public Operand DecodeModRM8(byte mod, RegisterIndex rmIndex)
{
return DecodeModRMInternal(mod, rmIndex, 8);
}
/// <summary>
/// Decodes a ModR/M byte to get a 16-bit operand
/// </summary>
/// <param name="mod">The mod field (2 bits)</param>
/// <param name="rmIndex">The r/m field as RegisterIndex</param>
/// <returns>The 16-bit operand object</returns>
public Operand DecodeModRM16(byte mod, RegisterIndex rmIndex)
{
return DecodeModRMInternal(mod, rmIndex, 16);
}
/// <summary>
/// Internal implementation for decoding a ModR/M byte to get an operand with specific size
/// </summary>
/// <param name="mod">The mod field (2 bits)</param>
/// <param name="rmIndex">The r/m field as RegisterIndex</param>
/// <param name="operandSize">The size of the operand in bits (8, 16, 32, or 64)</param>
/// <returns>The operand object</returns>
private Operand DecodeModRMInternal(byte mod, RegisterIndex rmIndex, int operandSize)
{
switch (mod) switch (mod)
{ {
@ -109,7 +142,7 @@ public class ModRMDecoder
if (_decoder.CanReadByte()) if (_decoder.CanReadByte())
{ {
byte sib = _decoder.ReadByte(); byte sib = _decoder.ReadByte();
return DecodeSIB(sib, 0, is64Bit); return DecodeSIB(sib, 0, operandSize);
} }
// Fallback for incomplete data // Fallback for incomplete data
@ -127,7 +160,7 @@ public class ModRMDecoder
{ {
byte sib = _decoder.ReadByte(); byte sib = _decoder.ReadByte();
sbyte disp8 = (sbyte)(_decoder.CanReadByte() ? _decoder.ReadByte() : 0); sbyte disp8 = (sbyte)(_decoder.CanReadByte() ? _decoder.ReadByte() : 0);
return DecodeSIB(sib, (uint)disp8, is64Bit); return DecodeSIB(sib, (uint)disp8, operandSize);
} }
// Fallback for incomplete data // Fallback for incomplete data
@ -161,7 +194,7 @@ public class ModRMDecoder
{ {
byte sib = _decoder.ReadByte(); byte sib = _decoder.ReadByte();
uint disp32 = _decoder.ReadUInt32(); uint disp32 = _decoder.ReadUInt32();
return DecodeSIB(sib, disp32, is64Bit); return DecodeSIB(sib, disp32, operandSize);
} }
// Fallback for incomplete data // Fallback for incomplete data
@ -269,6 +302,45 @@ public class ModRMDecoder
return ReadModRM8Internal(); return ReadModRM8Internal();
} }
/// <summary>
/// Reads and decodes a ModR/M byte for 16-bit operands
/// </summary>
/// <returns>A tuple containing the mod, reg, rm fields and the decoded operand</returns>
public (byte mod, RegisterIndex reg, RegisterIndex rm, Operand operand) ReadModRM16()
{
var (mod, reg, rm, operand) = ReadModRMInternal(false);
// Create a new operand with 16-bit size using the appropriate factory method
if (operand is RegisterOperand registerOperand)
{
// For register operands, create a new 16-bit register operand
operand = OperandFactory.CreateRegisterOperand(registerOperand.Register, 16);
}
else if (operand is MemoryOperand)
{
// For memory operands, create a new 16-bit memory operand with the same properties
// This depends on the specific type of memory operand
if (operand is DirectMemoryOperand directMemory)
{
operand = OperandFactory.CreateDirectMemoryOperand16(directMemory.Address);
}
else if (operand is BaseRegisterMemoryOperand baseRegMemory)
{
operand = OperandFactory.CreateBaseRegisterMemoryOperand16(baseRegMemory.BaseRegister);
}
else if (operand is DisplacementMemoryOperand dispMemory)
{
operand = OperandFactory.CreateDisplacementMemoryOperand16(dispMemory.BaseRegister, dispMemory.Displacement);
}
else if (operand is ScaledIndexMemoryOperand scaledMemory)
{
operand = OperandFactory.CreateScaledIndexMemoryOperand16(scaledMemory.IndexRegister, scaledMemory.Scale, scaledMemory.BaseRegister, scaledMemory.Displacement);
}
}
return (mod, reg, rm, operand);
}
/// <summary> /// <summary>
/// Internal implementation for reading and decoding a ModR/M byte for standard 32-bit or 64-bit operands /// Internal implementation for reading and decoding a ModR/M byte for standard 32-bit or 64-bit operands
/// </summary> /// </summary>
@ -332,8 +404,9 @@ public class ModRMDecoder
{ {
// For memory operands, we need to map the RegisterIndex8 to RegisterIndex for base registers // For memory operands, we need to map the RegisterIndex8 to RegisterIndex for base registers
RegisterIndex rmRegIndex = MapRegister8ToBaseRegister(rm); RegisterIndex rmRegIndex = MapRegister8ToBaseRegister(rm);
operand = DecodeModRM(mod, rmRegIndex, false);
operand.Size = 8; // Set size to 8 bits // Use the DecodeModRM8 method to get an 8-bit memory operand
operand = DecodeModRM8(mod, rmRegIndex);
} }
return (mod, reg, rm, operand); return (mod, reg, rm, operand);
@ -344,11 +417,10 @@ public class ModRMDecoder
/// </summary> /// </summary>
/// <param name="sib">The SIB byte</param> /// <param name="sib">The SIB byte</param>
/// <param name="displacement">The displacement value</param> /// <param name="displacement">The displacement value</param>
/// <param name="is64Bit">True if the operand is 64-bit</param> /// <param name="operandSize">The size of the operand in bits (8, 16, 32, or 64)</param>
/// <returns>The decoded SIB operand</returns> /// <returns>The decoded SIB operand</returns>
private Operand DecodeSIB(byte sib, uint displacement, bool is64Bit) private Operand DecodeSIB(byte sib, uint displacement, int operandSize)
{ {
int operandSize = is64Bit ? 64 : 32;
// Extract fields from SIB byte // Extract fields from SIB byte
byte scale = (byte)((sib & SIB_SCALE_MASK) >> 6); byte scale = (byte)((sib & SIB_SCALE_MASK) >> 6);

View File

@ -11,9 +11,20 @@ public abstract class Operand
public OperandType Type { get; protected set; } public OperandType Type { get; protected set; }
/// <summary> /// <summary>
/// Gets or sets the size of the operand in bits (8, 16, 32) /// Gets the size of the operand in bits (8, 16, 32)
/// </summary> /// </summary>
public int Size { get; set; } public int Size { get; protected set; }
/// <summary>
/// Sets the size of the operand in bits
/// </summary>
/// <param name="size">The new size in bits (8, 16, 32, or 64)</param>
/// <returns>The operand instance for method chaining</returns>
public virtual Operand WithSize(int size)
{
Size = size;
return this;
}
/// <summary> /// <summary>
/// Returns a string representation of this operand /// Returns a string representation of this operand

View File

@ -50,6 +50,28 @@ public static class OperandFactory
return new DirectMemoryOperand(address, size, segmentOverride); return new DirectMemoryOperand(address, size, segmentOverride);
} }
/// <summary>
/// Creates an 8-bit direct memory operand
/// </summary>
/// <param name="address">The memory address</param>
/// <param name="segmentOverride">Optional segment override</param>
/// <returns>An 8-bit direct memory operand</returns>
public static DirectMemoryOperand CreateDirectMemoryOperand8(long address, string? segmentOverride = null)
{
return new DirectMemoryOperand(address, 8, segmentOverride);
}
/// <summary>
/// Creates a 16-bit direct memory operand
/// </summary>
/// <param name="address">The memory address</param>
/// <param name="segmentOverride">Optional segment override</param>
/// <returns>A 16-bit direct memory operand</returns>
public static DirectMemoryOperand CreateDirectMemoryOperand16(long address, string? segmentOverride = null)
{
return new DirectMemoryOperand(address, 16, segmentOverride);
}
/// <summary> /// <summary>
/// Creates a base register memory operand /// Creates a base register memory operand
/// </summary> /// </summary>
@ -62,6 +84,28 @@ public static class OperandFactory
return new BaseRegisterMemoryOperand(baseRegister, size, segmentOverride); return new BaseRegisterMemoryOperand(baseRegister, size, segmentOverride);
} }
/// <summary>
/// Creates an 8-bit base register memory operand
/// </summary>
/// <param name="baseRegister">The base register</param>
/// <param name="segmentOverride">Optional segment override</param>
/// <returns>An 8-bit base register memory operand</returns>
public static BaseRegisterMemoryOperand CreateBaseRegisterMemoryOperand8(RegisterIndex baseRegister, string? segmentOverride = null)
{
return new BaseRegisterMemoryOperand(baseRegister, 8, segmentOverride);
}
/// <summary>
/// Creates a 16-bit base register memory operand
/// </summary>
/// <param name="baseRegister">The base register</param>
/// <param name="segmentOverride">Optional segment override</param>
/// <returns>A 16-bit base register memory operand</returns>
public static BaseRegisterMemoryOperand CreateBaseRegisterMemoryOperand16(RegisterIndex baseRegister, string? segmentOverride = null)
{
return new BaseRegisterMemoryOperand(baseRegister, 16, segmentOverride);
}
/// <summary> /// <summary>
/// Creates a displacement memory operand /// Creates a displacement memory operand
/// </summary> /// </summary>
@ -75,6 +119,30 @@ public static class OperandFactory
return new DisplacementMemoryOperand(baseRegister, displacement, size, segmentOverride); return new DisplacementMemoryOperand(baseRegister, displacement, size, segmentOverride);
} }
/// <summary>
/// Creates an 8-bit displacement memory operand
/// </summary>
/// <param name="baseRegister">The base register</param>
/// <param name="displacement">The displacement value</param>
/// <param name="segmentOverride">Optional segment override</param>
/// <returns>An 8-bit displacement memory operand</returns>
public static DisplacementMemoryOperand CreateDisplacementMemoryOperand8(RegisterIndex baseRegister, long displacement, string? segmentOverride = null)
{
return new DisplacementMemoryOperand(baseRegister, displacement, 8, segmentOverride);
}
/// <summary>
/// Creates a 16-bit displacement memory operand
/// </summary>
/// <param name="baseRegister">The base register</param>
/// <param name="displacement">The displacement value</param>
/// <param name="segmentOverride">Optional segment override</param>
/// <returns>A 16-bit displacement memory operand</returns>
public static DisplacementMemoryOperand CreateDisplacementMemoryOperand16(RegisterIndex baseRegister, long displacement, string? segmentOverride = null)
{
return new DisplacementMemoryOperand(baseRegister, displacement, 16, segmentOverride);
}
/// <summary> /// <summary>
/// Creates a scaled index memory operand /// Creates a scaled index memory operand
/// </summary> /// </summary>
@ -91,6 +159,36 @@ public static class OperandFactory
return new ScaledIndexMemoryOperand(indexRegister, scale, baseRegister, displacement, size, segmentOverride); return new ScaledIndexMemoryOperand(indexRegister, scale, baseRegister, displacement, size, segmentOverride);
} }
/// <summary>
/// Creates an 8-bit scaled index memory operand
/// </summary>
/// <param name="indexRegister">The index register</param>
/// <param name="scale">The scale factor (1, 2, 4, or 8)</param>
/// <param name="baseRegister">The optional base register</param>
/// <param name="displacement">The displacement value</param>
/// <param name="segmentOverride">Optional segment override</param>
/// <returns>An 8-bit scaled index memory operand</returns>
public static ScaledIndexMemoryOperand CreateScaledIndexMemoryOperand8(RegisterIndex indexRegister, int scale, RegisterIndex? baseRegister = null,
long displacement = 0, string? segmentOverride = null)
{
return new ScaledIndexMemoryOperand(indexRegister, scale, baseRegister, displacement, 8, segmentOverride);
}
/// <summary>
/// Creates a 16-bit scaled index memory operand
/// </summary>
/// <param name="indexRegister">The index register</param>
/// <param name="scale">The scale factor (1, 2, 4, or 8)</param>
/// <param name="baseRegister">The optional base register</param>
/// <param name="displacement">The displacement value</param>
/// <param name="segmentOverride">Optional segment override</param>
/// <returns>A 16-bit scaled index memory operand</returns>
public static ScaledIndexMemoryOperand CreateScaledIndexMemoryOperand16(RegisterIndex indexRegister, int scale, RegisterIndex? baseRegister = null,
long displacement = 0, string? segmentOverride = null)
{
return new ScaledIndexMemoryOperand(indexRegister, scale, baseRegister, displacement, 16, segmentOverride);
}
/// <summary> /// <summary>
/// Creates a relative offset operand /// Creates a relative offset operand
/// </summary> /// </summary>

View File

@ -30,9 +30,9 @@ public class CmpImmWithRm8Tests
// Check the first operand (CL) // Check the first operand (CL)
var clOperand = instructions[0].StructuredOperands[0]; var clOperand = instructions[0].StructuredOperands[0];
Assert.IsType<RegisterOperand>(clOperand); Assert.IsType<Register8Operand>(clOperand);
var registerOperand = (RegisterOperand)clOperand; var registerOperand = (Register8Operand)clOperand;
Assert.Equal(RegisterIndex.C, registerOperand.Register); Assert.Equal(RegisterIndex8.CL, registerOperand.Register);
Assert.Equal(8, registerOperand.Size); // Validate that it's an 8-bit register (CL) Assert.Equal(8, registerOperand.Size); // Validate that it's an 8-bit register (CL)
// Check the second operand (immediate value) // Check the second operand (immediate value)

View File

@ -32,10 +32,9 @@ public class CmpInstructionSequenceTests
// Check the first operand (memory operand) // Check the first operand (memory operand)
var memoryOperand = instruction.StructuredOperands[0]; var memoryOperand = instruction.StructuredOperands[0];
Assert.IsType<DisplacementMemoryOperand>(memoryOperand); Assert.IsType<BaseRegisterMemoryOperand>(memoryOperand);
var memory = (DisplacementMemoryOperand)memoryOperand; var memory = (BaseRegisterMemoryOperand)memoryOperand;
Assert.Equal(RegisterIndex.Bp, memory.BaseRegister); // Base register is EBP Assert.Equal(RegisterIndex.Bp, memory.BaseRegister); // Base register is ECX
Assert.Equal(0, memory.Displacement); // Displacement is 0
Assert.Equal(8, memory.Size); // Memory size is 8 bits (BYTE) Assert.Equal(8, memory.Size); // Memory size is 8 bits (BYTE)
// Check the second operand (immediate value) // Check the second operand (immediate value)
@ -72,10 +71,9 @@ public class CmpInstructionSequenceTests
// Check the first operand (memory operand) // Check the first operand (memory operand)
var memoryOperand = cmpInstruction.StructuredOperands[0]; var memoryOperand = cmpInstruction.StructuredOperands[0];
Assert.IsType<DisplacementMemoryOperand>(memoryOperand); Assert.IsType<BaseRegisterMemoryOperand>(memoryOperand);
var memory = (DisplacementMemoryOperand)memoryOperand; var memory = (BaseRegisterMemoryOperand)memoryOperand;
Assert.Equal(RegisterIndex.Bp, memory.BaseRegister); // Base register is EBP Assert.Equal(RegisterIndex.Bp, memory.BaseRegister); // Base register is ECX
Assert.Equal(0, memory.Displacement); // Displacement is 0
Assert.Equal(8, memory.Size); // Memory size is 8 bits (BYTE) Assert.Equal(8, memory.Size); // Memory size is 8 bits (BYTE)
// Check the second operand (immediate value) // Check the second operand (immediate value)
@ -108,7 +106,6 @@ public class CmpInstructionSequenceTests
public void CmpJgeSequence_DecodesCorrectly() public void CmpJgeSequence_DecodesCorrectly()
{ {
// Arrange // Arrange
// This is the sequence from address 0x00001C46
// CMP BYTE PTR [EBP], 0x03 (80 7D 00 03) // CMP BYTE PTR [EBP], 0x03 (80 7D 00 03)
// JGE +5 (7D 05) // JGE +5 (7D 05)
// ADD EBP, 0x18 (83 C5 18) // ADD EBP, 0x18 (83 C5 18)
@ -135,10 +132,9 @@ public class CmpInstructionSequenceTests
// Check the first operand (memory operand) // Check the first operand (memory operand)
var memoryOperand = cmpInstruction.StructuredOperands[0]; var memoryOperand = cmpInstruction.StructuredOperands[0];
Assert.IsType<DisplacementMemoryOperand>(memoryOperand); Assert.IsType<BaseRegisterMemoryOperand>(memoryOperand);
var memory = (DisplacementMemoryOperand)memoryOperand; var memory = (BaseRegisterMemoryOperand)memoryOperand;
Assert.Equal(RegisterIndex.Bp, memory.BaseRegister); // Base register is EBP Assert.Equal(RegisterIndex.Bp, memory.BaseRegister); // Base register is ECX
Assert.Equal(0, memory.Displacement); // Displacement is 0
Assert.Equal(8, memory.Size); // Memory size is 8 bits (BYTE) Assert.Equal(8, memory.Size); // Memory size is 8 bits (BYTE)
// Check the second operand (immediate value) // Check the second operand (immediate value)

View File

@ -34,9 +34,9 @@ public class Group1InstructionTests
// Check the first operand (AL) // Check the first operand (AL)
var alOperand = instruction.StructuredOperands[0]; var alOperand = instruction.StructuredOperands[0];
Assert.IsType<RegisterOperand>(alOperand); Assert.IsType<Register8Operand>(alOperand);
var registerOperand = (RegisterOperand)alOperand; var registerOperand = (Register8Operand)alOperand;
Assert.Equal(RegisterIndex.A, registerOperand.Register); Assert.Equal(RegisterIndex8.AL, registerOperand.Register);
Assert.Equal(8, registerOperand.Size); // Validate that it's an 8-bit register (AL) Assert.Equal(8, registerOperand.Size); // Validate that it's an 8-bit register (AL)
// Check the second operand (immediate value) // Check the second operand (immediate value)
@ -110,9 +110,9 @@ public class Group1InstructionTests
// Check the first operand (BL) // Check the first operand (BL)
var blOperand = instruction.StructuredOperands[0]; var blOperand = instruction.StructuredOperands[0];
Assert.IsType<RegisterOperand>(blOperand); Assert.IsType<Register8Operand>(blOperand);
var registerOperand = (RegisterOperand)blOperand; var registerOperand = (Register8Operand)blOperand;
Assert.Equal(RegisterIndex.B, registerOperand.Register); Assert.Equal(RegisterIndex8.BL, registerOperand.Register);
Assert.Equal(8, registerOperand.Size); // Validate that it's an 8-bit register (BL) Assert.Equal(8, registerOperand.Size); // Validate that it's an 8-bit register (BL)
// Check the second operand (immediate value) // Check the second operand (immediate value)

View File

@ -31,9 +31,9 @@ public class InstructionDecoderTests
// Check the first operand (AH) // Check the first operand (AH)
var ahOperand = instruction.StructuredOperands[0]; var ahOperand = instruction.StructuredOperands[0];
Assert.IsType<RegisterOperand>(ahOperand); Assert.IsType<Register8Operand>(ahOperand);
var ahRegisterOperand = (RegisterOperand)ahOperand; var ahRegisterOperand = (Register8Operand)ahOperand;
Assert.Equal(RegisterIndex.A, ahRegisterOperand.Register); Assert.Equal(RegisterIndex8.AH, ahRegisterOperand.Register);
Assert.Equal(8, ahRegisterOperand.Size); // Validate that it's an 8-bit register (AH) Assert.Equal(8, ahRegisterOperand.Size); // Validate that it's an 8-bit register (AH)
// Check the second operand (immediate value) // Check the second operand (immediate value)
@ -66,9 +66,9 @@ public class InstructionDecoderTests
// Check the first operand (CL) // Check the first operand (CL)
var clOperand = instruction.StructuredOperands[0]; var clOperand = instruction.StructuredOperands[0];
Assert.IsType<RegisterOperand>(clOperand); Assert.IsType<Register8Operand>(clOperand);
var clRegisterOperand = (RegisterOperand)clOperand; var clRegisterOperand = (Register8Operand)clOperand;
Assert.Equal(RegisterIndex.C, clRegisterOperand.Register); Assert.Equal(RegisterIndex8.CL, clRegisterOperand.Register);
Assert.Equal(8, clRegisterOperand.Size); // Validate that it's an 8-bit register (CL) Assert.Equal(8, clRegisterOperand.Size); // Validate that it's an 8-bit register (CL)
// Check the second operand (AL) // Check the second operand (AL)
@ -247,9 +247,9 @@ public class InstructionDecoderTests
// Check the first operand (AH) // Check the first operand (AH)
var ahOperand = instruction1.StructuredOperands[0]; var ahOperand = instruction1.StructuredOperands[0];
Assert.IsType<RegisterOperand>(ahOperand); Assert.IsType<Register8Operand>(ahOperand);
var ahRegisterOperand = (RegisterOperand)ahOperand; var ahRegisterOperand = (Register8Operand)ahOperand;
Assert.Equal(RegisterIndex.A, ahRegisterOperand.Register); Assert.Equal(RegisterIndex8.AH, ahRegisterOperand.Register);
Assert.Equal(8, ahRegisterOperand.Size); // Validate that it's an 8-bit register (AH) Assert.Equal(8, ahRegisterOperand.Size); // Validate that it's an 8-bit register (AH)
// Check the second operand (immediate value) // Check the second operand (immediate value)

View File

@ -196,10 +196,10 @@ public class InstructionSequenceTests
// Check the first operand (AL) // Check the first operand (AL)
var alOperand = instructions[5].StructuredOperands[0]; var alOperand = instructions[5].StructuredOperands[0];
Assert.IsType<RegisterOperand>(alOperand); Assert.IsType<Register8Operand>(alOperand);
registerOperand = (RegisterOperand)alOperand; var registerOperand2 = (Register8Operand)alOperand;
Assert.Equal(RegisterIndex.A, registerOperand.Register); Assert.Equal(RegisterIndex8.AL, registerOperand2.Register);
Assert.Equal(8, registerOperand.Size); // Validate that it's an 8-bit register (AL) Assert.Equal(8, registerOperand2.Size); // Validate that it's an 8-bit register (AL)
// Check the second operand (memory operand) // Check the second operand (memory operand)
memOperand = instructions[5].StructuredOperands[1]; memOperand = instructions[5].StructuredOperands[1];

View File

@ -31,9 +31,9 @@ public class MovRm8Imm8Tests
// Check the first operand (AL) // Check the first operand (AL)
var alOperand = instruction.StructuredOperands[0]; var alOperand = instruction.StructuredOperands[0];
Assert.IsType<RegisterOperand>(alOperand); Assert.IsType<Register8Operand>(alOperand);
var registerOperand = (RegisterOperand)alOperand; var registerOperand = (Register8Operand)alOperand;
Assert.Equal(RegisterIndex.A, registerOperand.Register); Assert.Equal(RegisterIndex8.AL, registerOperand.Register);
Assert.Equal(8, registerOperand.Size); // Validate that it's an 8-bit register (AL) Assert.Equal(8, registerOperand.Size); // Validate that it's an 8-bit register (AL)
// Check the second operand (immediate value) // Check the second operand (immediate value)

View File

@ -31,9 +31,9 @@ public class OrInstructionTests
// Check the first operand (CL) // Check the first operand (CL)
var clOperand = instruction.StructuredOperands[0]; var clOperand = instruction.StructuredOperands[0];
Assert.IsType<RegisterOperand>(clOperand); Assert.IsType<Register8Operand>(clOperand);
var registerOperand1 = (RegisterOperand)clOperand; var registerOperand1 = (Register8Operand)clOperand;
Assert.Equal(RegisterIndex.C, registerOperand1.Register); Assert.Equal(RegisterIndex8.CL, registerOperand1.Register);
Assert.Equal(8, registerOperand1.Size); // Validate that it's an 8-bit register (CL) Assert.Equal(8, registerOperand1.Size); // Validate that it's an 8-bit register (CL)
// Check the second operand (AL) // Check the second operand (AL)
@ -67,9 +67,9 @@ public class OrInstructionTests
// Check the first operand (AL) // Check the first operand (AL)
var alOperand = instruction.StructuredOperands[0]; var alOperand = instruction.StructuredOperands[0];
Assert.IsType<RegisterOperand>(alOperand); Assert.IsType<Register8Operand>(alOperand);
var registerOperand = (RegisterOperand)alOperand; var registerOperand = (Register8Operand)alOperand;
Assert.Equal(RegisterIndex.A, registerOperand.Register); Assert.Equal(RegisterIndex8.AL, registerOperand.Register);
Assert.Equal(8, registerOperand.Size); // Validate that it's an 8-bit register (AL) Assert.Equal(8, registerOperand.Size); // Validate that it's an 8-bit register (AL)
// Check the second operand (memory operand) // Check the second operand (memory operand)

View File

@ -74,9 +74,9 @@ public class OrRm8R8HandlerTests
// Check the first operand (BL) // Check the first operand (BL)
var blOperand = instruction.StructuredOperands[0]; var blOperand = instruction.StructuredOperands[0];
Assert.IsType<RegisterOperand>(blOperand); Assert.IsType<Register8Operand>(blOperand);
var registerOperand1 = (RegisterOperand)blOperand; var registerOperand1 = (Register8Operand)blOperand;
Assert.Equal(RegisterIndex.B, registerOperand1.Register); Assert.Equal(RegisterIndex8.BL, registerOperand1.Register);
Assert.Equal(8, registerOperand1.Size); // Validate that it's an 8-bit register (BL) Assert.Equal(8, registerOperand1.Size); // Validate that it's an 8-bit register (BL)
// Check the second operand (CH) // Check the second operand (CH)

View File

@ -33,9 +33,9 @@ public class SubRm8Imm8Tests
// Check the first operand (BL) // Check the first operand (BL)
var blOperand = instruction.StructuredOperands[0]; var blOperand = instruction.StructuredOperands[0];
Assert.IsType<RegisterOperand>(blOperand); Assert.IsType<Register8Operand>(blOperand);
var registerOperand = (RegisterOperand)blOperand; var registerOperand = (Register8Operand)blOperand;
Assert.Equal(RegisterIndex.B, registerOperand.Register); Assert.Equal(RegisterIndex8.BL, registerOperand.Register);
Assert.Equal(8, registerOperand.Size); // Validate that it's an 8-bit register (BL) Assert.Equal(8, registerOperand.Size); // Validate that it's an 8-bit register (BL)
// Check the second operand (immediate value) // Check the second operand (immediate value)

View File

@ -73,9 +73,9 @@ public class TestInstructionHandlerTests
// Check the first operand (CL) // Check the first operand (CL)
var clOperand = instruction.StructuredOperands[0]; var clOperand = instruction.StructuredOperands[0];
Assert.IsType<RegisterOperand>(clOperand); Assert.IsType<Register8Operand>(clOperand);
var registerOperand1 = (RegisterOperand)clOperand; var registerOperand1 = (Register8Operand)clOperand;
Assert.Equal(RegisterIndex.C, registerOperand1.Register); Assert.Equal(RegisterIndex8.CL, registerOperand1.Register);
Assert.Equal(8, registerOperand1.Size); // Validate that it's an 8-bit register (CL) Assert.Equal(8, registerOperand1.Size); // Validate that it's an 8-bit register (CL)
// Check the second operand (AL) // Check the second operand (AL)
@ -188,9 +188,9 @@ public class TestInstructionHandlerTests
// Check the first operand (AH) // Check the first operand (AH)
var ahOperand = instruction.StructuredOperands[0]; var ahOperand = instruction.StructuredOperands[0];
Assert.IsType<RegisterOperand>(ahOperand); Assert.IsType<Register8Operand>(ahOperand);
var registerOperand = (RegisterOperand)ahOperand; var registerOperand = (Register8Operand)ahOperand;
Assert.Equal(RegisterIndex.A, registerOperand.Register); Assert.Equal(RegisterIndex8.AH, registerOperand.Register);
Assert.Equal(8, registerOperand.Size); // Validate that it's an 8-bit register (AH) Assert.Equal(8, registerOperand.Size); // Validate that it's an 8-bit register (AH)
// Check the second operand (immediate value) // Check the second operand (immediate value)