public Instruction(ICollection <byte> prefixes, OpCode opCode, ModRegRM modReg = null, Constant constant = null)
 {
     Prefixes = prefixes;
     OpCode   = opCode;
     ModRegRM = modReg;
     Constant = constant;
 }
        public byte[] GetBytes(ModRegRM rm)
        {
            switch (rm.Mod)
            {
            case Mod.E1:
                return(new byte[0]);

            case Mod.E2:
                return(BitConverter.GetBytes((sbyte)Value).Take(1).ToArray());

            case Mod.E3:
                return(BitConverter.GetBytes((int)Value));

            case Mod.E4:
                /*
                 *                  var reg = rm.RegisterOrMemory; // Correct?
                 *                  switch (reg.Size)
                 *                  {
                 *                          case Size.S8:
                 *                                  return BitConverter.GetBytes((sbyte)Value).Take(1).ToArray();
                 *
                 *                          case Size.S16:
                 *                                  return BitConverter.GetBytes((short)Value).ToArray();
                 *
                 *                          case Size.S32:
                 *                                  return BitConverter.GetBytes((int)Value);
                 *                  }
                 *                  break;
                 */
                return(BitConverter.GetBytes((sbyte)Value).Take(1).ToArray());
            }

            throw new Exception();
        }
        private byte[] Encode(OpCode opCode, ModRegRM modReg = null, Constant constant = null)
        {
            List <byte> bytes = new List <byte>();

            bytes.AddRange(opCode.GetBytes());

            if (opCode.Type.HasModRegRM)
            {
                bytes.AddRange(modReg.Encode());
            }

            if (constant != null)
            {
                var label = constant as Label;

                if (label != null)
                {
                    var size = 0;
                    size += opCode.Size;
                    if (opCode.Type.HasModRegRM)
                    {
                        size += modReg.Size;
                    }

                    if (opCode.Is32Bit)
                    {
                        bytes.AddRange(BitConverter.GetBytes((uint)0));
                    }
                    else
                    {
                        bytes.AddRange(BitConverter.GetBytes((ushort)0));
                    }

                    label.References.Add((uint)(Offset + size));
                }
                else
                {
                    if (opCode.Is32Bit)
                    {
                        bytes.AddRange(BitConverter.GetBytes((uint)constant));
                    }
                    else
                    {
                        bytes.AddRange(BitConverter.GetBytes((ushort)constant));
                    }
                }
            }

            return(bytes.ToArray());
        }
        public byte[] Encode()
        {
            var bytes = new List <byte>();

            bytes.AddRange(OpCode.GetBytes());
            if (OpCode.Type.HasModRegRM && ModRegRM != null)
            {
                bytes.AddRange(ModRegRM.Encode());
            }

            if (Constant != null)
            {
                var label = Constant as Label;
                if (label != null)
                {
                    var size = 0;
                    size += OpCode.Size;
                    if (OpCode.Type.HasModRegRM)
                    {
                        size += ModRegRM.Size;
                    }

                    label.References.Add((uint)size);
                    if (OpCode.Is32Bit)
                    {
                        bytes.AddRange(BitConverter.GetBytes((uint)0));
                    }
                    else
                    {
                        bytes.AddRange(BitConverter.GetBytes((ushort)0));
                    }
                }
                else
                {
                    if (OpCode.Is32Bit)
                    {
                        bytes.AddRange(BitConverter.GetBytes((uint)Constant));
                    }
                    else
                    {
                        bytes.AddRange(BitConverter.GetBytes((ushort)Constant));
                    }
                }
            }

            return(bytes.ToArray());
        }
 public Instruction(OpCode opCode, ModRegRM modReg = null, Constant constant = null)
 {
     OpCode   = opCode;
     ModRegRM = modReg;
     Constant = constant;
 }
        public void Emit(OpCode opCode, ModRegRM modRegRm, Constant constant)
        {
            var data = new Instruction(opCode, modRegRm, constant);

            Append(Encode(opCode, modRegRm, constant));
        }
        public void Emit(OpCode opCode, ModRegRM modRegRm)
        {
            var data = new Instruction(opCode, modRegRm);

            Append(Encode(opCode, modRegRm));
        }