📄 dcinstrsource.pas
字号:
unit dcInstrSource;
interface
uses
Classes, DisAsmX;
type
{ IInstrSource }
IInstrSource = interface;
TGetSourcesCallback = procedure (Source: IInstrSource) of object;
TAsPascalCallback = procedure (Source: IInstrSource; var AsPascal: string) of object;
IInstrSource = interface(IUnknown)
['{9E19A141-FE8D-11D3-9895-AF349D573647}']
function Replace(FindSource, ReplaceSource: IInstrSource): IInstrSource;
function Compare(ASource: IInstrSource): Boolean;
procedure GetSources(Callback: TGetSourcesCallback);
function AsPascal(Callback: TAsPascalCallback): string;
function Optimize: IInstrSource;
end;
{ IMonoSource }
TMonoSourceType = (mostRef);
IMonoSource = interface(IInstrSource)
['{9E19A140-FE8D-11D3-9895-AF349D573647}']
function GetSource: IInstrSource;
function GetSourceType: TMonoSourceType;
property Source: IInstrSource read GetSource;
property SourceType: TMonoSourceType read GetSourceType;
end;
{ IRefSource }
IRefSource = interface(IMonoSource)
['{9E19A142-FE8D-11D3-9895-AF349D573647}']
function GetSize: Integer;
property Size: Integer read GetSize;
end;
{ IDuoSource }
TDuoSourceType = (dstMultiply, dstDivide, dstAdd, dstSub);
IDuoSource = interface(IInstrSource)
['{9E19A143-FE8D-11D3-9895-AF349D573647}']
function GetSource1: IInstrSource;
function GetSource2: IInstrSource;
function GetSourceType: TDuoSourceType;
property Source1: IInstrSource read GetSource1;
property Source2: IInstrSource read GetSource2;
property SourceType: TDuoSourceType read GetSourceType;
end;
(* { IMultiSource }
TMultiSourceType = (mustFuncCall);
IMultiSource = interface(IInstrSource)
['{9E19A144-FE8D-11D3-9895-AF349D573647}']
function GetItem(Index: Integer): IInstrSource;
function GetCount: Integer;
function GetSourceType: TMultiSourceType;
property Count: Integer read GetCount;
property Items[Index: Integer]: IInstrSource read GetItem;
property SourceType: TMultiSourceType read GetSourceType;
end;
*)
{ IRegSource }
IRegSource = interface(IInstrSource)
['{9E19A145-FE8D-11D3-9895-AF349D573647}']
function GetReg: TRegister;
function GetRegType: TRegisterType;
property RegType: TRegisterType read GetRegType;
property Reg: TRegister read GetReg;
end;
{ IConstSource }
IConstSource = interface(IInstrSource)
['{9E19A146-FE8D-11D3-9895-AF349D573647}']
function GetValue: Cardinal;
property Value: Cardinal read GetValue;
end;
{ IAddressSource }
IAddressSource = interface(IInstrSource)
['{9E19A147-FE8D-11D3-9895-AF349D573647}']
function GetAddress: TAddress;
property Address: TAddress read GetAddress;
end;
// Interface creation functions.
// function CreateMonoSource(ASource: IInstrSource; ASourceType: TMonoSourceType): IMonoSource;
function CreateDuoSource(ASource1, ASource2: IInstrSource; ASourceType: TDuoSourceType): IDuoSource;
// function CreateMultiSource(const AItems: array of IInstrSource; ASourceType: TMultiSourceType): IMultiSource;
function CreateRegSource(AReg: TRegister; ARegType: TRegisterType): IRegSource;
function CreateConstSource(AValue: Cardinal): IConstSource;
function CreateAddressSource(AAddress: TAddress): IAddressSource;
function CreateRefSource(ASource: IInstrSource; ASize: Integer): IRefSource;
// Creates a IIinstrSource from an TOpcInstr
function ConvArgToIInstr(const Arg: TArgument): IInstrSource;
type
TIsAddressCallback = procedure (Imm: TAddress; var IsAddress: Boolean) of object;
var
IsImmAddressCallback: TIsAddressCallback;
implementation
uses
ActiveX, SysUtils, dcProcInstr;
type
{ TInstrSource }
TInstrSource = class(TInterfacedObject, IInstrSource)
public
function Replace(FindSource, ReplaceSource: IInstrSource): IInstrSource; virtual; abstract;
function Compare(ASource: IInstrSource): Boolean; virtual; abstract;
procedure GetSources(Callback: TGetSourcesCallback); virtual;
function AsPascal(Callback: TAsPascalCallback): string; virtual; abstract;
function Optimize: IInstrSource; virtual;
end;
{ TODO -cAdditions : Add GetSources and AsPascal for the TMultipleSource.}
{ TODO -cAdditions : Add override Optimize for TInstrSources descendants }
{ TMonoSource }
TMonoSource = class(TInstrSource, IMonoSource)
private
FSource: IInstrSource;
FSourceType: TMonoSourceType;
function GetSource: IInstrSource;
function GetSourceType: TMonoSourceType;
public
constructor Create(ASource: IInstrSource; ASourceType: TMonoSourceType);
// function Replace(FindSource, ReplaceSource: IInstrSource): IInstrSource; o
function Compare(ASource: IInstrSource): Boolean; override;
procedure GetSources(Callback: TGetSourcesCallback); override;
property Source: IInstrSource read GetSource;
property SourceType: TMonoSourceType read GetSourceType;
end;
{ TRefSoucre }
TRefSource = class(TMonoSource, IRefSource)
private
FSize: Integer;
function GetSize: Integer;
public
constructor Create(ASource: IInstrSource; ASize: Integer);
function Replace(FindSource, ReplaceSource: IInstrSource): IInstrSource; override;
function Compare(ASource: IInstrSource): Boolean; override;
function AsPascal(Callback: TAsPascalCallback): string; override;
property Size: Integer read GetSize;
end;
{ TDuoSource }
TDuoSource = class(TInstrSource, IDuoSource)
private
FSource1: IInstrSource;
FSource2: IInstrSource;
FSourceType: TDuoSourceType;
function GetSource1: IInstrSource;
function GetSource2: IInstrSource;
function GetSourceType: TDuoSourceType;
public
constructor Create(ASource1, ASource2: IInstrSource; ASourceType: TDuoSourceType);
function Replace(FindSource, ReplaceSource: IInstrSource): IInstrSource; override;
function Compare(ASource: IInstrSource): Boolean; override;
procedure GetSources(Callback: TGetSourcesCallback); override;
function AsPascal(Callback: TAsPascalCallback): string; override;
function Optimize: IInstrSource; override;
property Source1: IInstrSource read GetSource1;
property Source2: IInstrSource read GetSource2;
property SourceType: TDuoSourceType read GetSourceType;
end;
(* { TMultiSource }
TSourceItems = array[0..MaxListSize] of IInstrSource;
PSourceItems = ^TSourceItems;
TMultiSource = class(TInstrSource, IMultiSource)
private
FCount: Integer;
FItems: PSourceItems;
FSourceType: TMultiSourceType;
function GetCount: Integer;
function GetSourceType: TMultiSourceType;
function GetItem(Index: Integer): IInstrSource;
public
constructor Create(const AItems: array of IInstrSource; ASourceType: TMultiSourceType);
destructor Destroy; override;
function Replace(FindSource, ReplaceSource: IInstrSource): IInstrSource; override;
function Compare(ASource: IInstrSource): Boolean; override;
property Count: Integer read GetCount;
property Items[Index: Integer]: IInstrSource read GetItem;
property SourceType: TMultiSourceType read GetSourceType;
end;
*)
{ TRegSource }
TRegSource = class(TInstrSource, IRegSource)
private
FReg: TRegister;
FRegType: TRegisterType;
function GetReg: TRegister;
function GetRegType: TRegisterType;
public
constructor Create(AReg: TRegister; ARegType: TRegisterType);
function Replace(FindSource, ReplaceSource: IInstrSource): IInstrSource; override;
function Compare(ASource: IInstrSource): Boolean; override;
function AsPascal(Callback: TAsPascalCallback): string; override;
property RegType: TRegisterType read GetRegType;
property Reg: TRegister read GetReg;
end;
{ TConstSource }
TConstSource = class(TInstrSource, IConstSource)
private
FValue: Cardinal;
function GetValue: Cardinal;
public
constructor Create(AValue: Cardinal);
function Replace(FindSource, ReplaceSource: IInstrSource): IInstrSource; override;
function Compare(ASource: IInstrSource): Boolean; override;
function AsPascal(Callback: TAsPascalCallback): string; override;
property Value: Cardinal read GetValue;
end;
{ TAddressSource }
TAddressSource = class(TInstrSource, IAddressSource)
private
FAddress: TAddress;
function GetAddress: TAddress;
public
constructor Create(AAddress: TAddress);
function Replace(FindSource, ReplaceSource: IInstrSource): IInstrSource; override;
function Compare(ASource: IInstrSource): Boolean; override;
function AsPascal(Callback: TAsPascalCallback): string; override;
property Address: TAddress read GetAddress;
end;
{ TInstrSource }
procedure TInstrSource.GetSources(Callback: TGetSourcesCallback);
begin
Callback(Self);
end;
function TInstrSource.Optimize: IInstrSource;
begin
Result := Self;
end;
{ TMonoSource }
constructor TMonoSource.Create(ASource: IInstrSource; ASourceType: TMonoSourceType);
begin
inherited Create;
FSource := ASource;
FSourceType := ASourceType;
end;
(*
function TMonoSource.Replace(FindSource, ReplaceSource: IInstrSource): IInstrSource;
begin
if Compare(FindSource) then
Result := ReplaceSource
else
Result := TMonoSource.Create(Source.Replace(FindSource, ReplaceSource), SourceType);
end;
*)
function TMonoSource.Compare(ASource: IInstrSource): Boolean;
var
AMonoSource: IMonoSource;
begin
Result := Succeeded(ASource.QueryInterface(IMonoSource, AMonoSource)) and
(AMonoSource.SourceType = SourceType) and Source.Compare(AMonoSource.Source);
end;
function TMonoSource.GetSource: IInstrSource;
begin
Result := FSource;
end;
function TMonoSource.GetSourceType: TMonoSourceType;
begin
Result := FSourceType;
end;
procedure TMonoSource.GetSources(Callback: TGetSourcesCallback);
begin
inherited GetSources(Callback);
Source.GetSources(Callback);
end;
{ TRefSource }
constructor TRefSource.Create(ASource: IInstrSource; ASize: Integer);
begin
inherited Create(ASource, mostRef);
FSize := ASize;
end;
function TRefSource.GetSize: Integer;
begin
Result := FSize;
end;
function TRefSource.Replace(FindSource, ReplaceSource: IInstrSource): IInstrSource;
begin
if Compare(FindSource) then
Result := ReplaceSource
else
Result := TRefSource.Create(Source.Replace(FindSource, ReplaceSource), Size);
end;
function TRefSource.Compare(ASource: IInstrSource): Boolean;
var
ARefSource: IRefSource;
begin
Result := Succeeded(ASource.QueryInterface(IRefSource, ARefSource)) and
(ARefSource.Size = Size) and Source.Compare(ARefSource.Source);
end;
function TRefSource.AsPascal(Callback: TAsPascalCallback): string;
begin
case Size of
1: Result := Format('ShortInt(Pointer(%s)^)', [Source.AsPascal(Callback)]);
2: Result := Format('SmallInt(Pointer(%s)^)', [Source.AsPascal(Callback)]);
4: Result := Format('Integer(Pointer(%s)^)', [Source.AsPascal(Callback)]);
end;
Callback(Self, Result);
end;
{ TDuoSource }
constructor TDuoSource.Create(ASource1, ASource2: IInstrSource; ASourceType: TDuoSourceType);
begin
inherited Create;
FSource1 := ASource1;
FSource2 := ASource2;
FSourceType := ASourceType;
end;
function TDuoSource.Replace(FindSource, ReplaceSource: IInstrSource): IInstrSource;
begin
if Compare(FindSource) then
Result := ReplaceSource
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -