source: branches/virtcpu varint/UDisassembler.pas

Last change on this file was 197, checked in by chronos, 5 years ago
  • Modified: All parts of virtual machine have own form in Forms subdirectory.
  • Modified: Main form moved to Forms subdirectory.
  • Modified: TCpu class moved to UCpu unit.
  • Added: Assembler and dissasembler forms.
File size: 2.9 KB
Line 
1unit UDisassembler;
2
3{$mode delphi}
4
5interface
6
7uses
8 Classes, SysUtils, fgl, UCpu, UInstructionReader, Math, UOpcode, UVarInt;
9
10type
11 TDisassemblerLine = class
12 Address: Integer;
13 Opcode: string;
14 Instruction: string;
15 end;
16
17 { TDisassembler }
18
19 TDisassembler = class(TInstructionReader)
20 private
21 OpcodeDefs: TOpcodeDefs;
22 procedure ProcessParam(Param: TOpcodeParam; Line: TDisassemblerLine; Separator: string = '');
23 public
24 Output: TFPGObjectList<TDisassemblerLine>;
25 procedure Process;
26 constructor Create;
27 destructor Destroy; override;
28 end;
29
30
31implementation
32
33{ TDisassembler }
34
35procedure TDisassembler.ProcessParam(Param: TOpcodeParam; Line: TDisassemblerLine; Separator: string = '');
36var
37 Reg: TVarUInt;
38 Data: TVarUInt;
39 Address: TVarUInt;
40 AddressRel: TVarInt;
41begin
42 case Param of
43 prReg: begin
44 Reg := Read;
45 Line.Opcode := Line.Opcode + ' ' + IntToHex(Integer(Reg), 2);
46 Line.Instruction := Line.Instruction + Separator + ' R' + IntToStr(Integer(Reg));
47 end;
48 prData: begin
49 Data := Read;
50 Line.Opcode := Line.Opcode + ' ' + IntToHex(Integer(Data), 8);
51 Line.Instruction := Line.Instruction + Separator + ' ' + IntToHexEx(QWord(Data), -1, '$');
52 end;
53 prAddr: begin
54 Address := Read;
55 Line.Opcode := Line.Opcode + ' ' + IntToHex(Integer(Address), 8);
56 Line.Instruction := Line.Instruction + Separator + ' ' + IntToHexEx(QWord(Address), -1, '$');
57 end;
58 prAddrRel: begin
59 AddressRel := ReadSigned;
60 Line.Opcode := Line.Opcode + ' ' + IntToHexEx(Int64(AddressRel), 8);
61 Line.Instruction := Line.Instruction + Separator + ' ' + IntToHexEx(Int64(AddressRel), -1, '$');
62 end;
63 end;
64end;
65
66procedure TDisassembler.Process;
67var
68 Opcode: TVarUInt;
69 Line: TDisassemblerLine;
70 MemorySize: Integer;
71 OpcodeDef: TOpcodeDef;
72begin
73 Init;
74 Output.Clear;
75
76 MemorySize := MemSize(Cpu.Memory);
77 while IP < MemorySize do begin
78 Opcode := Read;
79 if Opcode <= Integer(High(TOpcode)) then begin
80 OpcodeDef := OpcodeDefs.SearchByOpcode(TOpcode(Integer(Opcode)));
81 Line := TDisassemblerLine.Create;
82 Line.Address := IP - 1;
83 Line.Opcode := IntToHex(Integer(Opcode), 2);
84 Line.Instruction := OpcodeDef.Name;
85 ProcessParam(OpcodeDef.Param1, Line);
86 ProcessParam(OpcodeDef.Param2, Line, ',');
87 ProcessParam(OpcodeDef.Param3, Line, ',');
88 ProcessParam(OpcodeDef.Param4, Line, ',');
89 Output.Add(Line);
90 end else begin
91 {Line := TDisassemblerLine.Create;
92 Line.Address := IP;
93 Line.Opcode := IntToHex(Opcode, 2);
94 Line.Instruction := '';
95 Output.Add(Line);
96 }
97 end;
98 end;
99end;
100
101constructor TDisassembler.Create;
102begin
103 OpcodeDefs := TOpcodeDefs.Create;
104 Output := TFPGObjectList<TDisassemblerLine>.Create;
105end;
106
107destructor TDisassembler.Destroy;
108begin
109 FreeAndNil(Output);
110 FreeAndNil(OpcodeDefs);
111 inherited Destroy;
112end;
113
114
115end.
116
Note: See TracBrowser for help on using the repository browser.