source: branches/ByteArray/Disassembler.pas

Last change on this file was 59, checked in by chronos, 6 months ago
  • Fixed: Assembler and disassembler to work correctly with supported instructions.
File size: 4.3 KB
Line 
1unit Disassembler;
2
3interface
4
5uses
6 Classes, SysUtils, Cpu, Instructions, StrUtils, Memory, BigInt;
7
8type
9
10 { TDisassembler }
11
12 TDisassembler = class
13 private
14 InstText: string;
15 InstBytes: string;
16 InstDataWidth: TBigIntSize;
17 InstAddressWidth: TBigIntSize;
18 procedure DisassembleData;
19 procedure DisassembleAddress;
20 procedure DisassembleRegister;
21 procedure DisassembleRegisterIndirect;
22 procedure DisassembleRegisterIndirectIndex;
23 procedure DisassembleDataWidth;
24 procedure DisassembleAddressWidth;
25 public
26 InstructionSet: TInstructionInfos;
27 Memory: TMemory;
28 DataWidth: TBigIntSize;
29 AddressWidth: TBigIntSize;
30 procedure Disassemble(Lines: TStrings);
31 procedure SaveToFile(FileName: string);
32 constructor Create;
33 destructor Destroy; override;
34 end;
35
36
37implementation
38
39procedure TDisassembler.DisassembleData;
40var
41 Text: string;
42begin
43 Text := IntToHex(Memory.ReadPos(InstDataWidth));
44 if not (Copy(Text, 1, 1)[1] in ['0'..'9']) then Text := '0' + Text;
45 InstText := InstText + Text + 'h';
46end;
47
48procedure TDisassembler.DisassembleAddress;
49var
50 Text: string;
51begin
52 Text := IntToHex(Memory.ReadPos(InstAddressWidth));
53 if not (Copy(Text, 1, 1)[1] in ['0'..'9']) then Text := '0' + Text;
54 InstText := InstText + Text + 'h';
55end;
56
57procedure TDisassembler.DisassembleRegister;
58begin
59 InstText := InstText + 'R' + IntToStr(Byte(Memory.ReadPos(1)));
60end;
61
62procedure TDisassembler.DisassembleRegisterIndirect;
63begin
64 InstText := InstText + '(R' + IntToStr(Byte(Memory.ReadPos(1))) + ')';
65end;
66
67procedure TDisassembler.DisassembleRegisterIndirectIndex;
68begin
69 InstText := InstText + '(R' + IntToStr(Byte(Memory.ReadPos(1))) +
70 ' + ';
71 DisassembleAddress;
72 InstText := InstText + ')';
73end;
74
75procedure TDisassembler.DisassembleDataWidth;
76begin
77 InstDataWidth := Memory.ReadPos(1);
78 InstText := InstText + 'D' + IntToStr(InstDataWidth);
79end;
80
81procedure TDisassembler.DisassembleAddressWidth;
82begin
83 InstAddressWidth := Memory.ReadPos(1);
84 InstText := InstText + 'A' + IntToStr(InstAddressWidth);
85end;
86
87procedure TDisassembler.Disassemble(Lines: TStrings);
88var
89 J: Integer;
90 Value: TBigInt;
91 Instruction: TInstruction;
92 InstructionInfo: TInstructionInfo;
93 Line: string;
94 MemoryPos: Integer;
95 InstructionByteSize: Integer;
96 I: Integer;
97begin
98 Memory.Position := 0;
99 while Memory.Position < Memory.Size do begin
100 Line := IntToHex(Memory.Position, 8) + ' ';
101 MemoryPos := Memory.Position;
102 Value := Memory.ReadPos(1);
103 InstBytes := IntToHex(Value, 2) + ' ';
104 InstText := '';
105 InstAddressWidth := AddressWidth;
106 InstDataWidth := DataWidth;
107 if (Value >= 0) and (Value <= Integer(High(TInstruction))) then begin
108 Instruction := TInstruction(Int64(Value));
109 InstructionInfo := InstructionSet.SearchInstruction(Instruction);
110 if Assigned(InstructionInfo) then begin
111 InstText := InstructionInfo.Name;
112 for J := 0 to Length(InstructionInfo.Params) - 1 do begin
113 if J > 0 then
114 InstText := InstText + ', ' else
115 InstText := InstText + ' ';
116 case InstructionInfo.Params[J] of
117 ptData: DisassembleData;
118 ptAddress: DisassembleAddress;
119 ptReg: DisassembleRegister;
120 ptRegIndirect: DisassembleRegisterIndirect;
121 ptRegIndirectIndex: DisassembleRegisterIndirectIndex;
122 ptDataWidth: DisassembleDataWidth;
123 ptAddressWidth: DisassembleAddressWidth;
124 end;
125 end;
126 end;
127 end;
128
129 // Instruction bytes to hex string
130 InstructionByteSize := Memory.Position - MemoryPos;
131 Memory.Position := MemoryPos;
132 InstBytes := '';
133 for I := 0 to InstructionByteSize - 1 do
134 InstBytes := InstBytes + IntToHex(Memory.ReadPos(1), 2) + ' ';
135 InstBytes := InstBytes + DupeString(' ', 13 - Length(InstBytes));
136
137 Line := Line + InstBytes + InstText;
138 Lines.Add(Line);
139 end;
140end;
141
142procedure TDisassembler.SaveToFile(FileName: string);
143var
144 Lines: TStringList;
145begin
146 Lines := TStringList.Create;
147 Disassemble(Lines);
148 Lines.SaveToFile(FileName);
149 Lines.Free;
150end;
151
152constructor TDisassembler.Create;
153begin
154 InstructionSet := TInstructionInfos.Create;
155 InstructionSet.Init;
156 DataWidth := 1;
157 AddressWidth := 1;
158end;
159
160destructor TDisassembler.Destroy;
161begin
162 FreeAndNil(InstructionSet);
163 inherited;
164end;
165
166end.
167
Note: See TracBrowser for help on using the repository browser.