source: branches/virtualcpu4/UDisassembler.pas

Last change on this file was 185, checked in by chronos, 5 years ago
  • Added: Assembler labels reference address calculation.
  • Fixed: Displaying address/data hex numbers in opcode and instruction.
File size: 5.0 KB
Line 
1unit UDisassembler;
2
3{$mode delphi}
4
5interface
6
7uses
8 Classes, SysUtils, UMemory, fgl, UCpu, UInstructionReader, Math, UOpcode;
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 public
23 Output: TFPGObjectList<TDisassemblerLine>;
24 procedure Process;
25 constructor Create;
26 destructor Destroy; override;
27 end;
28
29
30implementation
31
32{ TDisassembler }
33
34procedure TDisassembler.Process;
35var
36 Opcode: Byte;
37 Line: TDisassemblerLine;
38 MemorySize: Integer;
39 Data: QWord;
40 Address: TAddress;
41 AddressRel: TAddressSigned;
42 Reg: TRegIndex;
43 OpcodeDef: TOpcodeDef;
44begin
45 Init;
46 Output.Clear;
47
48 MemorySize := MemSize(Cpu.Memory);
49 while IP < MemorySize do begin
50 Prefix := False;
51 Opcode := Read8;
52 if Opcode <= Integer(High(TOpcode)) then begin
53 OpcodeDef := OpcodeDefs.SearchByOpcode(TOpcode(Opcode));
54 Prefix := OpcodeDef.Prefix;
55 case TOpcode(Opcode) of
56 opDataPrefix8: DataSize := bw8;
57 opDataPrefix16: DataSize := bw16;
58 opDataPrefix32: DataSize := bw32;
59 opDataPrefix64: DataSize := bw64;
60 opAddrPrefix8: AddrSize := bw8;
61 opAddrPrefix16: AddrSize := bw16;
62 opAddrPrefix32: AddrSize := bw32;
63 opAddrPrefix64: AddrSize := bw64;
64 end;
65 Line := TDisassemblerLine.Create;
66 Line.Address := IP - 1;
67 Line.Opcode := IntToHex(Opcode, 2);
68 Line.Instruction := OpcodeDef.Name;
69 case OpcodeDef.Param1 of
70 prReg: begin
71 Reg := Read8;
72 Line.Opcode := Line.Opcode + ' ' + IntToHex(Reg, 2);
73 Line.Instruction := Line.Instruction + ' R' + IntToStr(Reg);
74 end;
75 prData: begin
76 Data := ReadData;
77 Line.Opcode := Line.Opcode + ' ' + IntToHex(Data, BitWidthBytes[DataSize] * 2);
78 Line.Instruction := Line.Instruction + ' ' + IntToHexEx(Data, -1, '$');
79 end;
80 prAddr: begin
81 Address := ReadAddress;
82 Line.Opcode := Line.Opcode + ' ' + IntToHex(Address, BitWidthBytes[AddrSize] * 2);
83 Line.Instruction := Line.Instruction + ' ' + IntToHexEx(Address, -1, '$');
84 end;
85 prAddrRel: begin
86 AddressRel := ReadAddressSigned;
87 Line.Opcode := Line.Opcode + ' ' + IntToHexEx(QWord(AddressRel), BitWidthBytes[AddrSize] * 2);
88 Line.Instruction := Line.Instruction + ' ' + IntToHexEx(AddressRel, -1, '$');
89 end;
90 end;
91 case OpcodeDef.Param2 of
92 prReg: begin
93 Reg := Read8;
94 Line.Opcode := Line.Opcode + ' ' + IntToHex(Reg, 2);
95 Line.Instruction := Line.Instruction + ', R' + IntToStr(Reg);
96 end;
97 prData: begin
98 Data := ReadData;
99 Line.Opcode := Line.Opcode + ' ' + IntToHexEx(Data, BitWidthBytes[DataSize] * 2);
100 Line.Instruction := Line.Instruction + ', ' + IntToHexEx(Data, -1, '$');
101 end;
102 prAddr: begin
103 Address := ReadAddress;
104 Line.Opcode := Line.Opcode + ' ' + IntToHex(Address, BitWidthBytes[AddrSize] * 2);
105 Line.Instruction := Line.Instruction + ', ' + IntToHexEx(Address, -1, '$');
106 end;
107 prAddrRel: begin
108 AddressRel := ReadAddressSigned;
109 Line.Opcode := Line.Opcode + ' ' + IntToHex(QWord(AddressRel), BitWidthBytes[AddrSize] * 2);
110 Line.Instruction := Line.Instruction + ', ' + IntToHexEx(AddressRel, -1, '$');
111 end;
112 end;
113 case OpcodeDef.Param3 of
114 prReg: begin
115 Reg := Read8;
116 Line.Opcode := Line.Opcode + ' ' + IntToHex(Reg, 2);
117 Line.Instruction := Line.Instruction + ', R' + IntToStr(Reg);
118 end;
119 prData: begin
120 Data := ReadData;
121 Line.Opcode := Line.Opcode + ' ' + IntToHex(Data, BitWidthBytes[DataSize] * 2);
122 Line.Instruction := Line.Instruction + ', ' + IntToHexEx(Data, -1, '$');
123 end;
124 prAddr: begin
125 Address := ReadAddress;
126 Line.Opcode := Line.Opcode + ' ' + IntToHex(Address, BitWidthBytes[AddrSize] * 2);
127 Line.Instruction := Line.Instruction + ', ' + IntToHexEx(Address, -1, '$');
128 end;
129 prAddrRel: begin
130 AddressRel := ReadAddressSigned;
131 Line.Opcode := Line.Opcode + ' ' + IntToHex(QWord(AddressRel), BitWidthBytes[AddrSize] * 2);
132 Line.Instruction := Line.Instruction + ', ' + IntToHexEx(AddressRel, -1, '$');
133 end;
134 end;
135 Output.Add(Line);
136 if not Prefix then begin
137 DataSize := DataSizeBase;
138 AddrSize := AddrSizeBase;
139 end;
140 end else begin
141 {Line := TDisassemblerLine.Create;
142 Line.Address := IP;
143 Line.Opcode := IntToHex(Opcode, 2);
144 Line.Instruction := '';
145 Output.Add(Line);
146 }
147 end;
148 end;
149end;
150
151constructor TDisassembler.Create;
152begin
153 OpcodeDefs := TOpcodeDefs.Create;
154 Output := TFPGObjectList<TDisassemblerLine>.Create;
155end;
156
157destructor TDisassembler.Destroy;
158begin
159 FreeAndNil(Output);
160 FreeAndNil(OpcodeDefs);
161 inherited Destroy;
162end;
163
164
165end.
166
Note: See TracBrowser for help on using the repository browser.