Neue Architektur
This commit is contained in:
76
STCompiler.Disassembler/Program.cs
Normal file
76
STCompiler.Disassembler/Program.cs
Normal file
@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using STCompiler.Common;
|
||||
using System.Collections.Generic;
|
||||
|
||||
class Program {
|
||||
static int Main(string[] args) {
|
||||
if (args.Length < 1) {
|
||||
Console.WriteLine("Usage: StDisasm <file.stbc>");
|
||||
return 1;
|
||||
}
|
||||
var path = args[0];
|
||||
if (!File.Exists(path)) { Console.WriteLine("File not found: " + path); return 2; }
|
||||
var data = File.ReadAllBytes(path);
|
||||
try { Disasm(data); } catch(Exception ex) { Console.WriteLine("Error: " + ex.Message); return 3; }
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void Disasm(byte[] data) {
|
||||
using var ms = new MemoryStream(data);
|
||||
using var r = new BinaryReader(ms);
|
||||
|
||||
string magic = Encoding.ASCII.GetString(r.ReadBytes(4));
|
||||
Console.WriteLine($"Magic: {magic}");
|
||||
ushort ver = r.ReadUInt16();
|
||||
Console.WriteLine($"Version: {ver}");
|
||||
ushort nConsts = r.ReadUInt16();
|
||||
Console.WriteLine($"Consts: {nConsts}");
|
||||
var consts = new List<object>();
|
||||
for (int i = 0; i < nConsts; i++) {
|
||||
byte t = r.ReadByte();
|
||||
switch(t) {
|
||||
case 1: { long v = r.ReadInt64(); consts.Add(v); Console.WriteLine($" [{i}] (long) = {v}"); break; }
|
||||
case 2: { double v = r.ReadDouble(); consts.Add(v); Console.WriteLine($" [{i}] (double) = {v}"); break; }
|
||||
case 3: { float v = r.ReadSingle(); consts.Add(v); Console.WriteLine($" [{i}] (float) = {v}"); break; }
|
||||
case 4: { int v = r.ReadInt32(); consts.Add(v); Console.WriteLine($" [{i}] (int) = {v}"); break; }
|
||||
default: { Console.WriteLine($" [{i}] Unknown const type {t}"); break; }
|
||||
}
|
||||
}
|
||||
|
||||
ushort nVars = r.ReadUInt16();
|
||||
Console.WriteLine($"Vars: {nVars}");
|
||||
var varTypes = new byte[nVars];
|
||||
for (int i = 0; i < nVars; i++) { varTypes[i] = r.ReadByte(); Console.WriteLine($" Var[{i}] type = {varTypes[i]}"); }
|
||||
|
||||
ushort codeLen = r.ReadUInt16();
|
||||
Console.WriteLine($"CodeLen: {codeLen} bytes");
|
||||
var code = r.ReadBytes(codeLen);
|
||||
|
||||
Console.WriteLine("\n--- Disassembly ---");
|
||||
int ip = 0;
|
||||
while (ip < code.Length) {
|
||||
int addr = ip;
|
||||
byte op = code[ip++];
|
||||
Console.Write($"{addr:0000}: 0x{op:X2} {Bytecode.OpName(op)} ");
|
||||
switch (op) {
|
||||
case Bytecode.OpCodes.NOP: Console.WriteLine("NOP"); break;
|
||||
case Bytecode.OpCodes.PUSH_CONST: { ushort ci = ReadU16(code, ref ip); Console.WriteLine($"PUSH_CONST {ci} ({consts[ci]})"); break; }
|
||||
case Bytecode.OpCodes.PUSH_REAL_CONST: { ushort ci = ReadU16(code, ref ip); Console.WriteLine($"PUSH_REAL_CONST {ci} ({consts[ci]})"); break; }
|
||||
case Bytecode.OpCodes.LOAD_VAR: { ushort vi = ReadU16(code, ref ip); Console.WriteLine($"LOAD_VAR {vi}"); break; }
|
||||
case Bytecode.OpCodes.STORE_VAR: { ushort vi = ReadU16(code, ref ip); Console.WriteLine($"STORE_VAR {vi}"); break; }
|
||||
case Bytecode.OpCodes.JZ: { ushort target = ReadU16(code, ref ip); Console.WriteLine($"JZ addr={target}"); break; }
|
||||
case Bytecode.OpCodes.JMP: { ushort target = ReadU16(code, ref ip); Console.WriteLine($"JMP addr={target}"); break; }
|
||||
case Bytecode.OpCodes.HALT: Console.WriteLine("HALT"); break;
|
||||
default: Console.WriteLine($"{Bytecode.OpName(op)}"); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static ushort ReadU16(byte[] a, ref int ip) {
|
||||
ushort v = (ushort)(a[ip] | (a[ip+1] << 8));
|
||||
ip += 2;
|
||||
return v;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user