示例#1
0
        public static string Disassemble(byte[] program, int length)
        {
            StringBuilder builder = new StringBuilder();

            var position = 0;

            while (position < length)
            {
                var opcode = (Opcode)program[position];

                if (opcode == Opcode.Metadata)
                {
                    var m1 = program[position + 1];
                    var m2 = program[position + 2];
                    var m3 = program[position + 3];

                    builder.AppendFormat("\nFunction\n{0:D3}:\tMethod [Params: {3}]", position, m1, m2, m3);
                    position += 4;
                }
                else
                {
                    builder.AppendFormat("{0:D3}:\t{1, -16}", position, opcode);

                    position++;

                    foreach (Type t in OpcodeDefinition.For(opcode).Params)
                    {
                        if (t == typeof(byte))
                        {
                            builder.AppendFormat("{0:X2} ({0})\t", program[position++]);
                        }
                        else if (t == typeof(short))
                        {
                            builder.AppendFormat("{0:X4} ({0})\t", BitConverter.ToInt16(program, position));
                            position += sizeof(short);
                        }
                        else if (t == typeof(int))
                        {
                            builder.AppendFormat("{0:X8} ({0})\t", BitConverter.ToInt32(program, position));
                            position += sizeof(int);
                        }
                        else if (t == typeof(long))
                        {
                            builder.AppendFormat("{0:X16} ({0})\t", BitConverter.ToInt64(program, position));
                            position += sizeof(int);
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                    }
                }
                builder.AppendLine();
            }


            return(builder.ToString());
        }
示例#2
0
 public void Emit(Opcode opcode, long param1)
 {
     Requires.That(OpcodeDefinition.For(opcode).Params.SequenceEqual(new Type[] { typeof(int) }));
     Buffer.Position = Length;
     writer.Write((byte)opcode);
     writer.Write(param1);
     writer.Flush();
     Length = (int)Buffer.Position;
 }
示例#3
0
        public byte[] Link(IEnumerable <FunctionBuilder> emitters)
        {
            // goes through all the emitters, lays them out in memory and then links them to their
            // actual memory addresses.

            // first emitter is interpreted as main.

            var totalLength  = emitters.Sum(e => e.Length);
            var memoryStream = new MemoryStream(totalLength);
            var addresses    = new Dictionary <string, int>();

            // layout all emitters
            var offset = OpcodeDefinition.Stride(Opcode.Jump16) + OpcodeDefinition.Stride(Opcode.Halt);
            var entry  = emitters.First();

            foreach (var emitter in emitters)
            {
                var disassembly = Disassembler.Disassemble(emitter.Buffer.GetBuffer(), emitter.Length);
                //Console.WriteLine(disassembly);

                Console.WriteLine($"Linked {emitter.Name} @ {offset}");
                addresses.Add(emitter.Name, offset);
                emitter.Address = offset;
                offset         += emitter.Length;
            }

            // set absolute addresses
            foreach (var emitter in emitters)
            {
                foreach (var call in emitter.Calls)
                {
                    emitter.Link(call.Key, addresses[call.Value]);
                }
            }

            // Write jump to entry function.
            memoryStream.WriteByte((byte)Opcode.Call16);
            memoryStream.Write(BitConverter.GetBytes((short)addresses[entry.Name]), 0, sizeof(short));
            memoryStream.WriteByte((byte)Opcode.Halt);

            // iterate through all emitters, and rewrite
            foreach (var emitter in emitters)
            {
                var disassembly = Disassembler.Disassemble(emitter.Buffer.GetBuffer(), emitter.Length);
                //Console.WriteLine(disassembly);
                Requires.That(addresses[emitter.Name] == memoryStream.Position);
                emitter.Buffer.Position = 0;
                emitter.Buffer.CopyTo(memoryStream, emitter.Length);
            }

            memoryStream.Position = 0;
            BinaryReader reader = new BinaryReader(memoryStream);

            return(reader.ReadBytes((int)memoryStream.Length));
        }