public bool TryDisplacementParse(string sourceString, out ExtendedRegister extendedRegister, out sbyte displacement) { if (!new Regex("^(iy|ix)[+-]", RegexOptions.IgnoreCase).IsMatch(sourceString)) { extendedRegister = ExtendedRegister.None; displacement = 0; return(false); } var possibleRegister = sourceString.Substring(0, 2); var possibleSign = sourceString.Substring(2, 1); var possibleOffset = sourceString.Substring(3).Trim(); var validRegister = Enum.TryParse(possibleRegister, true, out extendedRegister); var validNumber = byte.TryParse(possibleOffset, out byte unsignedDisplacement) || _hexParser.TryByteParse(possibleOffset.Trim('-').Trim('+'), out unsignedDisplacement); displacement = possibleSign == "+" ? (sbyte)unsignedDisplacement : (sbyte)-unsignedDisplacement; return(validRegister && validNumber); }
/// <summary> /// Moves the content from a register to memory where the address is in a register + byte offset /// </summary> /// <param name="codeGenerator">The code generator</param> /// <param name="destinationMemoryRegister">The destination memory register</param> /// <param name="offset">The offset</param> /// <param name="source">The source register</param> public static void MoveRegisterToMemoryRegisterWithByteOffset(IList<byte> codeGenerator, Register destinationMemoryRegister, byte offset, ExtendedRegister source) { codeGenerator.Add(0x4c); codeGenerator.Add(0x89); codeGenerator.Add((byte)(0x40 | (byte)destinationMemoryRegister | (byte)((byte)source << 3))); codeGenerator.Add(offset); }
/// <summary> /// Adds the given int to the given register /// </summary> /// <param name="codeGenerator">The code generator</param> /// <param name="destReg"></param> /// <param name="sourceValue">The source value</param> public static void AddIntToRegister(IList<byte> codeGenerator, ExtendedRegister destReg, int sourceValue) { codeGenerator.Add(0x49); codeGenerator.Add(0x81); codeGenerator.Add((byte)(0xc0 | (byte)destReg)); foreach (var component in BitConverter.GetBytes(sourceValue)) { codeGenerator.Add(component); } }
/// <summary> /// Creates a new extended register /// </summary> /// <param name="extendedRegister">The extended register</param> public IntRegister(ExtendedRegister extendedRegister) { this.IsBase = false; this.BaseRegister = Register.AX; this.ExtendedRegister = extendedRegister; }
public DisplacementOperand(ExtendedRegister register, sbyte displacement) { Register = register; Displacement = displacement; }
/// <summary> /// Calls the given function where the entry points is in a register /// </summary> /// <param name="codeGenerator">The code generator</param> /// <param name="addressRegister">The register where the address is</param> public static void CallInRegister(IList<byte> codeGenerator, ExtendedRegister addressRegister) { codeGenerator.Add(0x41); codeGenerator.Add(0xff); codeGenerator.Add((byte)(0xd0 | (byte)addressRegister)); }
/// <summary> /// Moves the given long (64-bits) to the given register /// </summary> /// <param name="codeGenerator">The code generator</param> /// <param name="destination">The destination register</param> /// <param name="value">The value</param> public static void MoveLongToRegister(IList<byte> codeGenerator, ExtendedRegister destination, long value) { codeGenerator.Add(0x49); codeGenerator.Add((byte)(0xb8 | (byte)destination)); foreach (var component in BitConverter.GetBytes(value)) { codeGenerator.Add(component); } }
/// <summary> /// Moves the content from a memory where the address is a register + int offset to a register /// </summary> /// <param name="codeGenerator">The code generator</param> /// <param name="destination">The destination register</param> /// <param name="sourceMemoryRegister">The source memory register</param> /// <param name="offset">The offset</param> public static void MoveMemoryRegisterWithIntOffsetToRegister( IList<byte> codeGenerator, FloatRegister destination, ExtendedRegister sourceMemoryRegister, int offset) { codeGenerator.Add(0xf3); codeGenerator.Add(0x41); codeGenerator.Add(0x0f); codeGenerator.Add(0x10); codeGenerator.Add((byte)(0x80 | (byte)sourceMemoryRegister | (byte)((byte)destination << 3))); foreach (var component in BitConverter.GetBytes(offset)) { codeGenerator.Add(component); } }
/// <summary> /// Divides the second register from the first /// </summary> /// <param name="codeGenerator">The code generator</param> /// <param name="destination">The destination register</param> /// <param name="source">The source register</param> public static void DivRegisterFromRegister(IList<byte> codeGenerator, Register destination, ExtendedRegister source) { if (destination != Register.AX) { throw new ArgumentException("Only the AX register is supported as destination."); } codeGenerator.Add(0x49); codeGenerator.Add(0xf7); codeGenerator.Add((byte)(0xf8 | (byte)source | (byte)((byte)destination << 3))); }
/// <summary> /// Multiplies the memory by the first register where the memory address is in the second register + offset /// </summary> /// <param name="codeGenerator">The code generator</param> /// <param name="destination">The destination memory register</param> /// <param name="offset">The memory offset</param> /// <param name="sourceMemoryRegister">The source register</param> public static void MultMemoryRegisterWithOffsetByRegister( IList<byte> codeGenerator, Register destination, ExtendedRegister sourceMemoryRegister, int offset) { codeGenerator.Add(0x49); codeGenerator.Add(0x0f); codeGenerator.Add(0xaf); codeGenerator.Add((byte)(0x80 | (byte)destination << 3 | (byte)sourceMemoryRegister)); foreach (var component in BitConverter.GetBytes(offset)) { codeGenerator.Add(component); } }
/// <summary> /// Multiplies the first register by the second /// </summary> /// <param name="codeGenerator">The code generator</param> /// <param name="destination">The destination register</param> /// <param name="source">The source register</param> public static void MultRegisterByRegister(IList<byte> codeGenerator, Register destination, ExtendedRegister source) { codeGenerator.Add(0x49); codeGenerator.Add(0x0f); codeGenerator.Add(0xaf); codeGenerator.Add((byte)(0xc0 | (byte)source | (byte)((byte)destination << 3))); }
/// <summary> /// Subtracts the given int from the given register /// </summary> /// <param name="codeGenerator">The code generator</param> /// <param name="destinationRegister"></param> /// <param name="value">The value</param> public static void SubIntFromRegister(IList<byte> codeGenerator, ExtendedRegister destinationRegister, int value) { codeGenerator.Add(0x49); codeGenerator.Add(0x81); codeGenerator.Add((byte)(0xe8 | (byte)destinationRegister)); foreach (var component in BitConverter.GetBytes(value)) { codeGenerator.Add(component); } }
/// <summary> /// Subtracts the memory to the first register where the memory address is in the second register + offset /// </summary> /// <param name="codeGenerator">The code generator</param> /// <param name="destination">The destination memory register</param> /// <param name="offset">The memory offset</param> /// <param name="sourceMemoryRegister">The source register</param> public static void SubMemoryRegisterWithOffsetFromRegister( IList<byte> codeGenerator, ExtendedRegister destination, ExtendedRegister sourceMemoryRegister, int offset) { codeGenerator.Add(0x4d); codeGenerator.Add(0x2b); codeGenerator.Add((byte)(0x80 | (byte)sourceMemoryRegister | (byte)destination << 3)); foreach (var component in BitConverter.GetBytes(offset)) { codeGenerator.Add(component); } }
/// <summary> /// Subtracts the second register to the memory address which is in the first register + offset /// </summary> /// <param name="codeGenerator">The code generator</param> /// <param name="destinationMemoryRegister">The destination memory register</param> /// <param name="offset">The memory offset</param> /// <param name="source">The source register</param> public static void SubRegisterFromMemoryRegisterWithOffset( IList<byte> codeGenerator, Register destinationMemoryRegister, int offset, ExtendedRegister source) { codeGenerator.Add(0x4c); codeGenerator.Add(0x29); codeGenerator.Add((byte)(0x80 | (byte)destinationMemoryRegister | (byte)source << 3)); if (destinationMemoryRegister == Register.SP) { codeGenerator.Add(0x24); } foreach (var component in BitConverter.GetBytes(offset)) { codeGenerator.Add(component); } }
/// <summary> /// Subtracts the second register from the first /// </summary> /// <param name="codeGenerator">The code generator</param> /// <param name="destination">The destination register</param> /// <param name="source">The source register</param> public static void SubRegisterFromRegister(IList<byte> codeGenerator, ExtendedRegister destination, Register source) { codeGenerator.Add(0x49); codeGenerator.Add(0x29); codeGenerator.Add((byte)(0xc0 | (byte)destination | (byte)((byte)source << 3))); }
/// <summary> /// Moves the content from a register to memory where the address is in a register + int offset /// </summary> /// <param name="codeGenerator">The code generator</param> /// <param name="destinationMemoryRegister">The destination memory register</param> /// <param name="offset">The offset</param> /// <param name="source">The source register</param> public static void MoveRegisterToMemoryRegisterWithIntOffset( IList<byte> codeGenerator, ExtendedRegister destinationMemoryRegister, int offset, Register source) { codeGenerator.Add(0x49); codeGenerator.Add(0x89); codeGenerator.Add((byte)(0x80 | (byte)destinationMemoryRegister | (byte)((byte)source << 3))); foreach (var component in BitConverter.GetBytes(offset)) { codeGenerator.Add(component); } }
/// <summary> /// Moves the content from a memory where the address is a register + int offset to a register /// </summary> /// <param name="codeGenerator">The code generator</param> /// <param name="destination">The destination register</param> /// <param name="sourceMemoryRegister">The source memory register</param> /// <param name="offset">The offset</param> public static void MoveMemoryRegisterWithIntOffsetToRegister( IList<byte> codeGenerator, ExtendedRegister destination, Register sourceMemoryRegister, int offset) { if (sourceMemoryRegister != Register.SP) { codeGenerator.Add(0x4c); codeGenerator.Add(0x8b); codeGenerator.Add((byte)(0x80 | (byte)sourceMemoryRegister | (byte)((byte)destination << 3))); } else { codeGenerator.Add(0x4c); codeGenerator.Add(0x8b); codeGenerator.Add((byte)(0x84 | (byte)((byte)destination << 3))); codeGenerator.Add(0x24); } foreach (var component in BitConverter.GetBytes(offset)) { codeGenerator.Add(component); } }
/// <summary> /// Divides the memory by the first register where the memory address is in the second register + offset /// </summary> /// <param name="codeGenerator">The code generator</param> /// <param name="destination">The destination register</param> /// <param name="offset">The memory offset</param> /// <param name="sourceMemoryRegister">The source register</param> public static void DivMemoryRegisterWithOffsetFromRegister( IList<byte> codeGenerator, Register destination, ExtendedRegister sourceMemoryRegister, int offset) { if (destination != Register.AX) { throw new ArgumentException("Only the AX register is supported as destination."); } codeGenerator.Add(0x49); codeGenerator.Add(0xf7); codeGenerator.Add((byte)(0xb8 | (byte)sourceMemoryRegister | (byte)((byte)destination << 3))); foreach (var component in BitConverter.GetBytes(offset)) { codeGenerator.Add(component); } }
/// <summary> /// Moves the given integer to memory where the address is in a register + offset /// </summary> /// <param name="codeGenerator">The code generator</param> /// <param name="memoryRegister">The destination memory register</param> /// <param name="offset">The memory offset</param> /// <param name="value">The value</param> public static void MoveIntToMemoryRegWithOffset(IList<byte> codeGenerator, ExtendedRegister memoryRegister, int offset, int value) { codeGenerator.Add(0x49); codeGenerator.Add(0xc7); codeGenerator.Add((byte)(0x80 | (byte)memoryRegister)); foreach (var component in BitConverter.GetBytes(offset)) { codeGenerator.Add(component); } foreach (var component in BitConverter.GetBytes(value)) { codeGenerator.Add(component); } }
/// <summary> /// XOR's the second register to the first /// </summary> /// <param name="codeGenerator">The code generator</param> /// <param name="destination">The destination register</param> /// <param name="source">The source register</param> public static void XorRegisterToRegister(IList<byte> codeGenerator, Register destination, ExtendedRegister source) { codeGenerator.Add(0x4c); codeGenerator.Add(0x31); codeGenerator.Add((byte)(0xc0 | (byte)destination | (byte)((byte)source << 3))); }
/// <summary> /// Pushes the given generator /// </summary> /// <param name="codeGenerator">The code generator</param> /// <param name="register">The register</param> public static void PopRegister(IList<byte> codeGenerator, ExtendedRegister register) { codeGenerator.Add(0x41); codeGenerator.Add((byte)(0x58 | (byte)register)); }
/// <summary> /// Compares the two registers /// </summary> /// <param name="codeGenerator">The code generator</param> /// <param name="register1">The first register</param> /// <param name="register2">The second register</param> public static void CompareRegisterToRegister(IList<byte> codeGenerator, Register register1, ExtendedRegister register2) { codeGenerator.Add(0x4c); codeGenerator.Add(0x39); codeGenerator.Add((byte)(0xc0 | (byte)register1 | (byte)((byte)register2 << 3))); }
public RegisterExtendedOperand(ExtendedRegister register) { Register = register; }
/// <summary> /// Moves the content from a register to memory where the address is in a register + offset /// </summary> /// <param name="codeGenerator">The code generator</param> /// <param name="destinationMemoryRegister">The destination memory register</param> /// <param name="offset">The offset</param> /// <param name="source">The source register</param> public static void MoveRegisterToMemoryRegisterWithOffset(IList<byte> codeGenerator, Register destinationMemoryRegister, int offset, ExtendedRegister source) { if (AssemblerHelpers.IsValidByteValue(offset)) { MoveRegisterToMemoryRegisterWithByteOffset(codeGenerator, destinationMemoryRegister, (byte)offset, source); } else { MoveRegisterToMemoryRegisterWithIntOffset(codeGenerator, destinationMemoryRegister, offset, source); } }
/// <summary> /// Creates a new base register /// </summary> /// <param name="baseRegister">The base register</param> public IntRegister(Register baseRegister) { this.IsBase = true; this.BaseRegister = baseRegister; this.ExtendedRegister = ExtendedRegister.R8; }
/// <summary> /// Compares the a register and a memory address /// </summary> /// <param name="codeGenerator">The code generator</param> /// <param name="register1Memory">The register with the address of the first operand</param> /// <param name="register1MemoryOffset">The memory offset</param> /// <param name="register2">The second register</param> public static void CompareMemoryRegisterWithOffsetToRegister( IList<byte> codeGenerator, Register register1Memory, int register1MemoryOffset, ExtendedRegister register2) { codeGenerator.Add(0x4c); codeGenerator.Add(0x39); codeGenerator.Add((byte)(0x80 | (byte)register1Memory | (byte)register2 << 3)); if (register1Memory == Register.SP) { codeGenerator.Add(0x24); } foreach (var component in BitConverter.GetBytes(register1MemoryOffset)) { codeGenerator.Add(component); } }
public IndirectRegisterOperand(ExtendedRegister register) { Register = register; }
/// <summary> /// Compares a register and a memory address /// </summary> /// <param name="codeGenerator">The code generator</param> /// <param name="register1">The first register</param> /// <param name="register2">The second register</param> /// <param name="register2MemoryOffset">The offset for register 2</param> public static void CompareRegisterToMemoryRegisterWithOffset( IList<byte> codeGenerator, FloatRegister register1, ExtendedRegister register2, int register2MemoryOffset) { codeGenerator.Add(0x41); codeGenerator.Add(0x0f); codeGenerator.Add(0x2e); codeGenerator.Add((byte)(0x80 | (byte)register2 | (byte)((byte)register1 << 3))); foreach (var component in BitConverter.GetBytes(register2MemoryOffset)) { codeGenerator.Add(component); } }