6110 lines
135 KiB
ObjectPascal
6110 lines
135 KiB
ObjectPascal
////////////////////////////////////////////////////////////////////////////
|
|
// PaxCompiler
|
|
// Site: http://www.paxcompiler.com
|
|
// Author: Alexander Baranovsky (paxscript@gmail.com)
|
|
// ========================================================================
|
|
// Copyright (c) Alexander Baranovsky, 2006-2014. All rights reserved.
|
|
// Code Version: 4.2
|
|
// ========================================================================
|
|
// Unit: PAXCOMP_SYMBOL_PROGRAM.pas
|
|
// ========================================================================
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
{$I PaxCompiler.def}
|
|
{$R-}
|
|
|
|
unit PAXCOMP_SYMBOL_PROGRAM;
|
|
interface
|
|
|
|
uses {$I uses.def}
|
|
SysUtils,
|
|
Classes,
|
|
PAXCOMP_CONSTANTS,
|
|
PAXCOMP_TYPES,
|
|
PAXCOMP_SYS,
|
|
PAXCOMP_PROG,
|
|
PAXCOMP_SYMBOL_REC,
|
|
PAXCOMP_BASESYMBOL_TABLE,
|
|
PAXCOMP_SYMBOL_TABLE,
|
|
PAXCOMP_BYTECODE,
|
|
PAXCOMP_MODULE,
|
|
PAXCOMP_CLASSLST,
|
|
PAXCOMP_CLASSFACT,
|
|
PAXCOMP_TRYLST,
|
|
PAXCOMP_RTI,
|
|
PAXCOMP_DISASM,
|
|
PAXCOMP_STDLIB;
|
|
type
|
|
TSymbolProgRec = class
|
|
private
|
|
fPAX64: Boolean;
|
|
fLabelId: Integer;
|
|
procedure SetLabelId(value: Integer);
|
|
function GetPAX64: Boolean;
|
|
public
|
|
Op: Integer;
|
|
Arg1, Arg2: TArg;
|
|
Size: Integer;
|
|
code: array[0..11] of byte;
|
|
Comment: String;
|
|
SaveSubId: Integer;
|
|
ShiftValue: Integer;
|
|
Z: Boolean;
|
|
|
|
ProgOffset: Integer;
|
|
MustBeFixed: Boolean;
|
|
OpOffset: Integer;
|
|
SubId: Integer;
|
|
|
|
MapSub: Integer;
|
|
|
|
constructor Create(aPAX64: Boolean);
|
|
function ToStr: String;
|
|
procedure Decompile;
|
|
property LabelId: Integer read fLabelId write SetLabelId;
|
|
property PAX64: Boolean read GetPAX64;
|
|
end;
|
|
|
|
TSymbolProg = class(TTypedList)
|
|
private
|
|
function GetRecord(I: Integer): TSymbolProgRec;
|
|
function GetCard: Integer;
|
|
function GetProgSize: Integer;
|
|
function GetMovCode(Reg1, Reg2: Integer): Integer;
|
|
function Get64Code(Reg1, Reg2: Integer): Integer;
|
|
function GetMovESIPtrCode(Reg: Integer): Integer;
|
|
function GetMovEBPPtrCode(Reg: Integer): Integer;
|
|
function GetPAX64: Boolean;
|
|
function GetSizeOfPointer: Integer;
|
|
public
|
|
kernel: Pointer;
|
|
constructor Create(i_kernel: Pointer);
|
|
function AddRecord: TSymbolProgRec;
|
|
function Top: TSymbolProgRec;
|
|
procedure Optimization;
|
|
procedure Delete(I: Integer);
|
|
function GetOffset(S: TSymbolRec): Integer;
|
|
|
|
function AsmComment(const S: String): TSymbolProgRec;
|
|
|
|
// requires EmitGetAddressRegister
|
|
// MOV <SIZE> PTR [REG], Imm
|
|
procedure AsmMovREGPtr_Imm(Reg: Integer; S: TSymbolRec; value: IntPax); overload;
|
|
// requires EmitGetAddressRegister
|
|
// ADD <SIZE> PTR [REG], Imm
|
|
procedure AsmAddREGPtr_Imm(Reg: Integer; S: TSymbolRec; value: IntPax);
|
|
// requires EmitGetAddressRegister
|
|
// CMP <SIZE> PTR [REG], Imm
|
|
procedure AsmCmpREGPtr_Imm(Reg: Integer; S: TSymbolRec; value: IntPax);
|
|
// requires EmitGetAddressRegister
|
|
// NEG DWORD PTR [REG + Shift]
|
|
procedure AsmNEG_REGPtr(Reg: Integer; S: TSymbolRec);
|
|
// requires EmitGetAddressRegister
|
|
// Fld QWORD PTR [REG + Shift]
|
|
procedure AsmFldDouble_REGPtr(Reg: Integer; S: TSymbolRec); overload;
|
|
// requires EmitGetAddressRegister
|
|
// FStp QWORD PTR [REG + Shift]
|
|
procedure AsmFstpDouble_REGPtr(Reg: Integer; S: TSymbolRec); overload;
|
|
// requires EmitGetAddressRegister
|
|
// Fld DWORD PTR [REG + Shift]
|
|
procedure AsmFldSingle_REGPtr(Reg: Integer; S: TSymbolRec); overload;
|
|
// requires EmitGetAddressRegister
|
|
// Fld TBYTE PTR [REG + Shift]
|
|
procedure AsmFldExtended_REGPtr(Reg: Integer; S: TSymbolRec); overload;
|
|
// requires EmitGetAddressRegister
|
|
// FStp DWORD PTR [REG + Shift]
|
|
procedure AsmFstpSingle_REGPtr(Reg: Integer; S: TSymbolRec); overload;
|
|
// requires EmitGetAddressRegister
|
|
// FStp TBYTE PTR [REG + Shift]
|
|
procedure AsmFstpExtended_REGPtr(Reg: Integer; S: TSymbolRec); overload;
|
|
|
|
function AsmAddREG_Imm(Reg: Integer; value: Integer): TSymbolProgRec;
|
|
procedure AsmSubREG_Imm(Reg: Integer; value: IntPax);
|
|
procedure AsmAddREG_REG(Reg1, Reg2: Integer);
|
|
procedure AsmAdcREG_REG(Reg1, Reg2: Integer);
|
|
procedure AsmSbbREG_REG(Reg1, Reg2: Integer);
|
|
|
|
procedure AsmMulREG(Reg: Integer);
|
|
procedure AsmIMulREG(Reg: Integer);
|
|
procedure AsmDivREG(Reg: Integer);
|
|
procedure AsmIDivREG(Reg: Integer);
|
|
procedure AsmShlREG(Reg: Integer);
|
|
procedure AsmShrREG(Reg: Integer);
|
|
|
|
procedure AsmNotREG(Reg: Integer);
|
|
procedure AsmNegREG(Reg: Integer);
|
|
|
|
procedure AsmSubREG_REG(Reg1, Reg2: Integer);
|
|
procedure AsmXorREG_REG(Reg1, Reg2: Integer);
|
|
procedure AsmAndREG_REG(Reg1, Reg2: Integer);
|
|
procedure AsmOrREG_REG(Reg1, Reg2: Integer);
|
|
|
|
function AsmMovREG_REG(Reg1, Reg2: Integer): TSymbolProgRec;
|
|
{$IFDEF VARIANTS}
|
|
function AsmMovREG_Imm(Reg: Integer; value: Int64): TSymbolProgRec;
|
|
{$ELSE}
|
|
function AsmMovREG_Imm(Reg: Integer; value: Integer): TSymbolProgRec;
|
|
{$ENDIF}
|
|
procedure AsmMovREGPtr_Imm(Reg: Integer; value: IntPax); overload;
|
|
procedure AsmMovREGPtr_Imm(Reg, shift: Integer; value: IntPax); overload;
|
|
|
|
procedure AsmMovFS_REGPtr_REG32(Reg1, Reg2: Integer);
|
|
|
|
procedure AsmMovRSPPtr_REG64(Reg: Integer; Shift: Integer);
|
|
procedure AsmMovREG64_RSPPtr(Reg: Integer; Shift: Integer);
|
|
|
|
procedure AsmMovREGPtr_REG(Reg1, Reg2: Integer);
|
|
procedure AsmMovREGPtr_REG64(Reg1, Reg2: Integer);
|
|
procedure AsmMovREGPtr_REG32(Reg1, Reg2: Integer);
|
|
procedure AsmMovREGPtr_REG16(Reg1, Reg2: Integer);
|
|
procedure AsmMovREGPtr_REG8(Reg1, Reg2: Integer);
|
|
|
|
procedure AsmMovREG_REGPtr(Reg1, Reg2: Integer);
|
|
procedure AsmMovREG64_REGPtr(Reg1, Reg2: Integer);
|
|
procedure AsmMovREG32_REGPtr(Reg1, Reg2: Integer);
|
|
procedure AsmMovREG16_REGPtr(Reg1, Reg2: Integer);
|
|
procedure AsmMovREG8_REGPtr(Reg1, Reg2: Integer);
|
|
//< ?
|
|
procedure AsmFldDouble_REGPtr(Reg: Integer); overload;
|
|
procedure AsmFldSingle_REGPtr(Reg: Integer); overload;
|
|
procedure AsmFldExtended_REGPtr(Reg: Integer); overload;
|
|
//? >
|
|
procedure AsmFild_REG16Ptr(Reg: Integer);
|
|
procedure AsmFild_REG32Ptr(Reg: Integer);
|
|
procedure AsmFild_REG64Ptr(Reg: Integer);
|
|
|
|
procedure AsmFistp_REG64Ptr(Reg: Integer);
|
|
|
|
procedure AsmFAdd_REGPtr(Reg: Integer);
|
|
|
|
procedure AsmWait;
|
|
|
|
procedure AsmFAdd;
|
|
procedure AsmFSub;
|
|
procedure AsmFMul;
|
|
procedure AsmFDiv;
|
|
procedure AsmFChs;
|
|
procedure AsmFAbs;
|
|
procedure AsmFSub_REGPtr(Reg: Integer);
|
|
procedure AsmFMul_REGPtr(Reg: Integer);
|
|
procedure AsmFDiv_REGPtr(Reg: Integer);
|
|
|
|
procedure AsmFMul_ESIPtr32(Shift: Integer);
|
|
procedure AsmFDiv_ESIPtr32(Shift: Integer);
|
|
|
|
procedure AsmFstpDouble_REGPtr(Reg: Integer); overload;
|
|
procedure AsmFstpSingle_REGPtr(Reg: Integer); overload;
|
|
procedure AsmFstpExtended_REGPtr(Reg: Integer); overload;
|
|
|
|
procedure AsmFComp_REGPtr(Reg: Integer);
|
|
procedure AsmFCompP;
|
|
procedure AsmFstsw_AX;
|
|
procedure AsmSahv;
|
|
|
|
procedure AsmCDQ;
|
|
|
|
procedure AsmSet_REGPtr(ASM_OP, Reg: Integer; S: TSymbolRec);
|
|
|
|
procedure AsmSetL_REGPtr(Reg: Integer); // <
|
|
procedure AsmSetLE_REGPtr(Reg: Integer); // <=
|
|
procedure AsmSetNLE_REGPtr(Reg: Integer); // >
|
|
procedure AsmSetNL_REGPtr(Reg: Integer); // >=
|
|
|
|
procedure AsmSetB_REGPtr(Reg: Integer);
|
|
procedure AsmSetBE_REGPtr(Reg: Integer);
|
|
procedure AsmSetNBE_REGPtr(Reg: Integer);
|
|
procedure AsmSetNB_REGPtr(Reg: Integer);
|
|
procedure AsmSetZ_REGPtr(Reg: Integer);
|
|
procedure AsmSetNZ_REGPtr(Reg: Integer);
|
|
|
|
procedure AsmCmpByteREGPtr_Imm(Reg: Integer; value: Byte);
|
|
procedure AsmCmpREG_REG(Reg1, Reg2: Integer);
|
|
procedure AsmCmpREG_Imm(Reg: Integer; Value: Integer);
|
|
|
|
procedure AsmTestREG8_REG8(Reg1, Reg2: Integer);
|
|
|
|
procedure AsmCmpReg32Ptr_Imm(Reg: Integer; shift: Integer; value: Integer);
|
|
|
|
procedure AsmIncReg32Ptr(Reg: Integer; shift: Integer);
|
|
procedure AsmDecReg32Ptr(Reg: Integer; shift: Integer);
|
|
|
|
procedure AsmIncBytePtr(Reg: Integer; shift: Integer);
|
|
|
|
function AsmJmp_REG(Reg: Integer): TSymbolProgRec;
|
|
procedure AsmCall_REG(Reg: Integer);
|
|
procedure AsmPush_Imm(value: Integer);
|
|
function AsmPush_REG(Reg: Integer): TSymbolProgRec;
|
|
procedure AsmPush_Reg16(Reg: Integer);
|
|
|
|
procedure AsmPush_FS_REGPtr(Reg: Integer);
|
|
|
|
function AsmPop_REG(Reg: Integer): TSymbolProgRec;
|
|
procedure AsmPush_REGPtr(Reg: Integer);
|
|
|
|
function AsmGetREG_ESIPtr(Reg: Integer; shift: Integer): TSymbolProgRec;
|
|
function AsmGetREG64_RSIPtr(Reg: Integer; shift: Integer): TSymbolProgRec;
|
|
function AsmGetREG32_ESIPtr(Reg: Integer; shift: Integer): TSymbolProgRec;
|
|
procedure AsmGetREG16_ESIPtr(Reg: Integer; shift: Integer);
|
|
procedure AsmGetREG8_ESIPtr(Reg: Integer; shift: Integer);
|
|
|
|
procedure AsmPutREG_ESIPtr(Reg: Integer; shift: Integer);
|
|
procedure AsmPutREG64_RSIPtr(Reg: Integer; shift: Integer);
|
|
procedure AsmPutREG32_ESIPtr(Reg: Integer; shift: Integer);
|
|
procedure AsmPutREG16_ESIPtr(Reg: Integer; shift: Integer);
|
|
procedure AsmPutREG8_ESIPtr(Reg: Integer; shift: Integer);
|
|
|
|
procedure AsmGetREG_EBPPtr(Reg: Integer; shift: Integer);
|
|
procedure AsmGetREG64_RBPPtr(Reg: Integer; shift: Integer);
|
|
procedure AsmGetREG32_EBPPtr(Reg: Integer; shift: Integer);
|
|
procedure AsmGetREG16_EBPPtr(Reg: Integer; shift: Integer);
|
|
procedure AsmGetREG8_EBPPtr(Reg: Integer; shift: Integer);
|
|
|
|
procedure AsmPutREG_EBPPtr(Reg: Integer; shift: Integer);
|
|
procedure AsmPutREG64_RBPPtr(Reg: Integer; shift: Integer);
|
|
procedure AsmPutREG32_EBPPtr(Reg: Integer; shift: Integer);
|
|
procedure AsmPutREG16_EBPPtr(Reg: Integer; shift: Integer);
|
|
procedure AsmPutREG8_EBPPtr(Reg: Integer; shift: Integer);
|
|
|
|
procedure AsmNop;
|
|
procedure AsmClc;
|
|
procedure AsmPushfd;
|
|
procedure AsmPopfd;
|
|
procedure AsmXCHG(Reg1, Reg2: Integer);
|
|
procedure AsmRet(value: Word = 0);
|
|
procedure AsmJMP_Imm(value: Integer);
|
|
|
|
procedure AsmJNO_Imm(value: Byte);
|
|
procedure AsmJNC_Imm(value: Byte);
|
|
procedure AsmJBE_Imm(value: Byte);
|
|
procedure AsmJNLE_Imm(value: Byte);
|
|
|
|
procedure AsmJZ_Imm(value: SmallInt);
|
|
procedure AsmJNZ_Imm(value: SmallInt);
|
|
|
|
procedure AsmLeaReg32_RegPtr(Reg1, Reg2: Integer; shift: Integer);
|
|
|
|
procedure AsmRep_MOVSB;
|
|
procedure AsmRep_MOVSD;
|
|
|
|
procedure AsmCvtsd2ssXMM_RegPtr(XMMReg, Reg: Integer);
|
|
procedure AsmCvtss2sdXMM_RegPtr(XMMReg, Reg: Integer);
|
|
|
|
procedure AsmMovsdXMM_RegPtr(XMMReg, Reg: Integer);
|
|
procedure AsmMovsdRegPtr_XMM(XMMReg, Reg: Integer);
|
|
procedure AsmMovssXMM_RegPtr(XMMReg, Reg: Integer);
|
|
procedure AsmMovssRegPtr_XMM(XMMReg, Reg: Integer);
|
|
|
|
procedure AsmLoadESI_ESPPtr(shift: Integer); // not used
|
|
procedure AsmLoadEDI_ESPPtr(shift: Integer); // not used
|
|
|
|
procedure CreateProgram(result: TProgram; IsEval: Boolean = false);
|
|
procedure CreateProgramSimple(result: TProgram);
|
|
|
|
procedure AsmLeaRSP_RBPPtr(Shift: Integer);
|
|
|
|
function GetShiftOfRecord(R: TSymbolProgRec): Integer;
|
|
function GetShiftOfLabel(LabelId: Integer): Integer;
|
|
procedure CreateZList(P: TProgram);
|
|
function EmitZ: Integer;
|
|
function EmitGetCallerEIP: Integer;
|
|
|
|
procedure RaiseError(const Message: string; params: array of Const);
|
|
procedure CreateError(const Message: string; params: array of Const);
|
|
property Card: Integer read GetCard;
|
|
property ProgSize: Integer read GetProgSize;
|
|
property Records[I: Integer]: TSymbolProgRec read GetRecord; default;
|
|
property PAX64: Boolean read GetPAX64;
|
|
property SizeOfPointer: Integer read GetSizeOfPointer;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
PAXCOMP_MAP,
|
|
PAXCOMP_KERNEL;
|
|
|
|
constructor TSymbolProgRec.Create(aPAX64: Boolean);
|
|
begin
|
|
FillChar(code, SizeOf(code), 0);
|
|
Op := 0;
|
|
ClearArg(Arg1);
|
|
ClearArg(Arg2);
|
|
Size := 0;
|
|
LabelId := 0;
|
|
Comment := '';
|
|
SaveSubId := 0;
|
|
ShiftValue := 0;
|
|
Z := false;
|
|
fPAX64 := aPAX64;
|
|
end;
|
|
|
|
procedure TSymbolProgRec.SetLabelId(value: Integer);
|
|
begin
|
|
fLabelId := Value;
|
|
end;
|
|
|
|
function TSymbolProgRec.GetPAX64: Boolean;
|
|
begin
|
|
result := fPAX64;
|
|
end;
|
|
|
|
procedure SwapRegs(var Reg1, Reg2: Integer);
|
|
var
|
|
temp: Integer;
|
|
begin
|
|
temp := Reg1;
|
|
Reg1 := Reg2;
|
|
Reg2 := temp;
|
|
end;
|
|
|
|
function TSymbolProgRec.ToStr: String;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
result := '';
|
|
for I := 0 to Size - 1 do
|
|
result := result + ByteToHex(code[I]);
|
|
|
|
if Size = -1 then
|
|
result := AlignLeft('', 25) + Comment
|
|
else
|
|
begin
|
|
if Arg2.valid then
|
|
result := AlignLeft(result, 25) + AsmOperators[Op] + ' ' + ArgToString(Arg1, PAX64) +
|
|
', ' + ArgToString(Arg2, PAX64)
|
|
else
|
|
result := AlignLeft(result, 25) + AsmOperators[Op] + ' ' + ArgToString(Arg1, PAX64);
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProgRec.Decompile;
|
|
var
|
|
S: Integer;
|
|
begin
|
|
Decomp(@code, S, Op, Arg1, Arg2, PAX64);
|
|
if S <> Size then
|
|
raise Exception.Create(errInternalError);
|
|
end;
|
|
|
|
constructor TSymbolProg.Create(i_kernel: Pointer);
|
|
begin
|
|
inherited Create;
|
|
Self.kernel := i_kernel;
|
|
end;
|
|
|
|
function TSymbolProg.GetCard: Integer;
|
|
begin
|
|
result := L.Count;
|
|
end;
|
|
|
|
function TSymbolProg.GetMovESIPtrCode(Reg: Integer): Integer;
|
|
begin
|
|
result := 0;
|
|
case Reg of
|
|
_EAX: result := $86;
|
|
_ECX: result := $8E;
|
|
_EDX: result := $96;
|
|
_EBX: result := $9E;
|
|
_ESP: result := $A6;
|
|
_EBP: result := $AE;
|
|
_ESI: result := $B6;
|
|
_EDI: result := $BE;
|
|
_R8: result := $86;
|
|
_R9: result := $8E;
|
|
_R10: result := $96;
|
|
_R11: result := $9E;
|
|
_R12: result := $A6;
|
|
_R13: result := $AE;
|
|
_R14: result := $B6;
|
|
_R15: result := $BE;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
end;
|
|
|
|
function TSymbolProg.GetMovEBPPtrCode(Reg: Integer): Integer;
|
|
begin
|
|
result := 0;
|
|
case Reg of
|
|
_EAX: result := $85;
|
|
_ECX: result := $8D;
|
|
_EDX: result := $95;
|
|
_EBX: result := $9D;
|
|
_ESP: result := $A5;
|
|
_EBP: result := $AD;
|
|
_ESI: result := $B5;
|
|
_EDI: result := $BD;
|
|
_R8: result := $85;
|
|
_R9: result := $8D;
|
|
_R10: result := $95;
|
|
_R11: result := $9D;
|
|
_R12: result := $A5;
|
|
_R13: result := $AD;
|
|
_R14: result := $B5;
|
|
_R15: result := $BD;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
end;
|
|
|
|
function TSymbolProg.GetMovCode(Reg1, Reg2: Integer): Integer;
|
|
begin
|
|
result := 0;
|
|
case Reg1 of
|
|
_EAX, _R8:
|
|
case Reg2 of
|
|
_EAX, _R8: result := $C0;
|
|
_ECX, _R9: result := $C8;
|
|
_EDX, _R10: result := $D0;
|
|
_EBX, _R11: result := $D8;
|
|
_ESP, _R12: result := $E0;
|
|
_EBP, _R13: result := $E8;
|
|
_ESI, _R14: result := $F0;
|
|
_EDI, _R15: result := $F8;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_ECX, _R9:
|
|
case Reg2 of
|
|
_EAX, _R8: result := $C1;
|
|
_ECX, _R9: result := $C9;
|
|
_EDX, _R10: result := $D1;
|
|
_EBX, _R11: result := $D9;
|
|
_ESP, _R12: result := $E1;
|
|
_EBP, _R13: result := $E9;
|
|
_ESI, _R14: result := $F1;
|
|
_EDI, _R15: result := $F9;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EDX, _R10:
|
|
case Reg2 of
|
|
_EAX, _R8: result := $C2;
|
|
_ECX, _R9: result := $CA;
|
|
_EDX, _R10: result := $D2;
|
|
_EBX, _R11: result := $DA;
|
|
_ESP, _R12: result := $E2;
|
|
_EBP, _R13: result := $EA;
|
|
_ESI, _R14: result := $F2;
|
|
_EDI, _R15: result := $FA;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EBX, _R11:
|
|
case Reg2 of
|
|
_EAX, _R8: result := $C3;
|
|
_ECX, _R9: result := $CB;
|
|
_EDX, _R10: result := $D3;
|
|
_EBX, _R11: result := $DB;
|
|
_ESP, _R12: result := $E3;
|
|
_EBP, _R13: result := $EB;
|
|
_ESI, _R14: result := $F3;
|
|
_EDI, _R15: result := $FB;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_ESP:
|
|
case Reg2 of
|
|
_EAX, _R8: result := $C4;
|
|
_ECX, _R9: result := $CC;
|
|
_EDX, _R10: result := $D4;
|
|
_EBX, _R11: result := $DC;
|
|
_ESP, _R12: result := $E4;
|
|
_EBP, _R13: result := $EC;
|
|
_ESI, _R14: result := $F4;
|
|
_EDI, _R15: result := $FC;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EBP:
|
|
case Reg2 of
|
|
_EAX, _R8: result := $C5;
|
|
_ECX, _R9: result := $CD;
|
|
_EDX, _R10: result := $D5;
|
|
_EBX, _R11: result := $DD;
|
|
_ESP, _R12: result := $E5;
|
|
_EBP, _R13: result := $ED;
|
|
_ESI, _R14: result := $F5;
|
|
_EDI, _R15: result := $FD;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_ESI, _R13:
|
|
case Reg2 of
|
|
_EAX, _R8: result := $C6;
|
|
_ECX, _R9: result := $CE;
|
|
_EDX, _R10: result := $D6;
|
|
_EBX, _R11: result := $DE;
|
|
_ESP, _R12: result := $E6;
|
|
_EBP, _R13: result := $EE;
|
|
_ESI, _R14: result := $F6;
|
|
_EDI, _R15: result := $FE;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EDI, _R14:
|
|
case Reg2 of
|
|
_EAX, _R8: result := $C7;
|
|
_ECX, _R9: result := $CF;
|
|
_EDX, _R10: result := $D7;
|
|
_EBX, _R11: result := $DF;
|
|
_ESP, _R12: result := $E7;
|
|
_EBP, _R13: result := $EF;
|
|
_ESI, _R14: result := $F7;
|
|
_EDI, _R15: result := $FF;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TSymbolProg.Get64Code(Reg1, Reg2: Integer): Integer;
|
|
begin
|
|
result := 0;
|
|
case Reg1 of
|
|
_EAX, _R8:
|
|
case Reg2 of
|
|
_EAX: result := $00;
|
|
_ECX: result := $01;
|
|
_EDX: result := $02;
|
|
_EBX: result := $03;
|
|
_ESP: result := $04;
|
|
_EBP: result := $05;
|
|
_ESI: result := $06;
|
|
_EDI: result := $07;
|
|
|
|
_R8: result := $00;
|
|
_R9: result := $01;
|
|
_R10: result := $02;
|
|
_R11: result := $03;
|
|
_R12: result := $04;
|
|
_R13: result := $05;
|
|
_R14: result := $06;
|
|
_R15: result := $07;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_ECX, _R9:
|
|
case Reg2 of
|
|
_EAX: result := $08;
|
|
_ECX: result := $09;
|
|
_EDX: result := $0A;
|
|
_EBX: result := $0B;
|
|
_ESP: result := $0C;
|
|
_EBP: result := $0D;
|
|
_ESI: result := $0E;
|
|
_EDI: result := $0F;
|
|
|
|
_R8: result := $08;
|
|
_R9: result := $09;
|
|
_R10: result := $0A;
|
|
_R11: result := $0B;
|
|
_R12: result := $0C;
|
|
_R13: result := $0D;
|
|
_R14: result := $0E;
|
|
_R15: result := $0F;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EDX, _R10:
|
|
case Reg2 of
|
|
_EAX: result := $10;
|
|
_ECX: result := $11;
|
|
_EDX: result := $12;
|
|
_EBX: result := $13;
|
|
_ESP: result := $14;
|
|
_EBP: result := $15;
|
|
_ESI: result := $16;
|
|
_EDI: result := $17;
|
|
|
|
_R8: result := $10;
|
|
_R9: result := $11;
|
|
_R10: result := $12;
|
|
_R11: result := $13;
|
|
_R12: result := $14;
|
|
_R13: result := $15;
|
|
_R14: result := $16;
|
|
_R15: result := $17;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EBX, _R11:
|
|
case Reg2 of
|
|
_EAX: result := $18;
|
|
_ECX: result := $19;
|
|
_EDX: result := $1A;
|
|
_EBX: result := $1B;
|
|
_ESP: result := $1C;
|
|
_EBP: result := $1D;
|
|
_ESI: result := $1E;
|
|
_EDI: result := $1F;
|
|
|
|
_R8: result := $18;
|
|
_R9: result := $19;
|
|
_R10: result := $1A;
|
|
_R11: result := $1B;
|
|
_R12: result := $1C;
|
|
_R13: result := $1D;
|
|
_R14: result := $1E;
|
|
_R15: result := $1F;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_ESP, _R12:
|
|
case Reg2 of
|
|
_EAX: result := $20;
|
|
_ECX: result := $21;
|
|
_EDX: result := $22;
|
|
_EBX: result := $23;
|
|
_ESP: result := $24;
|
|
_EBP: result := $25;
|
|
_ESI: result := $26;
|
|
_EDI: result := $27;
|
|
|
|
_R8: result := $20;
|
|
_R9: result := $21;
|
|
_R10: result := $22;
|
|
_R11: result := $23;
|
|
_R12: result := $24;
|
|
_R13: result := $25;
|
|
_R14: result := $26;
|
|
_R15: result := $27;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EBP, _R13:
|
|
case Reg2 of
|
|
_EAX: result := $28;
|
|
_ECX: result := $29;
|
|
_EDX: result := $2A;
|
|
_EBX: result := $2B;
|
|
_ESP: result := $2C;
|
|
_EBP: result := $2D;
|
|
_ESI: result := $2E;
|
|
_EDI: result := $2F;
|
|
|
|
_R8: result := $28;
|
|
_R9: result := $29;
|
|
_R10: result := $2A;
|
|
_R11: result := $2B;
|
|
_R12: result := $2C;
|
|
_R13: result := $2D;
|
|
_R14: result := $2E;
|
|
_R15: result := $2F;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_ESI, _R14:
|
|
case Reg2 of
|
|
_EAX: result := $30;
|
|
_ECX: result := $31;
|
|
_EDX: result := $32;
|
|
_EBX: result := $33;
|
|
_ESP: result := $34;
|
|
_EBP: result := $35;
|
|
_ESI: result := $36;
|
|
_EDI: result := $37;
|
|
|
|
_R8: result := $30;
|
|
_R9: result := $31;
|
|
_R10: result := $32;
|
|
_R11: result := $33;
|
|
_R12: result := $34;
|
|
_R13: result := $35;
|
|
_R14: result := $36;
|
|
_R15: result := $37;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EDI, _R15:
|
|
case Reg2 of
|
|
_EAX: result := $38;
|
|
_ECX: result := $39;
|
|
_EDX: result := $3A;
|
|
_EBX: result := $3B;
|
|
_ESP: result := $3C;
|
|
_EBP: result := $3D;
|
|
_ESI: result := $3E;
|
|
_EDI: result := $3F;
|
|
|
|
_R8: result := $38;
|
|
_R9: result := $39;
|
|
_R10: result := $3A;
|
|
_R11: result := $3B;
|
|
_R12: result := $3C;
|
|
_R13: result := $3D;
|
|
_R14: result := $3E;
|
|
_R15: result := $3F;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
end;
|
|
|
|
function TSymbolProg.GetProgSize: Integer;
|
|
var
|
|
I, SZ: Integer;
|
|
begin
|
|
result := 0;
|
|
for I:=1 to Card do
|
|
begin
|
|
SZ := Records[I].Size;
|
|
if SZ > 0 then
|
|
result := result + SZ;
|
|
end;
|
|
end;
|
|
|
|
function TSymbolProg.GetShiftOfLabel(LabelId: Integer): Integer;
|
|
var
|
|
I, SZ: Integer;
|
|
begin
|
|
result := 0;
|
|
for I:=1 to Card do
|
|
begin
|
|
if Records[I].LabelId = LabelId then
|
|
Exit;
|
|
|
|
SZ := Records[I].Size;
|
|
if SZ > 0 then
|
|
result := result + SZ;
|
|
end;
|
|
result := -1;
|
|
end;
|
|
|
|
function TSymbolProg.GetShiftOfRecord(R: TSymbolProgRec): Integer;
|
|
var
|
|
I, SZ: Integer;
|
|
begin
|
|
result := 0;
|
|
for I:=1 to Card do
|
|
begin
|
|
if Records[I] = R then
|
|
Exit;
|
|
|
|
SZ := Records[I].Size;
|
|
if SZ > 0 then
|
|
result := result + SZ;
|
|
end;
|
|
result := -1;
|
|
end;
|
|
|
|
function TSymbolProg.AddRecord: TSymbolProgRec;
|
|
begin
|
|
result := TSymbolProgRec.Create(PAX64);
|
|
L.Add(result);
|
|
end;
|
|
|
|
function TSymbolProg.Top: TSymbolProgRec;
|
|
begin
|
|
result := Records[Card];
|
|
end;
|
|
|
|
procedure TSymbolProg.Delete(I: Integer);
|
|
begin
|
|
Records[I].Free;
|
|
L.Delete(I - 1);
|
|
end;
|
|
|
|
function TSymbolProg.AsmComment(const S: String): TSymbolProgRec;
|
|
begin
|
|
result := AddRecord;
|
|
with result do
|
|
begin
|
|
Size := -1;
|
|
Comment := ';' + S;
|
|
end;
|
|
end;
|
|
|
|
{$IFDEF VARIANTS}
|
|
function TSymbolProg.AsmMovREG_Imm(Reg: Integer; value: Int64): TSymbolProgRec;
|
|
{$ELSE}
|
|
function TSymbolProg.AsmMovREG_Imm(Reg: Integer; value: Integer): TSymbolProgRec;
|
|
{$ENDIF}
|
|
begin
|
|
result := AddRecord;
|
|
if PAX64 then
|
|
begin
|
|
with result do
|
|
begin
|
|
Size := 10;
|
|
code[0] := $48;
|
|
|
|
if Reg in R64 then
|
|
Code[0] := $49;
|
|
|
|
case Reg of
|
|
_EAX: code[1] := $B8;
|
|
_ECX: code[1] := $B9;
|
|
_EDX: code[1] := $BA;
|
|
_EBX: code[1] := $BB;
|
|
_ESP: code[1] := $BC;
|
|
_EBP: code[1] := $BD;
|
|
_ESI: code[1] := $BE;
|
|
_EDI: code[1] := $BF;
|
|
|
|
_R8: code[1] := $B8;
|
|
_R9: code[1] := $B9;
|
|
_R10: code[1] := $BA;
|
|
_R11: code[1] := $BB;
|
|
_R12: code[1] := $BC;
|
|
_R13: code[1] := $BD;
|
|
_R14: code[1] := $BE;
|
|
_R15: code[1] := $BF;
|
|
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(value, code[2], 8);
|
|
Decompile;
|
|
end;
|
|
end
|
|
else //32bit
|
|
begin
|
|
with result do
|
|
begin
|
|
Size := 5;
|
|
case Reg of
|
|
_EAX: code[0] := $B8;
|
|
_ECX: code[0] := $B9;
|
|
_EDX: code[0] := $BA;
|
|
_EBX: code[0] := $BB;
|
|
_ESP: code[0] := $BC;
|
|
_EBP: code[0] := $BD;
|
|
_ESI: code[0] := $BE;
|
|
_EDI: code[0] := $BF;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(value, code[1], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmLeaRSP_RBPPtr(Shift: Integer);
|
|
begin
|
|
if PAX64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 7;
|
|
code[0] := $48;
|
|
code[1] := $8D;
|
|
code[2] := $A5;
|
|
Move(Shift, code[3], 4);
|
|
Decompile;
|
|
end
|
|
else //32bit
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmMovREGPtr_Imm(Reg: Integer; value: IntPax);
|
|
begin
|
|
if PAX64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 7;
|
|
code[0] := $48;
|
|
if Reg in R64 then
|
|
Code[0] := $49;
|
|
|
|
code[1] := $C7;
|
|
case Reg of
|
|
_EAX: code[2] := $00;
|
|
_ECX: code[2] := $01;
|
|
_EDX: code[2] := $02;
|
|
_EBX: code[2] := $03;
|
|
|
|
_R8: code[2] := $00;
|
|
_R9: code[2] := $01;
|
|
_R10: code[2] := $02;
|
|
_R11: code[2] := $03;
|
|
_R12: code[2] := $04;
|
|
_R13: code[2] := $05;
|
|
_R14: code[2] := $06;
|
|
_R15: code[2] := $07;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(value, code[3], 4);
|
|
Decompile;
|
|
end
|
|
else //32bit
|
|
with AddRecord do
|
|
begin
|
|
Size := 6;
|
|
code[0] := $C7;
|
|
case Reg of
|
|
_EAX: code[1] := $00;
|
|
_ECX: code[1] := $01;
|
|
_EDX: code[1] := $02;
|
|
_EBX: code[1] := $03;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(value, code[2], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmMovREGPtr_Imm(Reg, shift: Integer; value: IntPax);
|
|
begin
|
|
if PAX64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 11;
|
|
code[0] := $48;
|
|
if Reg in R64 then
|
|
Code[0] := $49;
|
|
|
|
code[1] := $C7;
|
|
case Reg of
|
|
_EAX: code[2] := $80;
|
|
_ECX: code[2] := $81;
|
|
_EDX: code[2] := $82;
|
|
_EBX: code[2] := $83;
|
|
_EBP: code[2] := $85;
|
|
_ESI: code[2] := $86;
|
|
|
|
_R8: code[2] := $80;
|
|
_R9: code[2] := $81;
|
|
_R10: code[2] := $82;
|
|
_R11: code[2] := $83;
|
|
_R12: code[2] := $84;
|
|
_R13: code[2] := $85;
|
|
_R14: code[2] := $86;
|
|
_R15: code[2] := $87;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[3], 4);
|
|
Move(value, code[7], 4);
|
|
Decompile;
|
|
end
|
|
else //32bit
|
|
with AddRecord do
|
|
begin
|
|
Size := 10;
|
|
code[0] := $C7;
|
|
case Reg of
|
|
_EAX: code[1] := $80;
|
|
_ECX: code[1] := $81;
|
|
_EDX: code[1] := $82;
|
|
_EBX: code[1] := $83;
|
|
_EBP: code[1] := $85;
|
|
_ESI: code[1] := $86;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[2], 4);
|
|
Move(value, code[6], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmMovREG_REGPtr(Reg1, Reg2: Integer);
|
|
begin
|
|
if PAX64 then
|
|
AsmMovREG64_REGPtr(Reg1, Reg2)
|
|
else
|
|
AsmMovREG32_REGPtr(Reg1, Reg2);
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmMovREG64_REGPtr(Reg1, Reg2: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
if Reg1 in R32 then
|
|
begin
|
|
if Reg2 in R64 then
|
|
begin
|
|
Size := 3;
|
|
code[0] := $49;
|
|
code[1] := $8B;
|
|
code[2] := Get64Code(Reg1, Reg2);
|
|
end
|
|
else
|
|
begin
|
|
Size := 3;
|
|
code[0] := $48;
|
|
code[1] := $8B;
|
|
code[2] := Get64Code(Reg1, Reg2);
|
|
end;
|
|
end
|
|
else if Reg1 in R64 then
|
|
begin
|
|
Size := 3;
|
|
if Reg2 in R64 then
|
|
Code[0] := $4D
|
|
else
|
|
Code[0] := $4C;
|
|
Code[1] := $8B;
|
|
Code[2] := Get64Code(Reg1, Reg2);
|
|
end
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmMovREG32_REGPtr(Reg1, Reg2: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
if Reg1 in R32 then
|
|
begin
|
|
if Reg2 in R64 then
|
|
begin
|
|
Size := 4;
|
|
code[0] := $67;
|
|
code[1] := $41;
|
|
code[2] := $8B;
|
|
code[3] := Get64Code(Reg1, Reg2);
|
|
end
|
|
else
|
|
begin
|
|
Size := 2;
|
|
code[0] := $8B;
|
|
code[1] := Get64Code(Reg1, Reg2);
|
|
end;
|
|
end
|
|
else if Reg1 in R64 then
|
|
begin
|
|
Size := 3;
|
|
if Reg2 in R64 then
|
|
Code[0] := $45
|
|
else
|
|
Code[0] := $44;
|
|
Code[1] := $8B;
|
|
Code[2] := Get64Code(Reg1, Reg2);
|
|
end
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmMovREG16_REGPtr(Reg1, Reg2: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
if Reg1 in R32 then
|
|
begin
|
|
if Reg2 in R64 then
|
|
begin
|
|
Size := 4;
|
|
code[0] := $66;
|
|
code[1] := $41;
|
|
code[2] := $8B;
|
|
code[3] := Get64Code(Reg1, Reg2);
|
|
end
|
|
else
|
|
begin
|
|
Size := 3;
|
|
code[0] := $66;
|
|
code[1] := $8B;
|
|
code[2] := Get64Code(Reg1, Reg2);
|
|
end;
|
|
end
|
|
else if Reg1 in R64 then
|
|
begin
|
|
Size := 4;
|
|
code[0] := $66;
|
|
if Reg2 in R64 then
|
|
code[1] := $45
|
|
else
|
|
code[1] := $44;
|
|
code[2] := $8B;
|
|
code[3] := Get64Code(Reg1, Reg2);
|
|
end
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmMovREG8_REGPtr(Reg1, Reg2: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
if Reg1 in R32 then
|
|
begin
|
|
if Reg2 in R64 then
|
|
begin
|
|
Size := 3;
|
|
code[0] := $41;
|
|
code[1] := $8A;
|
|
code[2] := Get64Code(Reg1, Reg2);
|
|
end
|
|
else
|
|
begin
|
|
Size := 2;
|
|
code[0] := $8A;
|
|
code[1] := Get64Code(Reg1, Reg2);
|
|
end;
|
|
end
|
|
else if Reg1 in R64 then
|
|
begin
|
|
Size := 3;
|
|
if Reg2 in R64 then
|
|
code[0] := $45
|
|
else
|
|
code[0] := $44;
|
|
code[1] := $8A;
|
|
Code[2] := Get64Code(Reg1, Reg2);
|
|
end
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
function TSymbolProg.AsmMovREG_REG(Reg1, Reg2: Integer): TSymbolProgRec;
|
|
begin
|
|
result := AddRecord;
|
|
if PAX64 then
|
|
with result do
|
|
begin
|
|
Size := 3;
|
|
if Reg1 in R32 then
|
|
begin
|
|
if Reg2 in R64 then
|
|
code[0] := $4C
|
|
else
|
|
code[0] := $48;
|
|
end
|
|
else if Reg1 in R64 then
|
|
begin
|
|
if Reg2 in R64 then
|
|
code[0] := $4D
|
|
else
|
|
code[0] := $49;
|
|
end
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
code[1] := $89;
|
|
code[2] := GetMovCode(Reg1, Reg2);
|
|
Decompile;
|
|
end
|
|
else //32bit
|
|
with result do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $89;
|
|
code[1] := GetMovCode(Reg1, Reg2);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmCmpREG_Imm(Reg: Integer; Value: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
case Reg of
|
|
_EAX:
|
|
begin
|
|
Size := 5;
|
|
code[0] := $3D;
|
|
Move(Value, code[1], 4);
|
|
end;
|
|
_ECX, _EDX, _EBX:
|
|
begin
|
|
Size := 6;
|
|
code[0] := $81;
|
|
case Reg of
|
|
_ECX: code[1] := $F9;
|
|
_EDX: code[1] := $FA;
|
|
_EBX: code[1] := $FB;
|
|
_ESP: code[1] := $FC;
|
|
_EBP: code[1] := $FD;
|
|
_ESI: code[1] := $FE;
|
|
_EDI: code[1] := $FF;
|
|
end;
|
|
Move(Value, code[2], 4);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmCmpREG_REG(Reg1, Reg2: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $39;
|
|
case Reg1 of
|
|
_EAX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C0;
|
|
_ECX: code[1] := $C8;
|
|
_EDX: code[1] := $D0;
|
|
_EBX: code[1] := $D8;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_ECX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C1;
|
|
_ECX: code[1] := $C9;
|
|
_EDX: code[1] := $D1;
|
|
_EBX: code[1] := $D9;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EDX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C2;
|
|
_ECX: code[1] := $CA;
|
|
_EDX: code[1] := $D2;
|
|
_EBX: code[1] := $DA;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EBX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C3;
|
|
_ECX: code[1] := $CB;
|
|
_EDX: code[1] := $D3;
|
|
_EBX: code[1] := $DB;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmTestREG8_REG8(Reg1, Reg2: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
if (Reg1 = _EDX) and (Reg2 = _EDX) then
|
|
begin
|
|
Code[0] := $84;
|
|
Code[1] := $d2;
|
|
end
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmMovFS_REGPtr_REG32(Reg1, Reg2: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $64;
|
|
code[1] := $89;
|
|
case Reg1 of
|
|
_EAX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $00;
|
|
_ECX: code[2] := $08;
|
|
_EDX: code[2] := $10;
|
|
_EBX: code[2] := $18;
|
|
_ESP: code[2] := $20;
|
|
_EBP: code[2] := $28;
|
|
_ESI: code[2] := $30;
|
|
_EDI: code[2] := $38;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_ECX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $01;
|
|
_ECX: code[2] := $09;
|
|
_EDX: code[2] := $11;
|
|
_EBX: code[2] := $19;
|
|
_ESP: code[2] := $21;
|
|
_EBP: code[2] := $29;
|
|
_ESI: code[2] := $31;
|
|
_EDI: code[2] := $39;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EDX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $02;
|
|
_ECX: code[2] := $0A;
|
|
_EDX: code[2] := $12;
|
|
_EBX: code[2] := $1A;
|
|
_ESP: code[2] := $22;
|
|
_EBP: code[2] := $2A;
|
|
_ESI: code[2] := $32;
|
|
_EDI: code[2] := $3A;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EBX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $03;
|
|
_ECX: code[2] := $0B;
|
|
_EDX: code[2] := $13;
|
|
_EBX: code[2] := $1B;
|
|
_ESP: code[2] := $23;
|
|
_EBP: code[2] := $2B;
|
|
_ESI: code[2] := $33;
|
|
_EDI: code[2] := $3B;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmMovRSPPtr_REG64(Reg: Integer; Shift: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 8;
|
|
if Reg in R64 then
|
|
code[0] := $4C
|
|
else
|
|
code[0] := $48;
|
|
code[1] := $89;
|
|
case Reg of
|
|
_EAX: code[2] := $84;
|
|
_ECX: code[2] := $8C;
|
|
_EDX: code[2] := $94;
|
|
_EBX: code[2] := $9C;
|
|
_ESP: code[2] := $A4;
|
|
_EBP: code[2] := $AC;
|
|
_ESI: code[2] := $B4;
|
|
_EDI: code[2] := $BC;
|
|
|
|
_R8: code[2] := $84;
|
|
_R9: code[2] := $8C;
|
|
_R10: code[2] := $94;
|
|
_R11: code[2] := $9C;
|
|
_R12: code[2] := $A4;
|
|
_R13: code[2] := $AC;
|
|
_R14: code[2] := $B4;
|
|
_R15: code[2] := $BC;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
code[3] := $24;
|
|
Move(Shift, code[4], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmMovREG64_RSPPtr(Reg: Integer; Shift: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 8;
|
|
if Reg in R64 then
|
|
code[0] := $4C
|
|
else
|
|
code[0] := $48;
|
|
code[1] := $8B;
|
|
case Reg of
|
|
_EAX: code[2] := $84;
|
|
_ECX: code[2] := $8C;
|
|
_EDX: code[2] := $94;
|
|
_EBX: code[2] := $9C;
|
|
_ESP: code[2] := $A4;
|
|
_EBP: code[2] := $AC;
|
|
_ESI: code[2] := $B4;
|
|
_EDI: code[2] := $BC;
|
|
|
|
_R8: code[2] := $84;
|
|
_R9: code[2] := $8C;
|
|
_R10: code[2] := $94;
|
|
_R11: code[2] := $9C;
|
|
_R12: code[2] := $A4;
|
|
_R13: code[2] := $AC;
|
|
_R14: code[2] := $B4;
|
|
_R15: code[2] := $BC;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
code[3] := $24;
|
|
Move(Shift, code[4], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmMovREGPtr_REG(Reg1, Reg2: Integer);
|
|
begin
|
|
if PAX64 then
|
|
AsmMovREGPtr_REG64(Reg1, Reg2)
|
|
else
|
|
AsmMovREGPtr_REG32(Reg1, Reg2);
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmMovREGPtr_REG64(Reg1, Reg2: Integer);
|
|
begin
|
|
SwapRegs(Reg1, Reg2);
|
|
with AddRecord do
|
|
begin
|
|
if Reg1 in R32 then
|
|
begin
|
|
if Reg2 in R64 then
|
|
begin
|
|
Size := 3;
|
|
code[0] := $49;
|
|
code[1] := $89;
|
|
code[2] := Get64Code(Reg1, Reg2);
|
|
end
|
|
else
|
|
begin
|
|
Size := 3;
|
|
code[0] := $48;
|
|
code[1] := $89;
|
|
code[2] := Get64Code(Reg1, Reg2);
|
|
end;
|
|
end
|
|
else if Reg1 in R64 then
|
|
begin
|
|
Size := 3;
|
|
if Reg2 in R64 then
|
|
Code[0] := $4D
|
|
else
|
|
Code[0] := $4C;
|
|
Code[1] := $89;
|
|
Code[2] := Get64Code(Reg1, Reg2);
|
|
end
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmMovREGPtr_REG32(Reg1, Reg2: Integer);
|
|
begin
|
|
SwapRegs(Reg1, Reg2);
|
|
with AddRecord do
|
|
begin
|
|
if Reg1 in R32 then
|
|
begin
|
|
if Reg2 in R64 then
|
|
begin
|
|
Size := 4;
|
|
code[0] := $67;
|
|
code[1] := $41;
|
|
code[2] := $89;
|
|
code[3] := Get64Code(Reg1, Reg2);
|
|
end
|
|
else
|
|
begin
|
|
Size := 2;
|
|
code[0] := $89;
|
|
code[1] := Get64Code(Reg1, Reg2);
|
|
end;
|
|
end
|
|
else if Reg1 in R64 then
|
|
begin
|
|
Size := 3;
|
|
if Reg2 in R64 then
|
|
Code[0] := $45
|
|
else
|
|
Code[0] := $44;
|
|
Code[1] := $89;
|
|
Code[2] := Get64Code(Reg1, Reg2);
|
|
end
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmMovREGPtr_REG16(Reg1, Reg2: Integer);
|
|
begin
|
|
SwapRegs(Reg1, Reg2);
|
|
with AddRecord do
|
|
begin
|
|
if Reg1 in R32 then
|
|
begin
|
|
if Reg2 in R64 then
|
|
begin
|
|
Size := 4;
|
|
code[0] := $66;
|
|
code[1] := $41;
|
|
code[2] := $89;
|
|
code[3] := Get64Code(Reg1, Reg2);
|
|
end
|
|
else
|
|
begin
|
|
Size := 3;
|
|
code[0] := $66;
|
|
code[1] := $89;
|
|
code[2] := Get64Code(Reg1, Reg2);
|
|
end;
|
|
end
|
|
else if Reg1 in R64 then
|
|
begin
|
|
Size := 4;
|
|
code[0] := $66;
|
|
if Reg2 in R64 then
|
|
code[1] := $45
|
|
else
|
|
code[1] := $44;
|
|
code[2] := $89;
|
|
code[3] := Get64Code(Reg1, Reg2);
|
|
end
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmMovREGPtr_REG8(Reg1, Reg2: Integer);
|
|
begin
|
|
SwapRegs(Reg1, Reg2);
|
|
with AddRecord do
|
|
begin
|
|
if Reg1 in R32 then
|
|
begin
|
|
if Reg2 in R64 then
|
|
begin
|
|
Size := 3;
|
|
code[0] := $41;
|
|
code[1] := $88;
|
|
code[2] := Get64Code(Reg1, Reg2);
|
|
end
|
|
else
|
|
begin
|
|
Size := 2;
|
|
code[0] := $88;
|
|
code[1] := Get64Code(Reg1, Reg2);
|
|
end;
|
|
end
|
|
else if Reg1 in R64 then
|
|
begin
|
|
Size := 3;
|
|
if Reg2 in R64 then
|
|
code[0] := $45
|
|
else
|
|
code[0] := $44;
|
|
code[1] := $88;
|
|
Code[2] := Get64Code(Reg1, Reg2);
|
|
end
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
Decompile;
|
|
end;
|
|
exit;
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $88;
|
|
case Reg1 of
|
|
_EAX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $00;
|
|
_ECX: code[1] := $08;
|
|
_EDX: code[1] := $10;
|
|
_EBX: code[1] := $18;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_ECX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $01;
|
|
_ECX: code[1] := $09;
|
|
_EDX: code[1] := $11;
|
|
_EBX: code[1] := $19;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EDX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $02;
|
|
_ECX: code[1] := $0A;
|
|
_EDX: code[1] := $12;
|
|
_EBX: code[1] := $1A;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EBX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $03;
|
|
_ECX: code[1] := $0B;
|
|
_EDX: code[1] := $13;
|
|
_EBX: code[1] := $1B;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
function TSymbolProg.AsmAddREG_Imm(Reg: Integer; value: Integer): TSymbolProgRec;
|
|
begin
|
|
result := AddRecord;
|
|
with result do
|
|
begin
|
|
if PAX64 then
|
|
begin
|
|
Size := 7;
|
|
if Reg in R64 then
|
|
code[0] := $49
|
|
else
|
|
code[0] := $48;
|
|
|
|
code[1] := $81;
|
|
case Reg of
|
|
_EAX: code[2] := $C0;
|
|
_ECX: code[2] := $C1;
|
|
_EDX: code[2] := $C2;
|
|
_EBX: code[2] := $C3;
|
|
_ESP: code[2] := $C4;
|
|
_EBP: code[2] := $C5;
|
|
_ESI: code[2] := $C6;
|
|
_EDI: code[2] := $C7;
|
|
|
|
_R8: code[2] := $C0;
|
|
_R9: code[2] := $C1;
|
|
_R10: code[2] := $C2;
|
|
_R11: code[2] := $C3;
|
|
_R12: code[2] := $C4;
|
|
_R13: code[2] := $C5;
|
|
_R14: code[2] := $C6;
|
|
_R15: code[2] := $C7;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(value, code[3], 4);
|
|
end
|
|
else // 32bit
|
|
case Reg of
|
|
_EAX:
|
|
begin
|
|
Size := 5;
|
|
code[0] := $05;
|
|
Move(value, code[1], 4);
|
|
end;
|
|
_ECX:
|
|
begin
|
|
Size := 6;
|
|
code[0] := $81;
|
|
code[1] := $C1;
|
|
Move(value, code[2], 4);
|
|
end;
|
|
_EDX:
|
|
begin
|
|
Size := 6;
|
|
code[0] := $81;
|
|
code[1] := $C2;
|
|
Move(value, code[2], 4);
|
|
end;
|
|
_EBX:
|
|
begin
|
|
Size := 6;
|
|
code[0] := $81;
|
|
code[1] := $C3;
|
|
Move(value, code[2], 4);
|
|
end;
|
|
_ESP:
|
|
begin
|
|
Size := 6;
|
|
code[0] := $81;
|
|
code[1] := $C4;
|
|
Move(value, code[2], 4);
|
|
end;
|
|
_EBP:
|
|
begin
|
|
Size := 6;
|
|
code[0] := $81;
|
|
code[1] := $C5;
|
|
Move(value, code[2], 4);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmSubREG_Imm(Reg: Integer; value: IntPax);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
if PAX64 then
|
|
begin
|
|
Size := 7;
|
|
code[0] := $48;
|
|
code[1] := $81;
|
|
case Reg of
|
|
_EAX: code[2] := $E8;
|
|
_ECX: code[2] := $E9;
|
|
_EDX: code[2] := $EA;
|
|
_EBX: code[2] := $EB;
|
|
_ESP: code[2] := $EC;
|
|
_EBP: code[2] := $ED;
|
|
_ESI: code[2] := $EE;
|
|
_EDI: code[2] := $EF;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(value, code[3], 4);
|
|
end
|
|
else //32bit
|
|
case Reg of
|
|
_EAX:
|
|
begin
|
|
Size := 5;
|
|
code[0] := $2D;
|
|
Move(value, code[1], 4);
|
|
end;
|
|
_ECX:
|
|
begin
|
|
Size := 6;
|
|
code[0] := $81;
|
|
code[1] := $E9;
|
|
Move(value, code[2], 4);
|
|
end;
|
|
_EDX:
|
|
begin
|
|
Size := 6;
|
|
code[0] := $81;
|
|
code[1] := $EA;
|
|
Move(value, code[2], 4);
|
|
end;
|
|
_EBX:
|
|
begin
|
|
Size := 6;
|
|
code[0] := $81;
|
|
code[1] := $EB;
|
|
Move(value, code[2], 4);
|
|
end;
|
|
_ESP:
|
|
begin
|
|
Size := 6;
|
|
code[0] := $81;
|
|
code[1] := $EC;
|
|
Move(value, code[2], 4);
|
|
end;
|
|
_EBP:
|
|
begin
|
|
Size := 6;
|
|
code[0] := $81;
|
|
code[1] := $ED;
|
|
Move(value, code[2], 4);
|
|
end;
|
|
_ESI:
|
|
begin
|
|
Size := 6;
|
|
code[0] := $81;
|
|
code[1] := $EE;
|
|
Move(value, code[2], 4);
|
|
end;
|
|
_EDI:
|
|
begin
|
|
Size := 6;
|
|
code[0] := $81;
|
|
code[1] := $EF;
|
|
Move(value, code[2], 4);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
// requires EmitGetAddressRegister
|
|
// MOV <SIZE> PTR [REG], Imm
|
|
|
|
procedure TSymbolProg.AsmMovREGPtr_Imm(Reg: Integer; S: TSymbolRec; value: IntPax);
|
|
var
|
|
shift: Integer;
|
|
begin
|
|
shift := GetOffset(S);
|
|
if Reg in CommonRegisters then
|
|
Shift := 0;
|
|
with AddRecord do
|
|
begin
|
|
case S.PtrSize of
|
|
1:
|
|
begin
|
|
Size := 7;
|
|
code[0] := $C6;
|
|
case Reg of
|
|
_EAX: code[1] := $80;
|
|
_ECX: code[1] := $81;
|
|
_EDX: code[1] := $82;
|
|
_EBX: code[1] := $83;
|
|
_ESP: code[1] := $84;
|
|
_EBP: code[1] := $85;
|
|
_ESI: code[1] := $86;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[2], 4);
|
|
code[6] := value;
|
|
end;
|
|
2:
|
|
begin
|
|
Size := 9;
|
|
code[0] := $66;
|
|
code[1] := $C7;
|
|
case Reg of
|
|
_EAX: code[2] := $80;
|
|
_ECX: code[2] := $81;
|
|
_EDX: code[2] := $82;
|
|
_EBX: code[2] := $83;
|
|
_ESP: code[2] := $84;
|
|
_EBP: code[2] := $85;
|
|
_ESI: code[2] := $86;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[3], 4);
|
|
Move(value, code[7], 2);
|
|
end;
|
|
4:
|
|
begin
|
|
Size := 10;
|
|
code[0] := $C7;
|
|
case Reg of
|
|
_EAX: code[1] := $80;
|
|
_ECX: code[1] := $81;
|
|
_EDX: code[1] := $82;
|
|
_EBX: code[1] := $83;
|
|
_EBP: code[1] := $85;
|
|
_ESI: code[1] := $86;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[2], 4);
|
|
Move(value, code[6], 4);
|
|
end;
|
|
8:
|
|
begin
|
|
Size := 11;
|
|
code[0] := $48;
|
|
code[1] := $C7;
|
|
case Reg of
|
|
_EAX: code[2] := $80;
|
|
_ECX: code[2] := $81;
|
|
_EDX: code[2] := $82;
|
|
_EBX: code[2] := $83;
|
|
_EBP: code[2] := $85;
|
|
_ESI: code[2] := $86;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[3], 4);
|
|
Move(value, code[7], 4);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
// requires EmitGetAddressRegister
|
|
// ADD <SIZE> PTR [REG], Imm
|
|
procedure TSymbolProg.AsmAddREGPtr_Imm(Reg: Integer; S: TSymbolRec; value: IntPax);
|
|
var
|
|
shift: Integer;
|
|
begin
|
|
shift := GetOffset(S);
|
|
if Reg in CommonRegisters then
|
|
Shift := 0;
|
|
|
|
with AddRecord do
|
|
begin
|
|
|
|
case S.PtrSize of
|
|
1:
|
|
begin
|
|
Size := 7;
|
|
code[0] := $80;
|
|
case Reg of
|
|
_EAX: code[1] := $80;
|
|
_ECX: code[1] := $81;
|
|
_EDX: code[1] := $82;
|
|
_EBX: code[1] := $83;
|
|
_ESP: code[1] := $84;
|
|
_EBP: code[1] := $85;
|
|
_ESI: code[1] := $86;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[2], 4);
|
|
Move(value, code[6], 1);
|
|
end;
|
|
2:
|
|
begin
|
|
Size := 9;
|
|
code[0] := $66;
|
|
code[1] := $81;
|
|
case Reg of
|
|
_EAX: code[2] := $80;
|
|
_ECX: code[2] := $81;
|
|
_EDX: code[2] := $82;
|
|
_EBX: code[2] := $83;
|
|
_ESP: code[2] := $84;
|
|
_EBP: code[2] := $85;
|
|
_ESI: code[2] := $86;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[3], 4);
|
|
Move(value, code[7], 2);
|
|
end;
|
|
4:
|
|
begin
|
|
Size := 10;
|
|
code[0] := $81;
|
|
case Reg of
|
|
_EAX: code[1] := $80;
|
|
_ECX: code[1] := $81;
|
|
_EDX: code[1] := $82;
|
|
_EBX: code[1] := $83;
|
|
_EBP: code[1] := $85;
|
|
_ESI: code[1] := $86;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[2], 4);
|
|
Move(value, code[6], 4);
|
|
end;
|
|
8:
|
|
begin
|
|
Size := 11;
|
|
code[0] := $48;
|
|
code[1] := $81;
|
|
case Reg of
|
|
_EAX: code[2] := $80;
|
|
_ECX: code[2] := $81;
|
|
_EDX: code[2] := $82;
|
|
_EBX: code[2] := $83;
|
|
_EBP: code[2] := $85;
|
|
_ESI: code[2] := $86;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[3], 4);
|
|
Move(value, code[7], 4);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
// requires EmitGetAddressRegister
|
|
// CMP <SIZE> PTR [REG], Imm
|
|
procedure TSymbolProg.AsmCmpREGPtr_Imm(Reg: Integer; S: TSymbolRec; value: IntPax);
|
|
var
|
|
shift: Integer;
|
|
begin
|
|
shift := GetOffset(S);
|
|
if Reg in CommonRegisters then
|
|
Shift := 0;
|
|
|
|
with AddRecord do
|
|
begin
|
|
case S.PtrSize of
|
|
1:
|
|
begin
|
|
Size := 7;
|
|
code[0] := $80;
|
|
case Reg of
|
|
_EAX: code[1] := $B8;
|
|
_ECX: code[1] := $B9;
|
|
_EDX: code[1] := $BA;
|
|
_EBX: code[1] := $BB;
|
|
_ESP: code[1] := $BC;
|
|
_EBP: code[1] := $BD;
|
|
_ESI: code[1] := $BE;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[2], 4);
|
|
Move(value, code[6], 1);
|
|
end;
|
|
2:
|
|
begin
|
|
Size := 9;
|
|
code[0] := $66;
|
|
code[1] := $81;
|
|
case Reg of
|
|
_EAX: code[2] := $B8;
|
|
_ECX: code[2] := $B9;
|
|
_EDX: code[2] := $BA;
|
|
_EBX: code[2] := $BB;
|
|
_ESP: code[2] := $BC;
|
|
_EBP: code[2] := $BD;
|
|
_ESI: code[2] := $BE;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[3], 4);
|
|
Move(value, code[7], 2);
|
|
end;
|
|
4:
|
|
begin
|
|
Size := 10;
|
|
code[0] := $81;
|
|
case Reg of
|
|
_EAX: code[1] := $B8;
|
|
_ECX: code[1] := $B9;
|
|
_EDX: code[1] := $BA;
|
|
_EBX: code[1] := $BB;
|
|
_ESP: code[1] := $BC;
|
|
_EBP: code[1] := $BD;
|
|
_ESI: code[1] := $BE;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[2], 4);
|
|
Move(value, code[6], 4);
|
|
end;
|
|
8:
|
|
begin
|
|
Size := 11;
|
|
code[0] := $48;
|
|
code[1] := $81;
|
|
case Reg of
|
|
_EAX: code[2] := $B8;
|
|
_ECX: code[2] := $B9;
|
|
_EDX: code[2] := $BA;
|
|
_EBX: code[2] := $BB;
|
|
_ESP: code[2] := $BC;
|
|
_EBP: code[2] := $BD;
|
|
_ESI: code[2] := $BE;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[3], 4);
|
|
Move(value, code[7], 4);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmIncReg32Ptr(Reg: Integer; shift: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 6;
|
|
code[0] := $FF;
|
|
case Reg of
|
|
_EAX: code[1] := $80;
|
|
_ECX: code[1] := $81;
|
|
_EDX: code[1] := $82;
|
|
_EBX: code[1] := $83;
|
|
_EBP: code[1] := $85;
|
|
_ESI: code[1] := $86;
|
|
_EDI: code[1] := $87;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[2], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmIncBytePtr(Reg: Integer; shift: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
case Reg of
|
|
_ESP:
|
|
begin
|
|
if Shift <> -12 then
|
|
RaiseError(errInternalError, []);
|
|
|
|
Size := 4;
|
|
Code[0] := $FE;
|
|
Code[1] := $44;
|
|
Code[2] := $24;
|
|
Code[3] := $F4;
|
|
Decompile;
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmDecReg32Ptr(Reg: Integer; shift: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 6;
|
|
code[0] := $FF;
|
|
case Reg of
|
|
_EAX: code[1] := $88;
|
|
_ECX: code[1] := $89;
|
|
_EDX: code[1] := $8A;
|
|
_EBX: code[1] := $8B;
|
|
// _ESP: code[1] := $8C; special case
|
|
_EBP: code[1] := $8D;
|
|
_ESI: code[1] := $8E;
|
|
_EDI: code[1] := $8F;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[2], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmCmpReg32Ptr_Imm(Reg: Integer; shift: Integer; value: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 10;
|
|
code[0] := $81;
|
|
case Reg of
|
|
_EAX: code[1] := $B8;
|
|
_ECX: code[1] := $B9;
|
|
_EDX: code[1] := $BA;
|
|
_EBX: code[1] := $BB;
|
|
_ESP: code[1] := $BC;
|
|
_EBP: code[1] := $BD;
|
|
_ESI: code[1] := $BE;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[2], 4);
|
|
Move(value, code[6], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmAddREG_REG(Reg1, Reg2: Integer);
|
|
begin
|
|
if PAX64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $48;
|
|
code[1] := $01;
|
|
case Reg1 of
|
|
_EAX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C0;
|
|
_ECX: code[2] := $C8;
|
|
_EDX: code[2] := $D0;
|
|
_EBX: code[2] := $D8;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_ECX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C1;
|
|
_ECX: code[2] := $C9;
|
|
_EDX: code[2] := $D1;
|
|
_EBX: code[2] := $D9;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EDX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C2;
|
|
_ECX: code[2] := $CA;
|
|
_EDX: code[2] := $D2;
|
|
_EBX: code[2] := $DA;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EBX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C3;
|
|
_ECX: code[2] := $CB;
|
|
_EDX: code[2] := $D3;
|
|
_EBX: code[2] := $DB;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end
|
|
else //32bit
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $01;
|
|
case Reg1 of
|
|
_EAX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C0;
|
|
_ECX: code[1] := $C8;
|
|
_EDX: code[1] := $D0;
|
|
_EBX: code[1] := $D8;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_ECX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C1;
|
|
_ECX: code[1] := $C9;
|
|
_EDX: code[1] := $D1;
|
|
_EBX: code[1] := $D9;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EDX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C2;
|
|
_ECX: code[1] := $CA;
|
|
_EDX: code[1] := $D2;
|
|
_EBX: code[1] := $DA;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EBX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C3;
|
|
_ECX: code[1] := $CB;
|
|
_EDX: code[1] := $D3;
|
|
_EBX: code[1] := $DB;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmAdcREG_REG(Reg1, Reg2: Integer);
|
|
begin
|
|
if PAX64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $48;
|
|
code[1] := $11;
|
|
case Reg1 of
|
|
_EAX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C0;
|
|
_ECX: code[2] := $C8;
|
|
_EDX: code[2] := $D0;
|
|
_EBX: code[2] := $D8;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_ECX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C1;
|
|
_ECX: code[2] := $C9;
|
|
_EDX: code[2] := $D1;
|
|
_EBX: code[2] := $D9;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EDX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C2;
|
|
_ECX: code[2] := $CA;
|
|
_EDX: code[2] := $D2;
|
|
_EBX: code[2] := $DA;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EBX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C3;
|
|
_ECX: code[2] := $CB;
|
|
_EDX: code[2] := $D3;
|
|
_EBX: code[2] := $DB;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end
|
|
else //32bit
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $11;
|
|
case Reg1 of
|
|
_EAX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C0;
|
|
_ECX: code[1] := $C8;
|
|
_EDX: code[1] := $D0;
|
|
_EBX: code[1] := $D8;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_ECX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C1;
|
|
_ECX: code[1] := $C9;
|
|
_EDX: code[1] := $D1;
|
|
_EBX: code[1] := $D9;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EDX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C2;
|
|
_ECX: code[1] := $CA;
|
|
_EDX: code[1] := $D2;
|
|
_EBX: code[1] := $DA;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EBX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C3;
|
|
_ECX: code[1] := $CB;
|
|
_EDX: code[1] := $D3;
|
|
_EBX: code[1] := $DB;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmSbbREG_REG(Reg1, Reg2: Integer);
|
|
begin
|
|
if PAX64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $48;
|
|
code[1] := $19;
|
|
case Reg1 of
|
|
_EAX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C0;
|
|
_ECX: code[2] := $C8;
|
|
_EDX: code[2] := $D0;
|
|
_EBX: code[2] := $D8;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_ECX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C1;
|
|
_ECX: code[2] := $C9;
|
|
_EDX: code[2] := $D1;
|
|
_EBX: code[2] := $D9;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EDX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C2;
|
|
_ECX: code[2] := $CA;
|
|
_EDX: code[2] := $D2;
|
|
_EBX: code[2] := $DA;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EBX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C3;
|
|
_ECX: code[2] := $CB;
|
|
_EDX: code[2] := $D3;
|
|
_EBX: code[2] := $DB;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end
|
|
else //32bit
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $19;
|
|
case Reg1 of
|
|
_EAX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C0;
|
|
_ECX: code[1] := $C8;
|
|
_EDX: code[1] := $D0;
|
|
_EBX: code[1] := $D8;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_ECX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C1;
|
|
_ECX: code[1] := $C9;
|
|
_EDX: code[1] := $D1;
|
|
_EBX: code[1] := $D9;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EDX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C2;
|
|
_ECX: code[1] := $CA;
|
|
_EDX: code[1] := $D2;
|
|
_EBX: code[1] := $DA;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EBX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C3;
|
|
_ECX: code[1] := $CB;
|
|
_EDX: code[1] := $D3;
|
|
_EBX: code[1] := $DB;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmSubREG_REG(Reg1, Reg2: Integer);
|
|
begin
|
|
if PAX64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $48;
|
|
code[1] := $29;
|
|
case Reg1 of
|
|
_EAX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C0;
|
|
_ECX: code[2] := $C8;
|
|
_EDX: code[2] := $D0;
|
|
_EBX: code[2] := $D8;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_ECX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C1;
|
|
_ECX: code[2] := $C9;
|
|
_EDX: code[2] := $D1;
|
|
_EBX: code[2] := $D9;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EDX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C2;
|
|
_ECX: code[2] := $CA;
|
|
_EDX: code[2] := $D2;
|
|
_EBX: code[2] := $DA;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EBX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C3;
|
|
_ECX: code[2] := $CB;
|
|
_EDX: code[2] := $D3;
|
|
_EBX: code[2] := $DB;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end
|
|
else //32bit
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $29;
|
|
case Reg1 of
|
|
_EAX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C0;
|
|
_ECX: code[1] := $C8;
|
|
_EDX: code[1] := $D0;
|
|
_EBX: code[1] := $D8;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_ECX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C1;
|
|
_ECX: code[1] := $C9;
|
|
_EDX: code[1] := $D1;
|
|
_EBX: code[1] := $D9;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EDX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C2;
|
|
_ECX: code[1] := $CA;
|
|
_EDX: code[1] := $D2;
|
|
_EBX: code[1] := $DA;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EBX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C3;
|
|
_ECX: code[1] := $CB;
|
|
_EDX: code[1] := $D3;
|
|
_EBX: code[1] := $DB;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmXorREG_REG(Reg1, Reg2: Integer);
|
|
begin
|
|
if PAX64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $48;
|
|
code[1] := $31;
|
|
case Reg1 of
|
|
_EAX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C0;
|
|
_ECX: code[2] := $C8;
|
|
_EDX: code[2] := $D0;
|
|
_EBX: code[2] := $D8;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_ECX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C1;
|
|
_ECX: code[2] := $C9;
|
|
_EDX: code[2] := $D1;
|
|
_EBX: code[2] := $D9;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EDX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C2;
|
|
_ECX: code[2] := $CA;
|
|
_EDX: code[2] := $D2;
|
|
_EBX: code[2] := $DA;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EBX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C3;
|
|
_ECX: code[2] := $CB;
|
|
_EDX: code[2] := $D3;
|
|
_EBX: code[2] := $DB;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end
|
|
else //32bit
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $31;
|
|
case Reg1 of
|
|
_EAX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C0;
|
|
_ECX: code[1] := $C8;
|
|
_EDX: code[1] := $D0;
|
|
_EBX: code[1] := $D8;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_ECX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C1;
|
|
_ECX: code[1] := $C9;
|
|
_EDX: code[1] := $D1;
|
|
_EBX: code[1] := $D9;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EDX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C2;
|
|
_ECX: code[1] := $CA;
|
|
_EDX: code[1] := $D2;
|
|
_EBX: code[1] := $DA;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EBX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C3;
|
|
_ECX: code[1] := $CB;
|
|
_EDX: code[1] := $D3;
|
|
_EBX: code[1] := $DB;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmAndREG_REG(Reg1, Reg2: Integer);
|
|
begin
|
|
if PAX64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $48;
|
|
code[1] := $21;
|
|
case Reg1 of
|
|
_EAX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C0;
|
|
_ECX: code[2] := $C8;
|
|
_EDX: code[2] := $D0;
|
|
_EBX: code[2] := $D8;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_ECX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C1;
|
|
_ECX: code[2] := $C9;
|
|
_EDX: code[2] := $D1;
|
|
_EBX: code[2] := $D9;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EDX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C2;
|
|
_ECX: code[2] := $CA;
|
|
_EDX: code[2] := $D2;
|
|
_EBX: code[2] := $DA;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EBX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C3;
|
|
_ECX: code[2] := $CB;
|
|
_EDX: code[2] := $D3;
|
|
_EBX: code[2] := $DB;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end
|
|
else //32bit
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $21;
|
|
case Reg1 of
|
|
_EAX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C0;
|
|
_ECX: code[1] := $C8;
|
|
_EDX: code[1] := $D0;
|
|
_EBX: code[1] := $D8;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_ECX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C1;
|
|
_ECX: code[1] := $C9;
|
|
_EDX: code[1] := $D1;
|
|
_EBX: code[1] := $D9;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EDX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C2;
|
|
_ECX: code[1] := $CA;
|
|
_EDX: code[1] := $D2;
|
|
_EBX: code[1] := $DA;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EBX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C3;
|
|
_ECX: code[1] := $CB;
|
|
_EDX: code[1] := $D3;
|
|
_EBX: code[1] := $DB;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmOrREG_REG(Reg1, Reg2: Integer);
|
|
begin
|
|
if PAX64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $48;
|
|
code[1] := $09;
|
|
case Reg1 of
|
|
_EAX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C0;
|
|
_ECX: code[2] := $C8;
|
|
_EDX: code[2] := $D0;
|
|
_EBX: code[2] := $D8;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_ECX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C1;
|
|
_ECX: code[2] := $C9;
|
|
_EDX: code[2] := $D1;
|
|
_EBX: code[2] := $D9;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EDX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C2;
|
|
_ECX: code[2] := $CA;
|
|
_EDX: code[2] := $D2;
|
|
_EBX: code[2] := $DA;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EBX:
|
|
case Reg2 of
|
|
_EAX: code[2] := $C3;
|
|
_ECX: code[2] := $CB;
|
|
_EDX: code[2] := $D3;
|
|
_EBX: code[2] := $DB;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end
|
|
else //32bit
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $09;
|
|
case Reg1 of
|
|
_EAX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C0;
|
|
_ECX: code[1] := $C8;
|
|
_EDX: code[1] := $D0;
|
|
_EBX: code[1] := $D8;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_ECX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C1;
|
|
_ECX: code[1] := $C9;
|
|
_EDX: code[1] := $D1;
|
|
_EBX: code[1] := $D9;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EDX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C2;
|
|
_ECX: code[1] := $CA;
|
|
_EDX: code[1] := $D2;
|
|
_EBX: code[1] := $DA;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EBX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $C3;
|
|
_ECX: code[1] := $CB;
|
|
_EDX: code[1] := $D3;
|
|
_EBX: code[1] := $DB;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmMulREG(Reg: Integer);
|
|
begin
|
|
if PAX64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $48;
|
|
code[1] := $F7;
|
|
case Reg of
|
|
_EAX: code[2] := $E0;
|
|
_ECX: code[2] := $E1;
|
|
_EDX: code[2] := $E2;
|
|
_EBX: code[2] := $E3;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end
|
|
else //32bit
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $F7;
|
|
case Reg of
|
|
_EAX: code[1] := $E0;
|
|
_ECX: code[1] := $E1;
|
|
_EDX: code[1] := $E2;
|
|
_EBX: code[1] := $E3;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmIMulREG(Reg: Integer);
|
|
begin
|
|
if PAX64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $48;
|
|
code[1] := $F7;
|
|
case Reg of
|
|
_EAX: code[2] := $E8;
|
|
_ECX: code[2] := $E9;
|
|
_EDX: code[2] := $EA;
|
|
_EBX: code[2] := $EB;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end
|
|
else //32bit
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $F7;
|
|
case Reg of
|
|
_EAX: code[1] := $E8;
|
|
_ECX: code[1] := $E9;
|
|
_EDX: code[1] := $EA;
|
|
_EBX: code[1] := $EB;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmDivREG(Reg: Integer);
|
|
begin
|
|
if PAX64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $48;
|
|
code[1] := $F7;
|
|
case Reg of
|
|
_EAX: code[2] := $F0;
|
|
_ECX: code[2] := $F1;
|
|
_EDX: code[2] := $F2;
|
|
_EBX: code[2] := $F3;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end
|
|
else //32bit
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $F7;
|
|
case Reg of
|
|
_EAX: code[1] := $F0;
|
|
_ECX: code[1] := $F1;
|
|
_EDX: code[1] := $F2;
|
|
_EBX: code[1] := $F3;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmIDivREG(Reg: Integer);
|
|
begin
|
|
if PAX64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $48;
|
|
code[1] := $F7;
|
|
case Reg of
|
|
_EAX: code[2] := $F8;
|
|
_ECX: code[2] := $F9;
|
|
_EDX: code[2] := $FA;
|
|
_EBX: code[2] := $FB;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end
|
|
else //32bit
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $F7;
|
|
case Reg of
|
|
_EAX: code[1] := $F8;
|
|
_ECX: code[1] := $F9;
|
|
_EDX: code[1] := $FA;
|
|
_EBX: code[1] := $FB;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmShlREG(Reg: Integer);
|
|
begin
|
|
if PAX64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $48;
|
|
code[1] := $D3;
|
|
case Reg of
|
|
_EAX: code[2] := $E0;
|
|
_ECX: code[2] := $E1;
|
|
_EDX: code[2] := $E2;
|
|
_EBX: code[2] := $E3;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end
|
|
else //32bit
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $D3;
|
|
case Reg of
|
|
_EAX: code[1] := $E0;
|
|
_ECX: code[1] := $E1;
|
|
_EDX: code[1] := $E2;
|
|
_EBX: code[1] := $E3;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmShrREG(Reg: Integer);
|
|
begin
|
|
if PAX64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $48;
|
|
code[1] := $D3;
|
|
case Reg of
|
|
_EAX: code[2] := $E8;
|
|
_ECX: code[2] := $E9;
|
|
_EDX: code[2] := $EA;
|
|
_EBX: code[2] := $EB;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end
|
|
else
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $D3;
|
|
case Reg of
|
|
_EAX: code[1] := $E8;
|
|
_ECX: code[1] := $E9;
|
|
_EDX: code[1] := $EA;
|
|
_EBX: code[1] := $EB;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmNotREG(Reg: Integer);
|
|
begin
|
|
if PAX64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $48;
|
|
code[1] := $F7;
|
|
case Reg of
|
|
_EAX: code[2] := $D0;
|
|
_ECX: code[2] := $D1;
|
|
_EDX: code[2] := $D2;
|
|
_EBX: code[2] := $D3;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end
|
|
else
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $F7;
|
|
case Reg of
|
|
_EAX: code[1] := $D0;
|
|
_ECX: code[1] := $D1;
|
|
_EDX: code[1] := $D2;
|
|
_EBX: code[1] := $D3;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmNegREG(Reg: Integer);
|
|
begin
|
|
if PAX64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $48;
|
|
code[1] := $F7;
|
|
case Reg of
|
|
_EAX: code[2] := $D8;
|
|
_ECX: code[2] := $D9;
|
|
_EDX: code[2] := $DA;
|
|
_EBX: code[2] := $DB;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end
|
|
else
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $F7;
|
|
case Reg of
|
|
_EAX: code[1] := $D8;
|
|
_ECX: code[1] := $D9;
|
|
_EDX: code[1] := $DA;
|
|
_EBX: code[1] := $DB;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
// requires EmitGetAddressRegister
|
|
// NEG <SIZE = 4> PTR [REG + Shift]
|
|
procedure TSymbolProg.AsmNEG_REGPtr(Reg: Integer; S: TSymbolRec);
|
|
var
|
|
shift: Integer;
|
|
begin
|
|
shift := GetOffset(S);
|
|
if Reg in CommonRegisters then
|
|
Shift := 0;
|
|
|
|
case S.PtrSize of
|
|
4:
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 6;
|
|
code[0] := $F7;
|
|
|
|
case Reg of
|
|
_EAX: code[1] := $98;
|
|
_ECX: code[1] := $99;
|
|
_EDX: code[1] := $9A;
|
|
_EBX: code[1] := $9B;
|
|
_ESP: code[1] := $9C;
|
|
_EBP: code[1] := $9D;
|
|
_ESI: code[1] := $9E;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
|
|
Move(shift, code[2], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
8:
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 7;
|
|
code[0] := $48;
|
|
code[1] := $F7;
|
|
|
|
case Reg of
|
|
_EAX: code[2] := $98;
|
|
_ECX: code[2] := $99;
|
|
_EDX: code[2] := $9A;
|
|
_EBX: code[2] := $9B;
|
|
_ESP: code[2] := $9C;
|
|
_EBP: code[2] := $9D;
|
|
_ESI: code[2] := $9E;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmLoadESI_ESPPtr(shift: Integer); // not used
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 7;
|
|
code[0] := $8B;
|
|
code[1] := $B4;
|
|
code[2] := $24;
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmLoadEDI_ESPPtr(shift: Integer); // not used
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 7;
|
|
code[0] := $8B;
|
|
code[1] := $BC;
|
|
code[2] := $24;
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
function TSymbolProg.AsmGetREG_ESIPtr(Reg: Integer; shift: Integer): TSymbolProgRec;
|
|
begin
|
|
if PAX64 then
|
|
result := AsmGetREG64_RSIPtr(Reg, shift)
|
|
else
|
|
result := AsmGetREG32_ESIPtr(Reg, shift);
|
|
end;
|
|
|
|
function TSymbolProg.AsmGetREG64_RSIPtr(Reg: Integer; shift: Integer): TSymbolProgRec;
|
|
begin
|
|
result := AddRecord;
|
|
with result do
|
|
begin
|
|
Size := 7;
|
|
if Reg in R64 then
|
|
code[0] := $4C
|
|
else
|
|
code[0] := $48;
|
|
code[1] := $8B;
|
|
code[2] := GetMovESIPtrCode(Reg);
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
function TSymbolProg.AsmGetREG32_ESIPtr(Reg: Integer; shift: Integer): TSymbolProgRec;
|
|
begin
|
|
result := AddRecord;
|
|
if Reg in R64 then
|
|
with result do
|
|
begin
|
|
Size := 7;
|
|
code[0] := $44;
|
|
code[1] := $8B;
|
|
code[2] := GetMovESIPtrCode(Reg);
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end
|
|
else
|
|
with result do
|
|
begin
|
|
Size := 6;
|
|
code[0] := $8B;
|
|
code[1] := GetMovESIPtrCode(Reg);
|
|
Move(shift, code[2], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmGetREG16_ESIPtr(Reg: Integer; shift: Integer);
|
|
begin
|
|
if Reg in R64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 8;
|
|
code[0] := $66;
|
|
code[1] := $44;
|
|
code[2] := $8B;
|
|
code[3] := GetMovESIPtrCode(Reg);
|
|
Move(shift, code[4], 4);
|
|
Decompile;
|
|
end
|
|
else
|
|
with AddRecord do
|
|
begin
|
|
Size := 7;
|
|
code[0] := $66;
|
|
code[1] := $8B;
|
|
code[2] := GetMovESIPtrCode(Reg);
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmGetREG8_ESIPtr(Reg: Integer; shift: Integer);
|
|
begin
|
|
if Reg in R64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 7;
|
|
code[0] := $44;
|
|
code[1] := $8A;
|
|
code[2] := GetMovESIPtrCode(Reg);
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end
|
|
else
|
|
with AddRecord do
|
|
begin
|
|
Size := 6;
|
|
code[0] := $8A;
|
|
code[1] := GetMovESIPtrCode(Reg);
|
|
Move(shift, code[2], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmPutREG_ESIPtr(Reg: Integer; shift: Integer);
|
|
begin
|
|
if PAX64 then
|
|
AsmPutREG64_RSIPtr(Reg, shift)
|
|
else
|
|
AsmPutREG32_ESIPtr(Reg, shift);
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmPutREG64_RSIPtr(Reg: Integer; shift: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 7;
|
|
if Reg in R64 then
|
|
code[0] := $4C
|
|
else
|
|
code[0] := $48;
|
|
code[1] := $89;
|
|
code[2] := GetMovESIPtrCode(Reg);
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmPutREG32_ESIPtr(Reg: Integer; shift: Integer);
|
|
begin
|
|
if Reg in R64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 7;
|
|
code[0] := $44;
|
|
code[1] := $89;
|
|
code[2] := GetMovESIPtrCode(Reg);
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end
|
|
else
|
|
with AddRecord do
|
|
begin
|
|
Size := 6;
|
|
code[0] := $89;
|
|
code[1] := GetMovESIPtrCode(Reg);
|
|
Move(shift, code[2], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmPutREG16_ESIPtr(Reg: Integer; shift: Integer);
|
|
begin
|
|
if Reg in R64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 8;
|
|
code[0] := $66;
|
|
code[1] := $44;
|
|
code[2] := $89;
|
|
code[3] := GetMovESIPtrCode(Reg);
|
|
Move(shift, code[4], 4);
|
|
Decompile;
|
|
end
|
|
else
|
|
with AddRecord do
|
|
begin
|
|
Size := 7;
|
|
code[0] := $66;
|
|
code[1] := $89;
|
|
code[2] := GetMovESIPtrCode(Reg);
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmPutREG8_ESIPtr(Reg: Integer; shift: Integer);
|
|
begin
|
|
if Reg in R64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 7;
|
|
code[0] := $44;
|
|
code[1] := $88;
|
|
code[2] := GetMovESIPtrCode(Reg);
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end
|
|
else
|
|
with AddRecord do
|
|
begin
|
|
Size := 6;
|
|
code[0] := $88;
|
|
code[1] := GetMovESIPtrCode(Reg);
|
|
Move(shift, code[2], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmLeaReg32_RegPtr(Reg1, Reg2: Integer; shift: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 6;
|
|
code[0] := $8D;
|
|
case Reg1 of
|
|
_EAX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $80;
|
|
_ECX: code[1] := $81;
|
|
_EDX: code[1] := $82;
|
|
_EBX: code[1] := $83;
|
|
|
|
_EBP: code[1] := $85;
|
|
_ESI: code[1] := $86;
|
|
_EDI: code[1] := $87;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_ECX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $88;
|
|
_ECX: code[1] := $89;
|
|
_EDX: code[1] := $8A;
|
|
_EBX: code[1] := $8B;
|
|
|
|
_EBP: code[1] := $8D;
|
|
_ESI: code[1] := $8E;
|
|
_EDI: code[1] := $8F;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EDX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $90;
|
|
_ECX: code[1] := $91;
|
|
_EDX: code[1] := $92;
|
|
_EBX: code[1] := $93;
|
|
|
|
_EBP: code[1] := $95;
|
|
_ESI: code[1] := $96;
|
|
_EDI: code[1] := $97;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_EBX:
|
|
case Reg2 of
|
|
_EAX: code[1] := $98;
|
|
_ECX: code[1] := $99;
|
|
_EDX: code[1] := $9A;
|
|
_EBX: code[1] := $9B;
|
|
|
|
_EBP: code[1] := $9D;
|
|
_ESI: code[1] := $9E;
|
|
_EDI: code[1] := $9F;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[2], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmGetREG_EBPPtr(Reg: Integer; shift: Integer);
|
|
begin
|
|
if PAX64 then
|
|
AsmGetREG64_RBPPtr(Reg, shift)
|
|
else
|
|
AsmGetREG32_EBPPtr(Reg, shift);
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmGetREG64_RBPPtr(Reg: Integer; shift: Integer);
|
|
begin
|
|
if Reg in R64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 7;
|
|
code[0] := $4C;
|
|
code[1] := $8B;
|
|
code[2] := GetMovEBPPtrCode(Reg);
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end
|
|
else
|
|
with AddRecord do
|
|
begin
|
|
Size := 7;
|
|
code[0] := $48;
|
|
code[1] := $8B;
|
|
code[2] := GetMovEBPPtrCode(Reg);
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmGetREG32_EBPPtr(Reg: Integer; shift: Integer);
|
|
begin
|
|
if Reg in R64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 7;
|
|
code[0] := $44;
|
|
code[1] := $8B;
|
|
code[2] := GetMovEBPPtrCode(Reg);
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end
|
|
else
|
|
with AddRecord do
|
|
begin
|
|
Size := 6;
|
|
code[0] := $8B;
|
|
code[1] := GetMovEBPPtrCode(Reg);
|
|
Move(shift, code[2], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmGetREG16_EBPPtr(Reg: Integer; shift: Integer);
|
|
begin
|
|
if Reg in R64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 8;
|
|
code[0] := $66;
|
|
code[1] := $44;
|
|
code[2] := $8B;
|
|
code[3] := GetMovEBPPtrCode(Reg);
|
|
Move(shift, code[4], 4);
|
|
Decompile;
|
|
end
|
|
else
|
|
with AddRecord do
|
|
begin
|
|
Size := 7;
|
|
code[0] := $66;
|
|
code[1] := $8B;
|
|
code[2] := GetMovEBPPtrCode(Reg);
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmPutREG_EBPPtr(Reg: Integer; shift: Integer);
|
|
begin
|
|
if PAX64 then
|
|
AsmPutREG64_RBPPtr(Reg, shift)
|
|
else
|
|
AsmPutREG32_EBPPtr(Reg, shift);
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmPutREG64_RBPPtr(Reg: Integer; shift: Integer);
|
|
begin
|
|
if Reg in R64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 7;
|
|
code[0] := $4C;
|
|
code[1] := $89;
|
|
code[2] := GetMovEBPPtrCode(Reg);
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end
|
|
else
|
|
with AddRecord do
|
|
begin
|
|
Size := 7;
|
|
code[0] := $48;
|
|
code[1] := $89;
|
|
code[2] := GetMovEBPPtrCode(Reg);
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmPutREG32_EBPPtr(Reg: Integer; shift: Integer);
|
|
begin
|
|
if Reg in R64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 7;
|
|
code[0] := $44;
|
|
code[1] := $89;
|
|
code[2] := GetMovEBPPtrCode(Reg);
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end
|
|
else
|
|
with AddRecord do
|
|
begin
|
|
Size := 6;
|
|
code[0] := $89;
|
|
code[1] := GetMovEBPPtrCode(Reg);
|
|
Move(shift, code[2], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmPutREG16_EBPPtr(Reg: Integer; shift: Integer);
|
|
begin
|
|
if Reg in R64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 8;
|
|
code[0] := $66;
|
|
code[1] := $44;
|
|
code[2] := $89;
|
|
code[3] := GetMovEBPPtrCode(Reg);
|
|
Move(shift, code[4], 4);
|
|
Decompile;
|
|
end
|
|
else
|
|
with AddRecord do
|
|
begin
|
|
Size := 7;
|
|
code[0] := $66;
|
|
code[1] := $89;
|
|
code[2] := GetMovEBPPtrCode(Reg);
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmGetREG8_EBPPtr(Reg: Integer; shift: Integer);
|
|
begin
|
|
if Reg in R64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 7;
|
|
code[0] := $44;
|
|
code[1] := $8A;
|
|
code[2] := GetMovEBPPtrCode(Reg);
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end
|
|
else
|
|
with AddRecord do
|
|
begin
|
|
Size := 6;
|
|
code[0] := $8A;
|
|
code[1] := GetMovEBPPtrCode(Reg);
|
|
Move(shift, code[2], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmPutREG8_EBPPtr(Reg: Integer; shift: Integer);
|
|
begin
|
|
if Reg in R64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 7;
|
|
code[0] := $44;
|
|
code[1] := $88;
|
|
code[2] := GetMovEBPPtrCode(Reg);
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end
|
|
else
|
|
with AddRecord do
|
|
begin
|
|
Size := 6;
|
|
code[0] := $88;
|
|
code[1] := GetMovEBPPtrCode(Reg);
|
|
Move(shift, code[2], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmFldDouble_REGPtr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $DD;
|
|
case Reg of
|
|
_EAX: code[1] := $00;
|
|
_ECX: code[1] := $01;
|
|
_EDX: code[1] := $02;
|
|
_EBX: code[1] := $03;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmFldSingle_REGPtr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $D9;
|
|
case Reg of
|
|
_EAX: code[1] := $00;
|
|
_ECX: code[1] := $01;
|
|
_EDX: code[1] := $02;
|
|
_EBX: code[1] := $03;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmFldExtended_REGPtr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $DB;
|
|
case Reg of
|
|
_EAX: code[1] := $28;
|
|
_ECX: code[1] := $29;
|
|
_EDX: code[1] := $2A;
|
|
_EBX: code[1] := $2B;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
// requires EmitGetAddressRegister
|
|
// Fld QWORD PTR [REG + Shift]
|
|
procedure TSymbolProg.AsmFldDouble_REGPtr(Reg: Integer; S: TSymbolRec);
|
|
var
|
|
shift: Integer;
|
|
begin
|
|
shift := GetOffset(S);
|
|
if Reg in CommonRegisters then
|
|
Shift := 0;
|
|
|
|
if PAX64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 7;
|
|
code[0] := $48;
|
|
code[1] := $DD;
|
|
case Reg of
|
|
_EAX: code[2] := $80;
|
|
_ECX: code[2] := $81;
|
|
_EDX: code[2] := $82;
|
|
_EBX: code[2] := $83;
|
|
_EBP: code[2] := $85;
|
|
_ESI: code[2] := $86;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end
|
|
else // 32bit
|
|
with AddRecord do
|
|
begin
|
|
Size := 6;
|
|
code[0] := $DD;
|
|
case Reg of
|
|
_EAX: code[1] := $80;
|
|
_ECX: code[1] := $81;
|
|
_EDX: code[1] := $82;
|
|
_EBX: code[1] := $83;
|
|
_EBP: code[1] := $85;
|
|
_ESI: code[1] := $86;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[2], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
// requires EmitGetAddressRegister
|
|
// Fld DWORD PTR [REG + Shift]
|
|
procedure TSymbolProg.AsmFldSingle_REGPtr(Reg: Integer; S: TSymbolRec);
|
|
var
|
|
shift: Integer;
|
|
begin
|
|
shift := GetOffset(S);
|
|
if Reg in CommonRegisters then
|
|
Shift := 0;
|
|
|
|
with AddRecord do
|
|
begin
|
|
Size := 6;
|
|
code[0] := $D9;
|
|
case Reg of
|
|
_EAX: code[1] := $80;
|
|
_ECX: code[1] := $81;
|
|
_EDX: code[1] := $82;
|
|
_EBX: code[1] := $83;
|
|
_EBP: code[1] := $85;
|
|
_ESI: code[1] := $86;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[2], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
// requires EmitGetAddressRegister
|
|
// Fld TBYTE PTR [REG + Shift]
|
|
procedure TSymbolProg.AsmFldExtended_REGPtr(Reg: Integer; S: TSymbolRec);
|
|
var
|
|
shift: Integer;
|
|
begin
|
|
shift := GetOffset(S);
|
|
if Reg in CommonRegisters then
|
|
Shift := 0;
|
|
|
|
with AddRecord do
|
|
begin
|
|
Size := 6;
|
|
code[0] := $DB;
|
|
case Reg of
|
|
_EAX: code[1] := $A8;
|
|
_ECX: code[1] := $A9;
|
|
_EDX: code[1] := $AA;
|
|
_EBX: code[1] := $AB;
|
|
_EBP: code[1] := $AD;
|
|
_ESI: code[1] := $AE;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[2], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmFild_REG32Ptr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $DB;
|
|
case Reg of
|
|
_EAX: code[1] := $00;
|
|
_ECX: code[1] := $01;
|
|
_EDX: code[1] := $02;
|
|
_EBX: code[1] := $03;
|
|
_ESI: code[1] := $06;
|
|
_EDI: code[1] := $07;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmFild_REG16Ptr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $DF;
|
|
case Reg of
|
|
_EAX: code[1] := $00;
|
|
_ECX: code[1] := $01;
|
|
_EDX: code[1] := $02;
|
|
_EBX: code[1] := $03;
|
|
_ESI: code[1] := $06;
|
|
_EDI: code[1] := $07;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmFild_REG64Ptr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $DF;
|
|
case Reg of
|
|
_EAX: code[1] := $28;
|
|
_ECX: code[1] := $29;
|
|
_EDX: code[1] := $2A;
|
|
_EBX: code[1] := $2B;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmFistp_REG64Ptr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $DF;
|
|
case Reg of
|
|
_EAX: code[1] := $38;
|
|
_ECX: code[1] := $39;
|
|
_EDX: code[1] := $3A;
|
|
_EBX: code[1] := $3B;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmFAdd_REGPtr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $DC;
|
|
case Reg of
|
|
_EAX: code[1] := $00;
|
|
_ECX: code[1] := $01;
|
|
_EDX: code[1] := $02;
|
|
_EBX: code[1] := $03;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmFSub_REGPtr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $DC;
|
|
case Reg of
|
|
_EAX: code[1] := $20;
|
|
_ECX: code[1] := $21;
|
|
_EDX: code[1] := $22;
|
|
_EBX: code[1] := $23;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmFMul_REGPtr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $DC;
|
|
case Reg of
|
|
_EAX: code[1] := $08;
|
|
_ECX: code[1] := $09;
|
|
_EDX: code[1] := $0A;
|
|
_EBX: code[1] := $0B;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmFMul_ESIPtr32(Shift: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 6;
|
|
code[0] := $D8;
|
|
code[1] := $8E;
|
|
Move(Shift, code[2], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmFDiv_ESIPtr32(Shift: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 6;
|
|
code[0] := $D8;
|
|
code[1] := $B6;
|
|
Move(Shift, code[2], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmFDiv_REGPtr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $DC;
|
|
case Reg of
|
|
_EAX: code[1] := $30;
|
|
_ECX: code[1] := $31;
|
|
_EDX: code[1] := $32;
|
|
_EBX: code[1] := $33;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmFComp_REGPtr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $D8;
|
|
case Reg of
|
|
_EAX: code[1] := $18;
|
|
_ECX: code[1] := $19;
|
|
_EDX: code[1] := $1A;
|
|
_EBX: code[1] := $1B;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmFAdd;
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $DE;
|
|
code[1] := $C1;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmFSub;
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $DE;
|
|
code[1] := $E9;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmFMul;
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $DE;
|
|
code[1] := $C9;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmFDiv;
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $DE;
|
|
code[1] := $F9;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmFChs;
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $D9;
|
|
code[1] := $E0;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmFAbs;
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $D9;
|
|
code[1] := $E1;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmFCompP;
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $DE;
|
|
code[1] := $D9;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmFstsw_AX;
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $DF;
|
|
code[1] := $E0;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmSahv;
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 1;
|
|
code[0] := $9E;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmCDQ;
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 1;
|
|
code[0] := $99;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmSetL_REGPtr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $0F;
|
|
code[1] := $9C;
|
|
case Reg of
|
|
_EAX: code[2] := $00;
|
|
_ECX: code[2] := $01;
|
|
_EDX: code[2] := $02;
|
|
_EBX: code[2] := $03;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmSetLE_REGPtr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $0F;
|
|
code[1] := $9E;
|
|
case Reg of
|
|
_EAX: code[2] := $00;
|
|
_ECX: code[2] := $01;
|
|
_EDX: code[2] := $02;
|
|
_EBX: code[2] := $03;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmSetNLE_REGPtr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $0F;
|
|
code[1] := $9F;
|
|
case Reg of
|
|
_EAX: code[2] := $00;
|
|
_ECX: code[2] := $01;
|
|
_EDX: code[2] := $02;
|
|
_EBX: code[2] := $03;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmSetNL_REGPtr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $0F;
|
|
code[1] := $9D;
|
|
case Reg of
|
|
_EAX: code[2] := $00;
|
|
_ECX: code[2] := $01;
|
|
_EDX: code[2] := $02;
|
|
_EBX: code[2] := $03;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmSetB_REGPtr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $0F;
|
|
code[1] := $92;
|
|
case Reg of
|
|
_EAX: code[2] := $00;
|
|
_ECX: code[2] := $01;
|
|
_EDX: code[2] := $02;
|
|
_EBX: code[2] := $03;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmSet_REGPtr(ASM_OP, Reg: Integer; S: TSymbolRec);
|
|
var
|
|
shift: Integer;
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
shift := GetOffset(S);
|
|
|
|
Size := 7;
|
|
code[0] := $0F;
|
|
|
|
if ASM_OP = ASM_SETB then code[1] := $92
|
|
else if ASM_OP = ASM_SETNB then code[1] := $93
|
|
else if ASM_OP = ASM_SETZ then code[1] := $94
|
|
else if ASM_OP = ASM_SETNZ then code[1] := $95
|
|
else if ASM_OP = ASM_SETBE then code[1] := $96
|
|
else if ASM_OP = ASM_SETNBE then code[1] := $97
|
|
else if ASM_OP = ASM_SETL then code[1] := $9C
|
|
else if ASM_OP = ASM_SETNL then code[1] := $9D
|
|
else if ASM_OP = ASM_SETLE then code[1] := $9E
|
|
else if ASM_OP = ASM_SETNLE then code[1] := $9F
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
|
|
case Reg of
|
|
_EAX: code[2] := $80;
|
|
_ECX: code[2] := $81;
|
|
_EDX: code[2] := $82;
|
|
_EBX: code[2] := $83;
|
|
_EBP: code[2] := $85;
|
|
_ESI: code[2] := $86;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmSetBE_REGPtr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $0F;
|
|
code[1] := $96;
|
|
case Reg of
|
|
_EAX: code[2] := $00;
|
|
_ECX: code[2] := $01;
|
|
_EDX: code[2] := $02;
|
|
_EBX: code[2] := $03;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmSetNBE_REGPtr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $0F;
|
|
code[1] := $97;
|
|
case Reg of
|
|
_EAX: code[2] := $00;
|
|
_ECX: code[2] := $01;
|
|
_EDX: code[2] := $02;
|
|
_EBX: code[2] := $03;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmSetNB_REGPtr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $0F;
|
|
code[1] := $93;
|
|
case Reg of
|
|
_EAX: code[2] := $00;
|
|
_ECX: code[2] := $01;
|
|
_EDX: code[2] := $02;
|
|
_EBX: code[2] := $03;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmSetZ_REGPtr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $0F;
|
|
code[1] := $94;
|
|
case Reg of
|
|
_EAX: code[2] := $00;
|
|
_ECX: code[2] := $01;
|
|
_EDX: code[2] := $02;
|
|
_EBX: code[2] := $03;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmSetNZ_REGPtr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $0F;
|
|
code[1] := $95;
|
|
case Reg of
|
|
_EAX: code[2] := $00;
|
|
_ECX: code[2] := $01;
|
|
_EDX: code[2] := $02;
|
|
_EBX: code[2] := $03;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmFstpDouble_REGPtr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $DD;
|
|
case Reg of
|
|
_EAX: code[1] := $18;
|
|
_ECX: code[1] := $19;
|
|
_EDX: code[1] := $1A;
|
|
_EBX: code[1] := $1B;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmFstpSingle_REGPtr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $D9;
|
|
case Reg of
|
|
_EAX: code[1] := $18;
|
|
_ECX: code[1] := $19;
|
|
_EDX: code[1] := $1A;
|
|
_EBX: code[1] := $1B;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
// FStp TBYTE PTR [REG]
|
|
procedure TSymbolProg.AsmFstpExtended_REGPtr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $DB;
|
|
case Reg of
|
|
_EAX: code[1] := $38;
|
|
_ECX: code[1] := $39;
|
|
_EDX: code[1] := $3A;
|
|
_EBX: code[1] := $3B;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
// requires EmitGetAddressRegister
|
|
// FStp QWORD PTR [REG + Shift]
|
|
procedure TSymbolProg.AsmFstpDouble_REGPtr(Reg: Integer; S: TSymbolRec);
|
|
var
|
|
shift: Integer;
|
|
begin
|
|
shift := GetOffset(S);
|
|
if Reg in CommonRegisters then
|
|
Shift := 0;
|
|
|
|
if PAX64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 7;
|
|
code[0] := $48;
|
|
code[1] := $DD;
|
|
case Reg of
|
|
_EAX: code[2] := $98;
|
|
_ECX: code[2] := $99;
|
|
_EDX: code[2] := $9A;
|
|
_EBX: code[2] := $9B;
|
|
_EBP: code[2] := $9D;
|
|
_ESI: code[2] := $9E;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end
|
|
else
|
|
with AddRecord do
|
|
begin
|
|
Size := 6;
|
|
code[0] := $DD;
|
|
case Reg of
|
|
_EAX: code[1] := $98;
|
|
_ECX: code[1] := $99;
|
|
_EDX: code[1] := $9A;
|
|
_EBX: code[1] := $9B;
|
|
_EBP: code[1] := $9D;
|
|
_ESI: code[1] := $9E;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[2], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
// requires EmitGetAddressRegister
|
|
// FStp DWORD PTR [REG + Shift]
|
|
procedure TSymbolProg.AsmFstpSingle_REGPtr(Reg: Integer; S: TSymbolRec);
|
|
var
|
|
shift: Integer;
|
|
begin
|
|
shift := GetOffset(S);
|
|
if Reg in CommonRegisters then
|
|
Shift := 0;
|
|
|
|
with AddRecord do
|
|
begin
|
|
Size := 6;
|
|
code[0] := $D9;
|
|
case Reg of
|
|
_EAX: code[1] := $98;
|
|
_ECX: code[1] := $99;
|
|
_EDX: code[1] := $9A;
|
|
_EBX: code[1] := $9B;
|
|
_EBP: code[1] := $9D;
|
|
_ESI: code[1] := $9E;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[2], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
// requires EmitGetAddressRegister
|
|
// FStp TBYTE PTR [REG + Shift]
|
|
procedure TSymbolProg.AsmFstpExtended_REGPtr(Reg: Integer; S: TSymbolRec);
|
|
var
|
|
shift: Integer;
|
|
begin
|
|
shift := GetOffset(S);
|
|
if Reg in CommonRegisters then
|
|
Shift := 0;
|
|
|
|
if PAX64 then
|
|
with AddRecord do
|
|
begin
|
|
Size := 7;
|
|
code[0] := $48;
|
|
code[1] := $DB;
|
|
case Reg of
|
|
_EAX: code[2] := $B8;
|
|
_ECX: code[2] := $B9;
|
|
_EDX: code[2] := $BA;
|
|
_EBX: code[2] := $BB;
|
|
_EBP: code[2] := $BD;
|
|
_ESI: code[2] := $BE;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[3], 4);
|
|
Decompile;
|
|
end
|
|
else //32bit
|
|
with AddRecord do
|
|
begin
|
|
Size := 6;
|
|
code[0] := $DB;
|
|
case Reg of
|
|
_EAX: code[1] := $B8;
|
|
_ECX: code[1] := $B9;
|
|
_EDX: code[1] := $BA;
|
|
_EBX: code[1] := $BB;
|
|
_EBP: code[1] := $BD;
|
|
_ESI: code[1] := $BE;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Move(shift, code[2], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmCmpByteREGPtr_Imm(Reg: Integer; value: Byte);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $80;
|
|
case Reg of
|
|
_EAX: code[1] := $38;
|
|
_ECX: code[1] := $39;
|
|
_EDX: code[1] := $3A;
|
|
_EBX: code[1] := $3B;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
code[2] := value;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
function TSymbolProg.AsmJmp_REG(Reg: Integer): TSymbolProgRec;
|
|
begin
|
|
result := AddRecord;
|
|
with result do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $FF;
|
|
case Reg of
|
|
_EAX: code[1] := $E0;
|
|
_ECX: code[1] := $E1;
|
|
_EDX: code[1] := $E2;
|
|
_EBX: code[1] := $E3;
|
|
else
|
|
begin
|
|
if Reg in [_R8.._R15] then
|
|
begin
|
|
Size := 3;
|
|
code[0] := $49;
|
|
code[1] := $FF;
|
|
case Reg of
|
|
_R8: code[2] := $E0;
|
|
_R9: code[2] := $E1;
|
|
_R10: code[2] := $E2;
|
|
_R11: code[2] := $E3;
|
|
_R12: code[2] := $E4;
|
|
_R13: code[2] := $E5;
|
|
_R14: code[2] := $E6;
|
|
_R15: code[2] := $E7;
|
|
end;
|
|
end
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmCall_REG(Reg: Integer);
|
|
begin
|
|
if PAX64 then
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $48;
|
|
code[1] := $FF;
|
|
case Reg of
|
|
_EAX: code[2] := $D0;
|
|
_ECX: code[2] := $D1;
|
|
_EDX: code[2] := $D2;
|
|
_EBX: code[2] := $D3;
|
|
_ESP: code[2] := $D4;
|
|
_EBP: code[2] := $D5;
|
|
_ESI: code[2] := $D6;
|
|
_EDI: code[2] := $D7;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end
|
|
else
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $FF;
|
|
case Reg of
|
|
_EAX: code[1] := $D0;
|
|
_ECX: code[1] := $D1;
|
|
_EDX: code[1] := $D2;
|
|
_EBX: code[1] := $D3;
|
|
_ESP: code[1] := $D4;
|
|
_EBP: code[1] := $D5;
|
|
_ESI: code[1] := $D6;
|
|
_EDI: code[1] := $D7;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmPush_Imm(value: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 5;
|
|
code[0] := $68;
|
|
Move(value, code[1], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
function TSymbolProg.AsmPush_REG(Reg: Integer): TSymbolProgRec;
|
|
begin
|
|
result := AddRecord;
|
|
if Reg in R64 then
|
|
with result do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $41;
|
|
case Reg of
|
|
_R8: code[1] := $50;
|
|
_R9: code[1] := $51;
|
|
_R10: code[1] := $52;
|
|
_R11: code[1] := $53;
|
|
_R12: code[1] := $54;
|
|
_R13: code[1] := $55;
|
|
_R14: code[1] := $56;
|
|
_R15: code[1] := $57;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end
|
|
else
|
|
with result do
|
|
begin
|
|
Size := 1;
|
|
case Reg of
|
|
_EAX: code[0] := $50;
|
|
_ECX: code[0] := $51;
|
|
_EDX: code[0] := $52;
|
|
_EBX: code[0] := $53;
|
|
_ESP: code[0] := $54;
|
|
_EBP: code[0] := $55;
|
|
_ESI: code[0] := $56;
|
|
_EDI: code[0] := $57;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
function TSymbolProg.AsmPop_REG(Reg: Integer): TSymbolProgRec;
|
|
begin
|
|
result := AddRecord;
|
|
if Reg in R64 then
|
|
with result do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $41;
|
|
case Reg of
|
|
_R8: code[1] := $58;
|
|
_R9: code[1] := $59;
|
|
_R10: code[1] := $5A;
|
|
_R11: code[1] := $5B;
|
|
_R12: code[1] := $5C;
|
|
_R13: code[1] := $5D;
|
|
_R14: code[1] := $5E;
|
|
_R15: code[1] := $5F;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end
|
|
else
|
|
with result do
|
|
begin
|
|
Size := 1;
|
|
case Reg of
|
|
_EAX: code[0] := $58;
|
|
_ECX: code[0] := $59;
|
|
_EDX: code[0] := $5A;
|
|
_EBX: code[0] := $5B;
|
|
_ESP: code[0] := $5C;
|
|
_EBP: code[0] := $5D;
|
|
_ESI: code[0] := $5E;
|
|
_EDI: code[0] := $5F;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmPush_REGPtr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $FF;
|
|
case Reg of
|
|
_EAX: code[1] := $30;
|
|
_ECX: code[1] := $31;
|
|
_EDX: code[1] := $32;
|
|
_EBX: code[1] := $33;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmPush_FS_REGPtr(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 3;
|
|
code[0] := $64;
|
|
code[1] := $FF;
|
|
case Reg of
|
|
_EAX: code[2] := $30;
|
|
_ECX: code[2] := $31;
|
|
_EDX: code[2] := $32;
|
|
_EBX: code[2] := $33;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmPush_Reg16(Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $66;
|
|
case Reg of
|
|
_EAX: code[1] := $50;
|
|
_ECX: code[1] := $51;
|
|
_EDX: code[1] := $52;
|
|
_EBX: code[1] := $53;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmRet(value: Word = 0);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
if value = 0 then
|
|
begin
|
|
Size := 1;
|
|
code[0] := $c3;
|
|
end
|
|
else
|
|
begin
|
|
Size := 3;
|
|
code[0] := $c2;
|
|
Move(value, code[1], 2);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmNop;
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 1;
|
|
code[0] := $90;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmWait;
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 1;
|
|
code[0] := $9B;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmClc;
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 1;
|
|
code[0] := $F8;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmPushfd;
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 1;
|
|
code[0] := $9C;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmPopfd;
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 1;
|
|
code[0] := $9D;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmXCHG(Reg1, Reg2: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
if Reg2 = _EAX then
|
|
begin
|
|
Reg2 := Reg1;
|
|
Reg1 := _EAX;
|
|
end;
|
|
|
|
if Reg1 = _EAX then
|
|
begin
|
|
Size := 1;
|
|
case Reg2 of
|
|
_EAX: code[0] := $90; // nop
|
|
_ECX: code[0] := $91;
|
|
_EDX: code[0] := $92;
|
|
_EBX: code[0] := $93;
|
|
_ESP: code[0] := $94;
|
|
_EBP: code[0] := $95;
|
|
_ESI: code[0] := $96;
|
|
_EDI: code[0] := $97;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
end
|
|
else if Reg1 = _ECX then
|
|
begin
|
|
Size := 2;
|
|
code[0] := $87;
|
|
case Reg2 of
|
|
_ECX: code[1] := $C9;
|
|
_EDX: code[1] := $CA;
|
|
_EBX: code[1] := $CB;
|
|
_ESP: code[1] := $CC;
|
|
_EBP: code[1] := $CD;
|
|
_ESI: code[1] := $CE;
|
|
_EDI: code[1] := $CF;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
end
|
|
else if Reg1 = _EDX then
|
|
begin
|
|
Size := 2;
|
|
code[0] := $87;
|
|
case Reg2 of
|
|
_ECX: code[1] := $D1;
|
|
_EDX: code[1] := $D2;
|
|
_EBX: code[1] := $D3;
|
|
_ESP: code[1] := $D4;
|
|
_EBP: code[1] := $D5;
|
|
_ESI: code[1] := $D6;
|
|
_EDI: code[1] := $D7;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
end
|
|
else if Reg1 = _EBX then
|
|
begin
|
|
Size := 2;
|
|
code[0] := $87;
|
|
case Reg2 of
|
|
_ECX: code[1] := $D9;
|
|
_EDX: code[1] := $DA;
|
|
_EBX: code[1] := $DB;
|
|
_ESP: code[1] := $DC;
|
|
_EBP: code[1] := $DD;
|
|
_ESI: code[1] := $DE;
|
|
_EDI: code[1] := $DF;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
end
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmJMP_Imm(value: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 5;
|
|
code[0] := $E9;
|
|
Move(value, code[1], 4);
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmJNO_Imm(value: Byte);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $71;
|
|
code[1] := value;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmJNC_Imm(value: Byte);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $73;
|
|
code[1] := value;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmJZ_Imm(value: SmallInt);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $74;
|
|
code[1] := value;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmJNZ_Imm(value: SmallInt);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $75;
|
|
code[1] := value;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmJBE_Imm(value: Byte);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $76;
|
|
code[1] := value;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmJNLE_Imm(value: Byte);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $7F;
|
|
code[1] := value;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TSymbolProg.AsmRep_MOVSB;
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $F3;
|
|
code[1] := $A4;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmRep_MOVSD;
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 2;
|
|
code[0] := $F3;
|
|
code[1] := $A5;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmCvtsd2ssXMM_RegPtr(XMMReg, Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 4;
|
|
code[0] := $F2;
|
|
code[1] := $0F;
|
|
code[2] := $5A;
|
|
case XMMReg of
|
|
_XMM0:
|
|
case Reg of
|
|
_EAX: code[3] := $00;
|
|
_ECX: code[3] := $01;
|
|
_EDX: code[3] := $02;
|
|
_EBX: code[3] := $03;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_XMM1:
|
|
case Reg of
|
|
_EAX: code[3] := $08;
|
|
_ECX: code[3] := $09;
|
|
_EDX: code[3] := $0A;
|
|
_EBX: code[3] := $0B;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_XMM2:
|
|
case Reg of
|
|
_EAX: code[3] := $10;
|
|
_ECX: code[3] := $11;
|
|
_EDX: code[3] := $12;
|
|
_EBX: code[3] := $13;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_XMM3:
|
|
case Reg of
|
|
_EAX: code[3] := $18;
|
|
_ECX: code[3] := $19;
|
|
_EDX: code[3] := $1A;
|
|
_EBX: code[3] := $1B;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_XMM4:
|
|
case Reg of
|
|
_EAX: code[3] := $20;
|
|
_ECX: code[3] := $21;
|
|
_EDX: code[3] := $22;
|
|
_EBX: code[3] := $23;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmCvtss2sdXMM_RegPtr(XMMReg, Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 4;
|
|
code[0] := $F3;
|
|
code[1] := $0F;
|
|
code[2] := $5A;
|
|
case XMMReg of
|
|
_XMM0:
|
|
case Reg of
|
|
_EAX: code[3] := $00;
|
|
_ECX: code[3] := $01;
|
|
_EDX: code[3] := $02;
|
|
_EBX: code[3] := $03;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_XMM1:
|
|
case Reg of
|
|
_EAX: code[3] := $08;
|
|
_ECX: code[3] := $09;
|
|
_EDX: code[3] := $0A;
|
|
_EBX: code[3] := $0B;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_XMM2:
|
|
case Reg of
|
|
_EAX: code[3] := $10;
|
|
_ECX: code[3] := $11;
|
|
_EDX: code[3] := $12;
|
|
_EBX: code[3] := $13;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_XMM3:
|
|
case Reg of
|
|
_EAX: code[3] := $18;
|
|
_ECX: code[3] := $19;
|
|
_EDX: code[3] := $1A;
|
|
_EBX: code[3] := $1B;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_XMM4:
|
|
case Reg of
|
|
_EAX: code[3] := $20;
|
|
_ECX: code[3] := $21;
|
|
_EDX: code[3] := $22;
|
|
_EBX: code[3] := $23;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmMovsdXMM_RegPtr(XMMReg, Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 6;
|
|
code[0] := $67;
|
|
code[1] := $F2;
|
|
code[2] := $48;
|
|
code[3] := $0F;
|
|
code[4] := $10;
|
|
case XMMReg of
|
|
_XMM0:
|
|
case Reg of
|
|
_EAX: code[5] := $00;
|
|
_ECX: code[5] := $01;
|
|
_EDX: code[5] := $02;
|
|
_EBX: code[5] := $03;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_XMM1:
|
|
case Reg of
|
|
_EAX: code[5] := $08;
|
|
_ECX: code[5] := $09;
|
|
_EDX: code[5] := $0A;
|
|
_EBX: code[5] := $0B;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_XMM2:
|
|
case Reg of
|
|
_EAX: code[5] := $10;
|
|
_ECX: code[5] := $11;
|
|
_EDX: code[5] := $12;
|
|
_EBX: code[5] := $13;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_XMM3:
|
|
case Reg of
|
|
_EAX: code[5] := $18;
|
|
_ECX: code[5] := $19;
|
|
_EDX: code[5] := $1A;
|
|
_EBX: code[5] := $1B;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_XMM4:
|
|
case Reg of
|
|
_EAX: code[5] := $20;
|
|
_ECX: code[5] := $21;
|
|
_EDX: code[5] := $22;
|
|
_EBX: code[5] := $23;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmMovsdRegPtr_XMM(XMMReg, Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 6;
|
|
code[0] := $67;
|
|
code[1] := $F2;
|
|
code[2] := $48;
|
|
code[3] := $0F;
|
|
code[4] := $11;
|
|
case XMMReg of
|
|
_XMM0:
|
|
case Reg of
|
|
_EAX: code[5] := $00;
|
|
_ECX: code[5] := $01;
|
|
_EDX: code[5] := $02;
|
|
_EBX: code[5] := $03;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_XMM1:
|
|
case Reg of
|
|
_EAX: code[5] := $08;
|
|
_ECX: code[5] := $09;
|
|
_EDX: code[5] := $0A;
|
|
_EBX: code[5] := $0B;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_XMM2:
|
|
case Reg of
|
|
_EAX: code[5] := $10;
|
|
_ECX: code[5] := $11;
|
|
_EDX: code[5] := $12;
|
|
_EBX: code[5] := $13;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_XMM3:
|
|
case Reg of
|
|
_EAX: code[5] := $18;
|
|
_ECX: code[5] := $19;
|
|
_EDX: code[5] := $1A;
|
|
_EBX: code[5] := $1B;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_XMM4:
|
|
case Reg of
|
|
_EAX: code[5] := $20;
|
|
_ECX: code[5] := $21;
|
|
_EDX: code[5] := $22;
|
|
_EBX: code[5] := $23;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmMovssXMM_RegPtr(XMMReg, Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 5;
|
|
code[0] := $67;
|
|
code[1] := $F3;
|
|
code[2] := $0F;
|
|
code[3] := $10;
|
|
case XMMReg of
|
|
_XMM0:
|
|
case Reg of
|
|
_EAX: code[4] := $00;
|
|
_ECX: code[4] := $01;
|
|
_EDX: code[4] := $02;
|
|
_EBX: code[4] := $03;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_XMM1:
|
|
case Reg of
|
|
_EAX: code[4] := $08;
|
|
_ECX: code[4] := $09;
|
|
_EDX: code[4] := $0A;
|
|
_EBX: code[4] := $0B;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_XMM2:
|
|
case Reg of
|
|
_EAX: code[4] := $10;
|
|
_ECX: code[4] := $11;
|
|
_EDX: code[4] := $12;
|
|
_EBX: code[4] := $13;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_XMM3:
|
|
case Reg of
|
|
_EAX: code[4] := $18;
|
|
_ECX: code[4] := $19;
|
|
_EDX: code[4] := $1A;
|
|
_EBX: code[4] := $1B;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_XMM4:
|
|
case Reg of
|
|
_EAX: code[4] := $20;
|
|
_ECX: code[4] := $21;
|
|
_EDX: code[4] := $22;
|
|
_EBX: code[4] := $23;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.AsmMovssRegPtr_XMM(XMMReg, Reg: Integer);
|
|
begin
|
|
with AddRecord do
|
|
begin
|
|
Size := 5;
|
|
code[0] := $67;
|
|
code[1] := $F3;
|
|
code[2] := $0F;
|
|
code[3] := $11;
|
|
case XMMReg of
|
|
_XMM0:
|
|
case Reg of
|
|
_EAX: code[4] := $00;
|
|
_ECX: code[4] := $01;
|
|
_EDX: code[4] := $02;
|
|
_EBX: code[4] := $03;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_XMM1:
|
|
case Reg of
|
|
_EAX: code[4] := $08;
|
|
_ECX: code[4] := $09;
|
|
_EDX: code[4] := $0A;
|
|
_EBX: code[4] := $0B;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_XMM2:
|
|
case Reg of
|
|
_EAX: code[4] := $10;
|
|
_ECX: code[4] := $11;
|
|
_EDX: code[4] := $12;
|
|
_EBX: code[4] := $13;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_XMM3:
|
|
case Reg of
|
|
_EAX: code[4] := $18;
|
|
_ECX: code[4] := $19;
|
|
_EDX: code[4] := $1A;
|
|
_EBX: code[4] := $1B;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
_XMM4:
|
|
case Reg of
|
|
_EAX: code[4] := $20;
|
|
_ECX: code[4] := $21;
|
|
_EDX: code[4] := $22;
|
|
_EBX: code[4] := $23;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
else
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
Decompile;
|
|
end;
|
|
end;
|
|
|
|
|
|
function TSymbolProg.GetRecord(I: Integer): TSymbolProgRec;
|
|
begin
|
|
result := TSymbolProgRec(L[I - 1]);
|
|
end;
|
|
|
|
procedure TSymbolProg.Optimization;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I:= 1 to Card - 2 do
|
|
if Records[I].Op = ASM_MOV then
|
|
begin
|
|
|
|
if Records[I + 1].Op = ASM_MOV then
|
|
begin
|
|
if EqualArgs(Records[I].Arg1, Records[I+1].Arg2) and
|
|
EqualArgs(Records[I].Arg2, Records[I+1].Arg1) then
|
|
begin
|
|
Records[I+1].Size := 0;
|
|
end;
|
|
end
|
|
else if (Records[I + 2].Op = ASM_MOV) and (Records[I + 1].Size < 0) then
|
|
begin
|
|
if EqualArgs(Records[I].Arg1, Records[I+2].Arg2) and
|
|
EqualArgs(Records[I].Arg2, Records[I+2].Arg1) then
|
|
begin
|
|
Records[I+2].Size := -1;
|
|
end;
|
|
end
|
|
end;
|
|
|
|
for I:=Card downto 1 do
|
|
if Records[I].Size = 0 then
|
|
Delete(I);
|
|
end;
|
|
|
|
procedure TSymbolProg.CreateProgramSimple(result: TProgram);
|
|
var
|
|
I, N, SZ: Integer;
|
|
begin
|
|
result.AllocateSimple(ProgSize, 0);
|
|
N := 0;
|
|
for I:=1 to Card do
|
|
begin
|
|
SZ := Records[I].Size;
|
|
if SZ >= 0 then
|
|
begin
|
|
Move(Records[I].code, result.CodePtr^[N], SZ);
|
|
Inc(N, SZ);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.CreateProgram(result: TProgram; IsEval: Boolean = false);
|
|
var
|
|
I, J, K, N, SZ: Integer;
|
|
SymbolTable: TSymbolTable;
|
|
Shift: Integer;
|
|
ProgOffset: Integer;
|
|
|
|
Code: TCode;
|
|
OP: Integer;
|
|
ID: Integer;
|
|
TryRec: TTryRec;
|
|
ClsIndex: Integer;
|
|
ClassRec: TClassRec;
|
|
DestructorId,
|
|
AfterConstructionId,
|
|
BeforeDestructionId,
|
|
SafeCallExceptionId,
|
|
DispatchId,
|
|
DefaultHandlerId,
|
|
NewInstanceId,
|
|
ToStringId,
|
|
FreeInstanceId : Integer;
|
|
RR: TSymbolRec;
|
|
temp: Boolean;
|
|
IntfId: Integer;
|
|
InterfaceMethodIds: TIntegerList;
|
|
ClassMethodIds: TIntegerList;
|
|
IntfRec: TIntfRec;
|
|
|
|
UpdatedProgSize, LastCard, NN: Integer;
|
|
PaxInfo: PPaxInfo;
|
|
PaxFactoryRec: TPaxClassFactoryRec;
|
|
SS: String;
|
|
InterfaceToObjectOffset: Integer;
|
|
RegX, RegY: Integer;
|
|
N1, N2: Integer;
|
|
MR: TMapRec;
|
|
begin
|
|
SymbolTable := TKernel(kernel).SymbolTable;
|
|
Code := TKernel(kernel).Code;
|
|
|
|
if TKernel(kernel).SignCompression then
|
|
SZ := TKernel(kernel).OffsetList.GetSize
|
|
else
|
|
SZ := SymbolTable.GetDataSize + 4096;
|
|
|
|
temp := result.UseMapping;
|
|
result.UseMapping := false;
|
|
result.Allocate(ProgSize, SZ);
|
|
result.UseMapping := temp;
|
|
|
|
N := 0;
|
|
N1 := 0;
|
|
for I:=1 to Card do
|
|
begin
|
|
SZ := Records[I].Size;
|
|
if SZ >= 0 then
|
|
begin
|
|
Records[I].ProgOffset := N;
|
|
|
|
Move(Records[I].code, result.CodePtr^[N], SZ);
|
|
Inc(N, SZ);
|
|
end
|
|
else if Records[I].MapSub < 0 then
|
|
begin
|
|
N1 := N;
|
|
end
|
|
else if Records[I].MapSub > 0 then
|
|
begin
|
|
N2 := N;
|
|
MR := result.ScriptMapTable.LookupSub(Records[I].MapSub);
|
|
if MR <> nil then
|
|
MR.SubDesc.SubSize := N2 - N1;
|
|
end;
|
|
end;
|
|
|
|
LastCard := Card;
|
|
NN := N;
|
|
UpdatedProgSize := ProgSize;
|
|
|
|
TKernel(kernel).AllocateConstants(result.ResultPtr);
|
|
|
|
with SymbolTable do
|
|
for I:=FirstLocalId + 1 to Card do
|
|
if Records[I].Host then
|
|
begin
|
|
RR := SymbolTable[I];
|
|
|
|
if RR.Address <> nil then
|
|
begin
|
|
if not InCode[I] then
|
|
continue;
|
|
|
|
if not TKernel(kernel).ExistsOffset(RR) then
|
|
begin
|
|
continue;
|
|
end;
|
|
|
|
result.SetAddress(GetOffset(RR), RR.Address);
|
|
end
|
|
else if RR.ClassIndex <> -1 then
|
|
begin
|
|
RR := SymbolTable[I + 1]; // cls ref
|
|
J := RR.Value;
|
|
if J = 0 then
|
|
begin
|
|
ClassRec := result.ClassList.Add(SymbolTable[I].FullName, SymbolTable[I].Host);
|
|
ClassRec.InstSize := SizeOfPointer;
|
|
end
|
|
else
|
|
begin
|
|
ClassRec := result.RegisterClass(TClass(Pointer(J)), SymbolTable[I].FullName, GetOffset(RR));
|
|
ClassRec.InstSize := TClass(Pointer(J)).InstanceSize;
|
|
end;
|
|
ClassRec.ParentFullName := Records[Records[I].AncestorId].FullName;
|
|
end;
|
|
end
|
|
else
|
|
if Records[I].ClassIndex > 0 then
|
|
begin
|
|
ClassRec := result.ClassList.Add(Records[I].FullName, Records[I].Host);
|
|
ClassRec.Host := false;
|
|
ClassRec.Offset := GetOffset(Records[I + 1]);
|
|
ClassRec.SizeOfScriptClassFields := Records[I].GetSizeOfScriptClassFields;
|
|
|
|
ClassRec.PClass := TClass(IntPax(Records[I + 1].Value));
|
|
ClassRec.ParentFullName := Records[Records[I].AncestorId].FullName;
|
|
|
|
DestructorId := FindDestructorId(I);
|
|
if DestructorId > 0 then
|
|
ClassRec.DestructorProgOffset := Records[DestructorId].Value;
|
|
|
|
SafeCallExceptionId := Lookup('SafeCallException', I, true);
|
|
if SafeCallExceptionId > 0 then
|
|
ClassRec.SafeCallExceptionProgOffset := Records[SafeCallExceptionId].Value;
|
|
|
|
AfterConstructionId := Lookup('AfterConstruction', I, true);
|
|
if AfterConstructionId > 0 then
|
|
ClassRec.AfterConstructionProgOffset := Records[AfterConstructionId].Value;
|
|
|
|
BeforeDestructionId := Lookup('BeforeDestruction', I, true);
|
|
if BeforeDestructionId > 0 then
|
|
ClassRec.BeforeDestructionProgOffset := Records[BeforeDestructionId].Value;
|
|
|
|
DispatchId := Lookup('Dispatch', I, true);
|
|
if DispatchId > 0 then
|
|
ClassRec.DispatchProgOffset := Records[DispatchId].Value;
|
|
|
|
DefaultHandlerId := Lookup('DefaultHandler', I, true);
|
|
if DefaultHandlerId > 0 then
|
|
ClassRec.DefaultHandlerProgOffset := Records[DefaultHandlerId].Value;
|
|
|
|
NewInstanceId := Lookup('NewInstance', I, true);
|
|
if NewInstanceId > 0 then
|
|
ClassRec.NewInstanceProgOffset := Records[NewInstanceId].Value;
|
|
|
|
FreeInstanceId := Lookup('FreeInstance', I, true);
|
|
if FreeInstanceId > 0 then
|
|
ClassRec.FreeInstanceProgOffset := Records[FreeInstanceId].Value;
|
|
|
|
{$IFDEF UNIC}
|
|
ToStringId := Lookup('ToString', I, true);
|
|
if ToStringId > 0 then
|
|
ClassRec.ToStringProgOffset := Records[ToStringId].Value;
|
|
{$ENDIF}
|
|
|
|
PaxInfo := GetPaxInfo(ClassRec.PClass);
|
|
if PaxInfo = nil then
|
|
RaiseError(errInternalError, []);
|
|
|
|
if not IsEval then
|
|
begin
|
|
PaxInfo^.Prog := result;
|
|
PaxInfo^.ClassIndex := Records[I].ClassIndex;
|
|
end;
|
|
|
|
PaxFactoryRec := TKernel(kernel).ClassFactory.FindRecord(ClassRec.PClass);
|
|
if PaxFactoryRec = nil then
|
|
RaiseError(errInternalError, []);
|
|
|
|
if Records[I].SupportedInterfaces = nil then
|
|
begin
|
|
ClassRec.InstSize := Records[I].GetSizeOfAllClassFields(result);
|
|
Inc(ClassRec.InstSize, SizeOf(Pointer)); // add monitor space
|
|
PaxFactoryRec.SetInstanceSize(ClassRec.InstSize);
|
|
continue;
|
|
end
|
|
else
|
|
begin
|
|
ClassRec.InstSize := Records[I].GetSizeOfAllClassFields(result) +
|
|
Records[I].SupportedInterfaces.Count * SizeOfPointer;
|
|
Inc(ClassRec.InstSize, SizeOf(Pointer)); // add monitor space
|
|
PaxFactoryRec.SetInstanceSize(ClassRec.InstSize);
|
|
end;
|
|
|
|
if Records[I].SupportedInterfaces.Count = 0 then
|
|
continue;
|
|
|
|
InterfaceMethodIds := TIntegerList.Create;
|
|
ClassMethodIds := TIntegerList.Create;
|
|
try
|
|
for J:=0 to Records[I].SupportedInterfaces.Count - 1 do
|
|
begin
|
|
|
|
IntfId := Records[I].SupportedInterfaces[J].Id;
|
|
CreateInterfaceMethodList(I, IntfId,
|
|
InterfaceMethodIds,
|
|
ClassMethodIds);
|
|
if (not Records[I].IsAbstract) and (InterfaceMethodIds.Count > 0) then // some methods not found
|
|
begin
|
|
for K:=0 to InterfaceMethodIds.Count - 1 do
|
|
begin
|
|
Code.N := Code.FindRecord1(OP_END_CLASS_TYPE, I);
|
|
CreateError(errUndeclaredIdentifier,
|
|
[Records[InterfaceMethodIds[K]].Name]);
|
|
end;
|
|
break;
|
|
end
|
|
else
|
|
begin
|
|
InterfaceToObjectOffset :=
|
|
-Records[I].GetSizeOfAllClassFields(result) + J * SizeOfPointer;
|
|
|
|
IntfRec := ClassRec.IntfList.Add;
|
|
IntfRec.GUID := Records[I].SupportedInterfaces[J].GUID;
|
|
for K:=0 to ClassMethodIds.Count - 1 do
|
|
begin
|
|
Id := ClassMethodIds[K];
|
|
|
|
IntfRec.IntfMethods.AddMethod(Records[Id].FullName,
|
|
UpdatedProgSize,
|
|
InterfaceToObjectOffset);
|
|
Inc(UpdatedProgSize, EmitZ);
|
|
|
|
{$IFDEF PAX64}
|
|
RegX := _R10;
|
|
RegY := _R11;
|
|
{$ELSE}
|
|
if Records[Id].Host then
|
|
RegX := _EDI
|
|
else
|
|
RegX := _ESI;
|
|
RegY := _EBX;
|
|
{$ENDIF}
|
|
|
|
if Records[Id].CallConv in [ccSTDCALL, ccCDECL, ccPASCAL, ccSAFECALL] then
|
|
begin
|
|
if Records[Id].ExtraParamNeeded then
|
|
Inc(UpdatedProgSize, AsmPop_REG(RegX).Size);
|
|
|
|
Inc(UpdatedProgSize, AsmPop_REG(RegY).Size);
|
|
Inc(UpdatedProgSize, AsmPop_REG(_EAX).Size);
|
|
end;
|
|
|
|
if PAX64 then
|
|
Inc(UpdatedProgSize, AsmAddREG_Imm(_ECX, InterfaceToObjectOffset).Size)
|
|
else
|
|
Inc(UpdatedProgSize, AsmAddREG_Imm(_EAX, InterfaceToObjectOffset).Size);
|
|
// EAX contains instance of object
|
|
|
|
if Records[Id].CallConv in [ccSTDCALL, ccCDECL, ccPASCAL, ccSAFECALL] then
|
|
begin
|
|
Inc(UpdatedProgSize, AsmPush_REG(_EAX).Size);
|
|
Inc(UpdatedProgSize, AsmPush_REG(RegY).Size);
|
|
if Records[Id].ExtraParamNeeded then
|
|
Inc(UpdatedProgSize, AsmPush_REG(RegX).Size);
|
|
end;
|
|
|
|
// jump to address
|
|
|
|
if Records[Id].Host then
|
|
begin
|
|
Inc(UpdatedProgSize, AsmGetREG_ESIPtr(RegY, GetOffset(Records[Id])).Size);
|
|
end
|
|
else
|
|
begin
|
|
Inc(UpdatedProgSize, AsmMovREG_REG(RegY, _EDI).Size);
|
|
Inc(UpdatedProgSize, AsmAddREG_Imm(RegY, Records[Id].Value).Size);
|
|
end;
|
|
Inc(UpdatedProgSize, AsmJMP_REG(RegY).Size);
|
|
end;
|
|
end;
|
|
end;
|
|
finally
|
|
FreeAndNil(InterfaceMethodIds);
|
|
FreeAndNil(ClassMethodIds);
|
|
end;
|
|
end;
|
|
|
|
result.Reallocate(UpdatedProgSize);
|
|
|
|
for I:= LastCard + 1 to Card do
|
|
begin
|
|
SZ := Records[I].Size;
|
|
if SZ >= 0 then
|
|
begin
|
|
Records[I].ProgOffset := NN;
|
|
|
|
Move(Records[I].code, result.CodePtr^[NN], SZ);
|
|
Inc(NN, SZ);
|
|
end;
|
|
end;
|
|
|
|
result.TryList.Clear;
|
|
result.RootTryStack.Clear;
|
|
|
|
for I:=1 to Code.Card do
|
|
if Code[I].Op = OP_TRY_ON then
|
|
begin
|
|
TryRec := result.TryList.Add;
|
|
TryRec.Level := Code[I].Res;
|
|
|
|
for J := I + 1 to Code.Card do
|
|
begin
|
|
Op := Code[J].Op;
|
|
if OP = OP_FINALLY then
|
|
begin
|
|
if Code[J].Arg1 = Code[I].Arg1 then
|
|
begin
|
|
TryRec.TryKind := tryFinally;
|
|
ID := Code[J].Arg2;
|
|
TryRec.ProgOffset := SymbolTable[ID].Value;
|
|
break;
|
|
end;
|
|
end
|
|
else if OP = OP_EXCEPT then
|
|
begin
|
|
if Code[J].Arg1 = Code[I].Arg1 then
|
|
begin
|
|
TryRec.TryKind := tryExcept;
|
|
ID := Code[J].Arg2;
|
|
TryRec.ProgOffset := SymbolTable[ID].Value;
|
|
break;
|
|
end;
|
|
end
|
|
else if OP = OP_TRY_OFF then
|
|
begin
|
|
if Code[J].Arg1 = Code[I].Arg1 then
|
|
begin
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
for I:=1 to Code.Card do
|
|
begin
|
|
OP := Code[I].Op;
|
|
if OP = OP_FINALLY then
|
|
begin
|
|
ID := Code[I].Arg2;
|
|
ProgOffset := SymbolTable[ID].Value;
|
|
|
|
TryRec := result.TryList[Code[I].Arg1];
|
|
|
|
TryRec.TryKind := tryFinally;
|
|
TryRec._ESP := 0; // will be determined at run-time
|
|
TryRec._EBP := 0; // will be determined at run-time
|
|
TryRec.ProgOffset := ProgOffset;
|
|
|
|
TryRec.N := I;
|
|
|
|
if (Code[I].BreakLabel > 0) and (Code[I].ContinueLabel > 0) then
|
|
begin
|
|
Id := Code[I].BreakLabel;
|
|
TryRec.BreakOffset := SymbolTable[ID].Value;
|
|
|
|
Id := Code[I].ContinueLabel;
|
|
TryRec.ContinueOffset := SymbolTable[ID].Value;
|
|
|
|
Id := Code[I].LoopLabel;
|
|
N1 := SymbolTable[ID].Value; // begin loop offset
|
|
N2 := TryRec.BreakOffset; // break offset (end loop offset)
|
|
for J := Code[I].Arg1 - 1 downto 0 do
|
|
if result.TryList[J].TryKind = tryFinally then
|
|
begin
|
|
if result.TryList[J].ProgOffset >= N1 then
|
|
if result.TryList[J].ProgOffset <= N2 then
|
|
begin
|
|
TryRec.BreakOffset := 0;
|
|
TryRec.ContinueOffset := 0;
|
|
end;
|
|
end;
|
|
end;
|
|
end
|
|
else if OP = OP_EXCEPT then
|
|
begin
|
|
ID := Code[I].Arg2;
|
|
ProgOffset := SymbolTable[ID].Value;
|
|
|
|
TryRec := result.TryList[Code[I].Arg1];
|
|
|
|
TryRec.TryKind := tryExcept;
|
|
TryRec._ESP := 0; // will be determined at run-time
|
|
TryRec._EBP := 0; // will be determined at run-time
|
|
TryRec.ProgOffset := ProgOffset;
|
|
|
|
TryRec.N := I;
|
|
|
|
if (Code[I].BreakLabel > 0) and (Code[I].ContinueLabel > 0) then
|
|
begin
|
|
Id := Code[I].BreakLabel;
|
|
TryRec.BreakOffset := SymbolTable[ID].Value;
|
|
|
|
Id := Code[I].ContinueLabel;
|
|
TryRec.ContinueOffset := SymbolTable[ID].Value;
|
|
|
|
Id := Code[I].LoopLabel;
|
|
N1 := SymbolTable[ID].Value; // begin loop offset
|
|
N2 := TryRec.BreakOffset; // break offset (end loop offset)
|
|
for J := Code[I].Arg1 - 1 downto 0 do
|
|
if result.TryList[J].TryKind = tryFinally then
|
|
begin
|
|
if result.TryList[J].ProgOffset >= N1 then
|
|
if result.TryList[J].ProgOffset <= N2 then
|
|
begin
|
|
TryRec.BreakOffset := result.TryList[J].ProgOffset;
|
|
TryRec.ContinueOffset := result.TryList[J].ProgOffset;
|
|
end;
|
|
end;
|
|
end;
|
|
end
|
|
else if OP = OP_EXCEPT_ON then
|
|
begin
|
|
ID := Code[I].Arg2;
|
|
ProgOffset := SymbolTable[ID].Value;
|
|
|
|
TryRec := result.TryList[Code[I].Arg1];
|
|
|
|
if Code[I].Res = 0 then
|
|
ClsIndex := -1 // else part
|
|
else
|
|
begin
|
|
ID := SymbolTable[Code[I].Res].TerminalTypeId;
|
|
ClsIndex := SymbolTable[ID].ClassIndex;
|
|
|
|
if ClsIndex <= 0 then
|
|
RaiseError(errInternalError, []);
|
|
end;
|
|
|
|
TryRec.ExceptOnInfo.Add(ClsIndex, ProgOffset);
|
|
|
|
TryRec.N := I;
|
|
end;
|
|
end;
|
|
|
|
TKernel(kernel).CreateRTI(result);
|
|
CreateZList(result);
|
|
|
|
if not IsEval then
|
|
begin
|
|
SymbolTable.ProcessClassFactory(Tkernel(kernel).ClassFactory, result);
|
|
TKernel(kernel).ClassFactory.SetupStdVirtuals(result.ClassList, result.CodePtr);
|
|
result.SetupInterfaces(result.CodePtr);
|
|
result.ProgTypeInfoList.AddToProgram(result);
|
|
end;
|
|
|
|
for I:= 1 to Card do
|
|
if Records[I].MustBeFixed then
|
|
begin
|
|
if SymbolTable[Records[I].SubId].MethodIndex = 0 then
|
|
begin
|
|
SS := SymbolTable[Records[I].SubId].Name;
|
|
|
|
if StrEql(SS, 'SafeCallException') then
|
|
Shift := -32
|
|
else if StrEql(SS, 'AfterConstruction') then
|
|
Shift := -28
|
|
else if StrEql(SS, 'BeforeDestruction') then
|
|
Shift := -24
|
|
else if StrEql(SS, 'Dispatch') then
|
|
Shift := -20
|
|
else if StrEql(SS, 'DefaultHandler') then
|
|
Shift := -16
|
|
else if StrEql(SS, 'NewInstance') then
|
|
Shift := -12
|
|
else if StrEql(SS, 'FreeInstance') then
|
|
Shift := -8
|
|
else if StrEql(SS, 'Destroy') then
|
|
Shift := -4
|
|
|
|
{$IFDEF UNIC}
|
|
else if StrEql(SS, 'ToString') then
|
|
Shift := -36
|
|
else if StrEql(SS, 'GetHashCode') then
|
|
Shift := -40
|
|
else if StrEql(SS, 'Equals') then
|
|
Shift := -44
|
|
{$ENDIF}
|
|
|
|
else
|
|
begin
|
|
TKernel(kernel).CreateError(errInternalErrorMethodIndex, []);
|
|
end;
|
|
end
|
|
else
|
|
Shift := (SymbolTable[Records[I].SubId].MethodIndex - 1) * 4;
|
|
Move(Shift, Records[I].Code[Records[I].OpOffset], 4);
|
|
Records[I].Decompile;
|
|
Move(Shift, ShiftPointer(result.CodePtr, Records[I].ProgOffset + Records[I].OpOffset)^, 4);
|
|
end;
|
|
end;
|
|
|
|
procedure TSymbolProg.CreateZList(P: TProgram);
|
|
var
|
|
I, S, SZ: Integer;
|
|
R: TSymbolProgRec;
|
|
begin
|
|
P.ZList.Clear;
|
|
{
|
|
|
|
for I:=1 to Card do
|
|
begin
|
|
R := Records[I];
|
|
if R.Z then
|
|
begin
|
|
S := GetShiftOfRecord(R);
|
|
P.ZList.Add(S);
|
|
end;
|
|
end;
|
|
}
|
|
S := 0;
|
|
for I:=1 to Card do
|
|
begin
|
|
R := Records[I];
|
|
|
|
if R.Z then
|
|
P.ZList.Add(S);
|
|
|
|
SZ := R.Size;
|
|
if SZ > 0 then
|
|
S := S + SZ;
|
|
end;
|
|
|
|
P.SetZList;
|
|
end;
|
|
|
|
procedure TSymbolProg.RaiseError(const Message: string; params: array of Const);
|
|
begin
|
|
raise Exception.Create(Format(Message, params));
|
|
end;
|
|
|
|
procedure TSymbolProg.CreateError(const Message: string; params: array of Const);
|
|
begin
|
|
TKernel(kernel).CreateError(Message, params);
|
|
end;
|
|
|
|
function TSymbolProg.GetOffset(S: TSymbolRec): Integer;
|
|
begin
|
|
result := TKernel(kernel).GetOffset(S);
|
|
end;
|
|
|
|
function TSymbolProg.EmitGetCallerEIP: Integer;
|
|
begin
|
|
AsmGetREG32_ESIPtr(_EAX, GetOffset(TKernel(kernel).SymbolTable[Id_GetAddressGetCallerEIP]));
|
|
//6
|
|
AsmSubREG_Imm(_ESP, 12);//6
|
|
AsmCall_REG(_EAX); //2
|
|
AsmCall_REG(_EAX); //2
|
|
AsmAddREG_Imm(_ESP, 12); //6
|
|
result := 6 + 6 + 2 + 2 + 6;
|
|
end;
|
|
|
|
function TSymbolProg.EmitZ: Integer;
|
|
var
|
|
R: TSymbolProgRec;
|
|
begin
|
|
R := AsmMovREG_Imm(_EDI, 400000); // 5 or 10 CodePtr
|
|
R.Z := true;
|
|
AsmMovREG_Imm(_ESI, 400000); // 5 or 10 DataPtr
|
|
if TKernel(kernel).TargetPlatform = tpWin64 then
|
|
result := 20
|
|
else
|
|
result := 10;
|
|
end;
|
|
|
|
function TSymbolProg.GetPAX64: Boolean;
|
|
begin
|
|
if kernel = nil then
|
|
result := false
|
|
else
|
|
result := TKernel(kernel).PAX64;
|
|
end;
|
|
|
|
function TSymbolProg.GetSizeOfPointer: Integer;
|
|
begin
|
|
if PAX64 then
|
|
result := 8
|
|
else
|
|
result := 4;
|
|
end;
|
|
|
|
end.
|