mirror of
https://github.com/cheat-engine/cheat-engine
synced 2026-08-15 02:26:08 -04:00
16590 lines
758 KiB
ObjectPascal
Executable file
16590 lines
758 KiB
ObjectPascal
Executable file
// Copyright Cheat Engine. All Rights Reserved.
|
|
|
|
unit disassembler;
|
|
|
|
{$MODE Delphi}
|
|
|
|
interface
|
|
|
|
{$ifdef jni}
|
|
uses unixporthelper, sysutils, byteinterpreter, symbolhandler, NewKernelHandler,
|
|
ProcessHandlerUnit, LastDisassembleData, DisassemblerArm, commonTypeDefs;
|
|
{$endif}
|
|
|
|
{$ifdef windows}
|
|
uses windows, classes, imagehlp,sysutils,LCLIntf,byteinterpreter, symbolhandler, symbolhandlerstructs,
|
|
CEFuncProc, NewKernelHandler, ProcessHandlerUnit, LastDisassembleData, disassemblerarm,
|
|
commonTypeDefs, maps, math,vextypedef, betterControls, syncobjs;
|
|
{$endif}
|
|
|
|
{$ifdef darwin}
|
|
uses LCLIntf, LCLType, macport, macportdefines, classes,sysutils,byteinterpreter, symbolhandler, symbolhandlerstructs,
|
|
CEFuncProc, ProcessHandlerUnit, LastDisassembleData, disassemblerarm,
|
|
commonTypeDefs, maps, math,vextypedef, syncobjs, NewKernelHandler;
|
|
{$endif}
|
|
|
|
//translation: There is no fucking way I change the descriptions to resource strings
|
|
//if you're bored, go do this
|
|
|
|
type Tprefix = set of byte;
|
|
type TMemory = array [0..64] of byte;
|
|
type TIntToHexS=function(address:ptrUInt;chars: integer; signed: boolean=false; signedsize: integer=0):string of object;
|
|
|
|
type TMRPos=(mLeft,mRight, mNone);
|
|
|
|
|
|
|
|
const BIT_REX_W=8; //1000
|
|
const BIT_REX_R=4;
|
|
const BIT_REX_X=2;
|
|
const BIT_REX_B=1;
|
|
|
|
{$ifdef UNIX}
|
|
const
|
|
EFLAGS_CF=(1 shl 0);
|
|
EFLAGS_PF=(1 shl 2);
|
|
EFLAGS_AF=(1 shl 4);
|
|
EFLAGS_ZF=(1 shl 6);
|
|
EFLAGS_SF=(1 shl 7);
|
|
EFLAGS_TF=(1 shl 8);
|
|
EFLAGS_IF=(1 shl 9);
|
|
EFLAGS_DF=(1 shl 10);
|
|
EFLAGS_OF=(1 shl 11);
|
|
EFLAGS_NT=(1 shl 14);
|
|
EFLAGS_RF=(1 shl 16);
|
|
EFLAGS_VM=(1 shl 17);
|
|
EFLAGS_AC=(1 shl 18);
|
|
EFLAGS_ID=(1 shl 21);
|
|
{$endif}
|
|
|
|
type
|
|
|
|
TDisassembleEvent=function(sender: TObject; address: ptruint; var ldd: TLastDisassembleData; var output: string; var description: string): boolean of object;
|
|
TRegisterType=(rt64, rt32, rt16, rt8, rtYMM, rtXMM,rtMM, rtSegment, rtControlRegister, rtDebugRegister);
|
|
|
|
TDisassembler=class
|
|
private
|
|
opcodeflags: record
|
|
pp: integer;
|
|
L: boolean;
|
|
vvvv: integer;
|
|
W: boolean;
|
|
mmmmm: integer;
|
|
B: boolean;
|
|
X: boolean;
|
|
R: boolean;
|
|
skipExtraRegOnMemoryAccess: boolean;
|
|
skipExtraReg: boolean;
|
|
ignoreLForExtraReg: boolean;
|
|
extrareginstoverride: integer;
|
|
end;
|
|
|
|
|
|
|
|
inttohexs: TIntToHexS;
|
|
RexPrefix: byte;
|
|
riprelative: boolean;
|
|
hasvex: boolean;
|
|
hasvsib: boolean;
|
|
|
|
colorhex: string;
|
|
colorreg: string;
|
|
colorsymbol: string;
|
|
endcolor: string;
|
|
|
|
_memory: TMemory;
|
|
prefix: TPrefix;
|
|
prefix2: TPrefix;
|
|
|
|
fsyntaxhighlighting: boolean;
|
|
fOnDisassembleOverride: TDisassembleEvent;
|
|
fOnPostDisassemble: TDisassembleEvent;
|
|
faggressivealignment: boolean;
|
|
|
|
|
|
modrmposition: TMRPos;
|
|
|
|
// cs: TCriticalSection;
|
|
|
|
ArmDisassembler: TArmDisassembler;
|
|
|
|
// firstThread: dword;
|
|
|
|
function SIB(memory:PByteArray; sibbyte: integer; var last: dword; addresssize: integer=0): string;
|
|
function MODRM(memory:PByteArray; prefix: TPrefix; modrmbyte: integer; inst: integer; out last: dword; position: TMRPos=mLeft): string; overload;
|
|
function MODRM(memory:PByteArray; prefix: TPrefix; modrmbyte: integer; inst: integer; out last: dword;opperandsize:integer; addresssize: integer=0; position:TMRPos=mLeft): string; overload;
|
|
|
|
function MODRM2(memory:PByteArray; prefix: TPrefix; modrmbyte: integer; inst: integer; out last: dword;opperandsize:integer=0;addresssize: integer=0;position: TMRPos=mLeft): string;
|
|
|
|
function getReg(bt: byte): byte;
|
|
function getmod(bt: byte): byte;
|
|
function getrm(bt: byte): byte;
|
|
|
|
function opcodeToValueType(opcode: string): integer;
|
|
function opcode2F(opcode: string): integer;
|
|
function opcode3FN(opcode: string): integer;
|
|
function opcode3FS(opcode: string): integer;
|
|
function opcode4FST(opcode: string): integer;
|
|
|
|
function Rex_B: boolean; inline;
|
|
function Rex_X: boolean; inline;
|
|
function Rex_R: boolean; inline;
|
|
function Rex_W: boolean; inline;
|
|
|
|
function regnrtostr(listtype: TRegisterType; nr: integer): string;
|
|
|
|
function rd(bt:byte):string;
|
|
function rd8(bt:byte): string;
|
|
function rd16(bt:byte): string;
|
|
function r8(bt:byte): string;
|
|
function r16(bt:byte): string;
|
|
function r32(bt:byte): string;
|
|
function r64(bt:byte): string; //for a few specific ones
|
|
function xmm(bt:byte): string;
|
|
function xmm_ignoreL(bt:byte): string;
|
|
function mm(bt:byte): string;
|
|
function sreg(bt:byte): string;
|
|
function cr(bt:byte): string;
|
|
function dr(bt:byte): string;
|
|
function GetBitOf(Bt: qword; bit: integer): byte;
|
|
function getsegmentoverride(prefix: TPrefix): string;
|
|
|
|
|
|
function inttohexs_withoutsymbols(value:ptrUint;chars: integer; signed: boolean=false; signedsize: integer=0):string;
|
|
function inttohexs_withsymbols(value:ptrUint;chars: integer; signed: boolean=false; signedsize: integer=0):string;
|
|
|
|
procedure setSyntaxHighlighting(state: boolean);
|
|
|
|
protected
|
|
function readMemory(address: ptruint; destination: pointer; size: integer): integer; virtual;
|
|
public
|
|
isdefault: boolean;
|
|
showsymbols: boolean;
|
|
showmodules: boolean;
|
|
showsections: boolean;
|
|
dataOnly: boolean;
|
|
|
|
is64bit: boolean;
|
|
is64bitOverride: boolean;
|
|
is64BitOverrideState: boolean;
|
|
|
|
architecture: (darchAutoDetect, darchX86, darchArm);
|
|
|
|
LastDisassembleData: TLastDisassembleData;
|
|
MarkIPRelativeInstructions: boolean;
|
|
|
|
debugpart: integer;
|
|
|
|
context: PCONTEXT;
|
|
|
|
// showvalues: boolean;
|
|
function disassemble(var offset: ptrUint; var description: string): string; overload;
|
|
function disassemble(var offset: ptrUint): string; overload;
|
|
procedure splitDisassembledString(disassembled: string; showvalues: boolean; var address: string; var bytes: string; var opcode: string; var special:string; context: PContext=nil);
|
|
|
|
function DecodeLastParametersToString: string; //returns the special line splitDisassemblerstring used to return
|
|
|
|
function getLastBytestring: string;
|
|
|
|
constructor create;
|
|
destructor destroy; override;
|
|
|
|
published
|
|
property syntaxhighlighting: boolean read fsyntaxhighlighting write setSyntaxHighlighting;
|
|
property OnDisassembleOverride: TDisassembleEvent read fOnDisassembleOverride write fOnDisassembleOverride;
|
|
property OnPostDisassemble: TDisassembleEvent read fOnPostDisassemble write fOnPostDisassemble;
|
|
property aggressivealignment: boolean read faggressivealignment write faggressivealignment;
|
|
end;
|
|
|
|
|
|
{$ifdef windows}
|
|
TCR3Disassembler=class(TDisassembler)
|
|
private
|
|
fcr3: QWORD;
|
|
procedure setCR3(c: QWORD);
|
|
protected
|
|
function readMemory(address: ptruint; destination: pointer; size: integer): integer; override;
|
|
published
|
|
property CR3: QWORD read fCR3 write setCR3;
|
|
|
|
end;
|
|
{$endif}
|
|
|
|
|
|
|
|
|
|
//function rd(bt: byte): string;
|
|
//function rd8(bt:byte): string;
|
|
//function rd16(bt:byte): string;
|
|
|
|
//function r8(bt:byte): string;
|
|
//function r16(bt:byte): string;
|
|
//function r32(bt:byte): string;
|
|
//function mm(bt:byte): string;
|
|
//function xmm(bt:byte): string;
|
|
//function sreg(bt:byte): string;
|
|
//function CR(bt:byte):string;
|
|
//function DR(bt:byte):string;
|
|
|
|
|
|
|
|
//function GetBitOf(Bt: qword; bit: integer): byte;
|
|
//function getsegmentoverride(prefix: TPrefix): string;
|
|
//function getmod(bt: byte): byte;
|
|
//function getRM(bt: byte): byte;
|
|
//function getREG(bt: byte): byte;
|
|
|
|
function disassemble(var offset: ptrUint): string; overload;
|
|
function disassemble(var offset: ptrUint; var description: string): string; overload;
|
|
|
|
function GetBitOf(Bt: qword; bit: integer): byte;
|
|
function previousopcode(address: ptrUint; d: Tdisassembler=nil):ptrUint;
|
|
function has4ByteHexString(d: string; var hexstring: string): boolean;
|
|
function hasAddress(d: string; var address: ptrUint; context: PContext=nil):boolean;
|
|
|
|
//function translatestring(disassembled: string; numberofbytes: integer; showvalues: boolean):string;
|
|
//function translatestring(disassembled: string; numberofbytes: integer; showvalues: boolean; var address: string; var bytes: string; var opcode: string; var special:string):string;
|
|
procedure splitDisassembledString(disassembled: string; showvalues: boolean; var address: string; var bytes: string; var opcode: string; var special:string; context: PContext=nil);
|
|
|
|
function registerGlobalDisassembleOverride(m: TDisassembleEvent): integer;
|
|
procedure unregisterGlobalDisassembleOverride(id: integer);
|
|
|
|
var visibleDisassembler: TDisassembler; //this disassembler is used to render the disassembly output. Each update it gets synced with the default
|
|
defaultDisassembler: TDisassembler;
|
|
GlobalDisassembleOverrides: array of TDisassembleEvent;
|
|
|
|
implementation
|
|
|
|
{$ifdef jni}
|
|
uses Assemblerunit, StrUtils, Parsers, memoryQuery;
|
|
{$endif}
|
|
|
|
{$ifdef windows}
|
|
uses Assemblerunit,CEDebugger, debughelper, StrUtils, debuggertypedefinitions,
|
|
Parsers, memoryQuery, binutils, luacaller, vmxfunctions, frmcodefilterunit,
|
|
BreakpointTypeDef, frmEditHistoryUnit, dialogs{$ifdef onebytejumps}, autoassemblerexeptionhandler {$endif};
|
|
{$endif}
|
|
|
|
{$ifdef darwin}
|
|
uses Assemblerunit,CEDebugger, debughelper, StrUtils, debuggertypedefinitions,
|
|
Parsers, memoryQuery, (*binutils,*) LuaCaller, (*vmxfunctions, frmcodefilterunit, *)
|
|
BreakpointTypeDef, frmEditHistoryUnit, dialogs;
|
|
{$endif}
|
|
|
|
|
|
|
|
function registerGlobalDisassembleOverride(m: TDisassembleEvent): integer;
|
|
var i: integer;
|
|
begin
|
|
for i:=0 to length(GlobalDisassembleOverrides)-1 do
|
|
begin
|
|
if assigned(GlobalDisassembleOverrides[i])=false then
|
|
begin
|
|
GlobalDisassembleOverrides[i]:=m;
|
|
result:=i;
|
|
exit;
|
|
end
|
|
end;
|
|
|
|
result:=length(GlobalDisassembleOverrides);
|
|
setlength(GlobalDisassembleOverrides, result+1);
|
|
GlobalDisassembleOverrides[result]:=m;
|
|
end;
|
|
|
|
procedure unregisterGlobalDisassembleOverride(id: integer);
|
|
begin
|
|
if id<length(GlobalDisassembleOverrides) then
|
|
begin
|
|
{$ifndef jni}
|
|
CleanupLuaCall(TMethod(GlobalDisassembleOverrides[id]));
|
|
{$endif}
|
|
GlobalDisassembleOverrides[id]:=nil;
|
|
end;
|
|
end;
|
|
|
|
|
|
function TDisassembler.regnrtostr(listtype: TRegisterType; nr: integer): string;
|
|
begin
|
|
result:='Error';
|
|
case listtype of
|
|
rt8:
|
|
begin
|
|
case nr of
|
|
0: result:='al';
|
|
1: result:='cl';
|
|
2: result:='dl';
|
|
3: result:='bl';
|
|
4: if rexprefix=0 then result:='ah' else result:='spl';
|
|
5: if rexprefix=0 then result:='ch' else result:='bpl';
|
|
6: if rexprefix=0 then result:='dh' else result:='sil';
|
|
7: if rexprefix=0 then result:='bh' else result:='dil';
|
|
8: result:='r8b';
|
|
9: result:='r9b';
|
|
10: result:='r10b';
|
|
11: result:='r11b';
|
|
12: result:='r12b';
|
|
13: result:='r13b';
|
|
14: result:='r14b';
|
|
15: result:='r15b';
|
|
end;
|
|
end;
|
|
|
|
rt16:
|
|
begin
|
|
case nr of
|
|
0: result:='ax';
|
|
1: result:='cx';
|
|
2: result:='dx';
|
|
3: result:='bx';
|
|
4: result:='sp';
|
|
5: result:='bp';
|
|
6: result:='si';
|
|
7: result:='di';
|
|
8: result:='r8w';
|
|
9: result:='r9w';
|
|
10: result:='r10w';
|
|
11: result:='r11w';
|
|
12: result:='r12w';
|
|
13: result:='r13w';
|
|
14: result:='r14w';
|
|
15: result:='r15w';
|
|
end;
|
|
end;
|
|
|
|
rt32:
|
|
begin
|
|
case nr of
|
|
0: result:='eax';
|
|
1: result:='ecx';
|
|
2: result:='edx';
|
|
3: result:='ebx';
|
|
4: result:='esp';
|
|
5: result:='ebp';
|
|
6: result:='esi';
|
|
7: result:='edi';
|
|
8: result:='r8d';
|
|
9: result:='r9d';
|
|
10: result:='r10d';
|
|
11: result:='r11d';
|
|
12: result:='r12d';
|
|
13: result:='r13d';
|
|
14: result:='r14d';
|
|
15: result:='r15d';
|
|
end;
|
|
end;
|
|
|
|
rt64:
|
|
begin
|
|
case nr of
|
|
0: result:='rax';
|
|
1: result:='rcx';
|
|
2: result:='rdx';
|
|
3: result:='rbx';
|
|
4: result:='rsp';
|
|
5: result:='rbp';
|
|
6: result:='rsi';
|
|
7: result:='rdi';
|
|
8: result:='r8';
|
|
9: result:='r9';
|
|
10: result:='r10';
|
|
11: result:='r11';
|
|
12: result:='r12';
|
|
13: result:='r13';
|
|
14: result:='r14';
|
|
15: result:='r15';
|
|
end;
|
|
end;
|
|
|
|
rtDebugRegister:
|
|
begin
|
|
case nr of
|
|
0: result:='dr0';
|
|
1: result:='dr1';
|
|
2: result:='dr2';
|
|
3: result:='dr3';
|
|
4: result:='dr4';
|
|
5: result:='dr5';
|
|
6: result:='dr6';
|
|
7: result:='dr7';
|
|
8: result:='dr8';//Do not exist, but let's implement the encoding
|
|
9: result:='dr9';
|
|
10: result:='dr10';
|
|
11: result:='dr11';
|
|
12: result:='dr12';
|
|
13: result:='dr13';
|
|
14: result:='dr14';
|
|
15: result:='dr15';
|
|
end;
|
|
end;
|
|
|
|
rtControlRegister:
|
|
begin
|
|
case nr of
|
|
0: result:='cr0';
|
|
1: result:='cr1';
|
|
2: result:='cr2';
|
|
3: result:='cr3';
|
|
4: result:='cr4';
|
|
5: result:='cr5';
|
|
6: result:='cr6';
|
|
7: result:='cr7';
|
|
8: result:='cr8';
|
|
9: result:='cr9';
|
|
10: result:='cr10';
|
|
11: result:='cr11';
|
|
12: result:='cr12';
|
|
13: result:='cr13';
|
|
14: result:='cr14';
|
|
15: result:='cr15';
|
|
end;
|
|
end;
|
|
rtSegment:
|
|
begin
|
|
case nr of
|
|
0: result:='es';
|
|
1: result:='cs';
|
|
2: result:='ss';
|
|
3: result:='ds';
|
|
4: result:='fs';
|
|
5: result:='gs';
|
|
6: result:='hs'; //as if...
|
|
7: result:='is';
|
|
8: result:='js';
|
|
9: result:='ks';
|
|
10: result:='ls';
|
|
11: result:='ms';
|
|
12: result:='ns';
|
|
13: result:='os';
|
|
14: result:='ps';
|
|
15: result:='qs';
|
|
end;
|
|
end;
|
|
|
|
rtMM:
|
|
begin
|
|
case nr of
|
|
0: result:='mm0';
|
|
1: result:='mm1';
|
|
2: result:='mm2';
|
|
3: result:='mm3';
|
|
4: result:='mm4';
|
|
5: result:='mm5';
|
|
6: result:='mm6';
|
|
7: result:='mm7';
|
|
8: result:='mm8';
|
|
9: result:='mm9';
|
|
10: result:='mm10';
|
|
11: result:='mm11';
|
|
12: result:='mm12';
|
|
13: result:='mm13';
|
|
14: result:='mm14';
|
|
15: result:='mm15';
|
|
end;
|
|
end;
|
|
|
|
rtXMM:
|
|
begin
|
|
case nr of
|
|
0: result:='xmm0';
|
|
1: result:='xmm1';
|
|
2: result:='xmm2';
|
|
3: result:='xmm3';
|
|
4: result:='xmm4';
|
|
5: result:='xmm5';
|
|
6: result:='xmm6';
|
|
7: result:='xmm7';
|
|
8: result:='xmm8';
|
|
9: result:='xmm9';
|
|
10: result:='xmm10';
|
|
11: result:='xmm11';
|
|
12: result:='xmm12';
|
|
13: result:='xmm13';
|
|
14: result:='xmm14';
|
|
15: result:='xmm15';
|
|
end;
|
|
end;
|
|
|
|
rtYMM:
|
|
begin
|
|
case nr of
|
|
0: result:='ymm0';
|
|
1: result:='ymm1';
|
|
2: result:='ymm2';
|
|
3: result:='ymm3';
|
|
4: result:='ymm4';
|
|
5: result:='ymm5';
|
|
6: result:='ymm6';
|
|
7: result:='ymm7';
|
|
8: result:='ymm8';
|
|
9: result:='ymm9';
|
|
10: result:='ymm10';
|
|
11: result:='ymm11';
|
|
12: result:='ymm12';
|
|
13: result:='ymm13';
|
|
14: result:='ymm14';
|
|
15: result:='ymm15';
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
function TDisassembler.rd(bt:byte):string;
|
|
begin
|
|
if rex_B then bt:=bt or 8;
|
|
case bt of
|
|
0: result:='eax';
|
|
1: result:='ecx';
|
|
2: result:='edx';
|
|
3: result:='ebx';
|
|
4: result:='esp';
|
|
5: result:='ebp';
|
|
6: result:='esi';
|
|
7: result:='edi';
|
|
8: result:='r8';
|
|
9: result:='r9';
|
|
10: result:='r10';
|
|
11: result:='r11';
|
|
12: result:='r12';
|
|
13: result:='r13';
|
|
14: result:='r14';
|
|
15: result:='r15';
|
|
else result:='';
|
|
end;
|
|
|
|
if not rex_w then
|
|
begin
|
|
//not a rex_w field
|
|
if bt>=8 then //but the bt field is higher than 8 (so 32-bit addressing, increased register)
|
|
begin
|
|
result:=result+'d'; //32-bit variant
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
result[1]:='r' //replace eax,ebx with rax,rbx...
|
|
end;
|
|
|
|
result:=colorreg+result+endcolor;
|
|
end;
|
|
|
|
|
|
function TDisassembler.rd8(bt:byte): string;
|
|
begin
|
|
if rex_B then bt:=bt or 8;
|
|
case bt of
|
|
0: result:='al';
|
|
1: result:='cl';
|
|
2: result:='dl';
|
|
3: result:='bl';
|
|
|
|
4: if rexprefix=0 then result:='ah' else result:='spl';
|
|
5: if rexprefix=0 then result:='ch' else result:='bpl';
|
|
6: if rexprefix=0 then result:='dh' else result:='sil';
|
|
7: if rexprefix=0 then result:='bh' else result:='dil';
|
|
8: result:='r8b';
|
|
9: result:='r9b';
|
|
10: result:='r10b';
|
|
11: result:='r11b';
|
|
12: result:='r12b';
|
|
13: result:='r13b';
|
|
14: result:='r14b';
|
|
15: result:='r15b';
|
|
else result:='';
|
|
end;
|
|
|
|
result:=colorreg+result+endcolor;
|
|
end;
|
|
|
|
|
|
function TDisassembler.rd16(bt:byte):string;
|
|
begin
|
|
if rex_B then bt:=bt or 8;
|
|
case bt of
|
|
0: result:='ax';
|
|
1: result:='cx';
|
|
2: result:='dx';
|
|
3: result:='bx';
|
|
4: result:='sp';
|
|
5: result:='bp';
|
|
6: result:='si';
|
|
7: result:='di';
|
|
8: result:='r8w';
|
|
9: result:='r9w';
|
|
10: result:='r10w';
|
|
11: result:='r11w';
|
|
12: result:='r12w';
|
|
13: result:='r13w';
|
|
14: result:='r14w';
|
|
15: result:='r15w';
|
|
else result:='';
|
|
|
|
end;
|
|
result:=colorreg+result+endcolor;
|
|
end;
|
|
|
|
|
|
function TDisassembler.r8(bt:byte): string;
|
|
var regnr: integer;
|
|
begin
|
|
regnr:=getreg(bt);
|
|
result:=colorreg+regnrtostr(rt8, regnr)+endcolor;
|
|
end;
|
|
|
|
|
|
function TDisassembler.r16(bt:byte): string;
|
|
var regnr: integer;
|
|
begin
|
|
regnr:=getreg(bt);
|
|
result:=colorreg+regnrtostr(rt16, regnr)+endcolor;
|
|
end;
|
|
|
|
|
|
function TDisassembler.r32(bt:byte): string;
|
|
var regnr: integer;
|
|
begin
|
|
regnr:=getreg(bt);
|
|
if rex_w then
|
|
result:=colorreg+regnrtostr(rt64, regnr)+endcolor
|
|
else
|
|
result:=colorreg+regnrtostr(rt32, regnr)+endcolor;
|
|
end;
|
|
|
|
function TDisassembler.r64(bt:byte): string;
|
|
var regnr: integer;
|
|
begin
|
|
regnr:=getreg(bt);
|
|
result:=colorreg+regnrtostr(rt64, regnr)+endcolor;
|
|
end;
|
|
|
|
|
|
function TDisassembler.xmm_ignoreL(bt:byte): string;
|
|
var regnr: integer;
|
|
begin
|
|
regnr:=getreg(bt);
|
|
result:=colorreg+regnrtostr(rtXMM, regnr)+endcolor;
|
|
end;
|
|
|
|
function TDisassembler.xmm(bt:byte): string;
|
|
var regnr: integer;
|
|
begin
|
|
regnr:=getreg(bt);
|
|
if opcodeflags.L then
|
|
result:=colorreg+regnrtostr(rtYMM, regnr)+endcolor
|
|
else
|
|
result:=colorreg+regnrtostr(rtXMM, regnr)+endcolor;
|
|
end;
|
|
|
|
function TDisassembler.mm(bt:byte): string;
|
|
var regnr: integer;
|
|
begin
|
|
regnr:=getreg(bt);
|
|
result:=colorreg+regnrtostr(rtMM, regnr)+endcolor;
|
|
end;
|
|
|
|
function TDisassembler.sreg(bt:byte): string;
|
|
var regnr: integer;
|
|
begin
|
|
regnr:=getreg(bt);
|
|
result:=colorreg+regnrtostr(rtSegment, regnr)+endcolor;
|
|
end;
|
|
|
|
function TDisassembler.CR(bt:byte):string;
|
|
var regnr: integer;
|
|
begin
|
|
regnr:=getreg(bt);
|
|
result:=colorreg+regnrtostr(rtControlRegister, regnr)+endcolor;
|
|
end;
|
|
|
|
function TDisassembler.DR(bt:byte):string;
|
|
var regnr: integer;
|
|
begin
|
|
regnr:=getreg(bt);
|
|
result:=colorreg+regnrtostr(rtDebugRegister, regnr)+endcolor;
|
|
end;
|
|
|
|
|
|
function GetBitOf(Bt: qword; bit: integer): byte;
|
|
begin
|
|
result:=getbit(bit,bt);
|
|
end;
|
|
|
|
function TDisassembler.GetBitOf(Bt: qword; bit: integer): byte;
|
|
begin
|
|
result:=getbit(bit,bt);
|
|
end;
|
|
|
|
function TDisassembler.getsegmentoverride(prefix: TPrefix): string;
|
|
begin
|
|
result:='';
|
|
if $2e in prefix then result:='cs:' else
|
|
if $26 in prefix then result:='es:' else
|
|
if $36 in prefix then result:='ss:' else
|
|
if $3e in prefix then result:='' else
|
|
if $64 in prefix then result:='fs:' else
|
|
if $65 in prefix then result:='gs:';
|
|
end;
|
|
|
|
function TDisassembler.getmod(bt: byte): byte;
|
|
begin
|
|
result:=(bt shr 6) and 3;
|
|
end;
|
|
|
|
function TDisassembler.getRM(bt: byte): byte;
|
|
begin
|
|
result:=bt and 7;
|
|
|
|
//if this instruction does NOT have a SIB byte, only then apply the rex_B bit
|
|
//It has an SIB byte if RM==4 and mod!=3
|
|
if rex_b and (not ((result=4) and (getmod(bt)<>3))) then
|
|
result:=result or 8;
|
|
end;
|
|
|
|
function TDisassembler.getREG(bt: byte): byte;
|
|
begin
|
|
result:=(bt shr 3) and 7;
|
|
if Rex_r then
|
|
result:=result or 8; //extend the reg field
|
|
end;
|
|
|
|
|
|
|
|
function TDisassembler.Rex_B: boolean; inline;
|
|
begin
|
|
exit(opcodeflags.B);
|
|
end;
|
|
|
|
function TDisassembler.Rex_X: boolean; inline;
|
|
begin
|
|
exit(opcodeflags.X);
|
|
end;
|
|
|
|
function TDisassembler.Rex_R: boolean; inline;
|
|
begin
|
|
exit(opcodeflags.R);
|
|
end;
|
|
|
|
function TDisassembler.Rex_W: boolean; inline;
|
|
begin
|
|
exit(opcodeflags.W);
|
|
end;
|
|
|
|
|
|
function TDisassembler.MODRM2(memory:PByteArray; prefix: TPrefix; modrmbyte: integer; inst: integer; out last: dword;opperandsize:integer=0; addresssize:integer=0; position:TMRPos=mLeft): string;
|
|
var dwordptr: ^dword;
|
|
regprefix: char;
|
|
i: integer;
|
|
|
|
ep: string='';
|
|
|
|
prestr: string='';
|
|
poststr: string='';
|
|
|
|
operandstring: string='';
|
|
|
|
showextrareg: boolean;
|
|
extrareginst: integer;
|
|
begin
|
|
modrmposition:=position;
|
|
result:='';
|
|
showextrareg:=hasvex and (opcodeflags.skipExtraReg=false);
|
|
if opcodeflags.extrareginstoverride<>-1 then
|
|
extrareginst:=opcodeflags.extrareginstoverride
|
|
else
|
|
extrareginst:=inst;
|
|
|
|
if is64bit then
|
|
regprefix:='r'
|
|
else
|
|
regprefix:='e';
|
|
|
|
case position of
|
|
mLeft,mNone:
|
|
begin
|
|
prestr:='';
|
|
poststr:=',';
|
|
end;
|
|
|
|
mRight:
|
|
begin
|
|
prestr:=',';
|
|
poststr:='';
|
|
end;
|
|
end;
|
|
|
|
case opperandsize of
|
|
8 : operandstring:='byte ptr ';
|
|
16: operandstring:='word ptr ';
|
|
32: operandstring:='dword ptr ';
|
|
64: operandstring:='qword ptr ';
|
|
80: operandstring:='tword ptr ';
|
|
128: operandstring:='dqword ptr ';
|
|
256: operandstring:='YMMword ptr ';
|
|
else
|
|
operandstring:='';
|
|
end;
|
|
|
|
|
|
|
|
LastDisassembleData.Seperators[LastDisassembleData.SeperatorCount]:=modrmbyte;
|
|
inc(LastDisassembleData.SeperatorCount);
|
|
|
|
dwordptr:=@memory[modrmbyte+1];
|
|
last:=modrmbyte+1;
|
|
|
|
LastDisassembleData.Seperators[LastDisassembleData.SeperatorCount]:=last;
|
|
inc(LastDisassembleData.SeperatorCount);
|
|
|
|
|
|
if (not processhandler.is64Bit) and ($67 in prefix) then
|
|
begin
|
|
// put some 16-bit stuff in here
|
|
// but since this is a 32-bit debugger only ,forget it...
|
|
|
|
end
|
|
else
|
|
begin
|
|
case getmod(memory[modrmbyte]) of
|
|
0:
|
|
begin
|
|
if showextrareg and opcodeflags.skipExtraRegOnMemoryAccess then showextrareg:=false;
|
|
|
|
case getrm(memory[modrmbyte]) of
|
|
0: result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'ax'+endcolor+']';
|
|
1: result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'cx'+endcolor+']';
|
|
2: result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'dx'+endcolor+']';
|
|
3: result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'bx'+endcolor+']';
|
|
4:
|
|
begin
|
|
//has an sib
|
|
result:=getsegmentoverride(prefix)+'['+sib(memory,modrmbyte+1,last, addresssize)+']';
|
|
end;
|
|
|
|
5:
|
|
begin
|
|
//followed by a disp32
|
|
if is64bit then
|
|
begin
|
|
riprelative:=true;
|
|
result:=getsegmentoverride(prefix)+'['+inttohexs_withoutsymbols(dwordptr^,8)+']';
|
|
|
|
|
|
LastDisassembleData.modrmValueType:=dvtAddress;
|
|
LastDisassembleData.modrmValue:=dwordptr^;
|
|
|
|
LastDisassembleData.riprelative:=modrmbyte+1;
|
|
|
|
end
|
|
else
|
|
begin
|
|
result:=getsegmentoverride(prefix)+'['+inttohexs(dwordptr^,8)+']';
|
|
LastDisassembleData.modrmValueType:=dvtAddress;
|
|
LastDisassembleData.modrmValue:=dwordptr^;
|
|
end;
|
|
last:=last+4;
|
|
end;
|
|
|
|
6: result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'si'+endcolor+']';
|
|
7: result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'di'+endcolor+']';
|
|
8: result:=getsegmentoverride(prefix)+'['+colorreg+'r8'+endcolor+']';
|
|
9: result:=getsegmentoverride(prefix)+'['+colorreg+'r9'+endcolor+']';
|
|
10: result:=getsegmentoverride(prefix)+'['+colorreg+'r10'+endcolor+']';
|
|
11: result:=getsegmentoverride(prefix)+'['+colorreg+'r11'+endcolor+']';
|
|
12: result:=getsegmentoverride(prefix)+'['+colorreg+'r12'+endcolor+']';
|
|
13: result:=getsegmentoverride(prefix)+'['+colorreg+'r13'+endcolor+']';
|
|
14: result:=getsegmentoverride(prefix)+'['+colorreg+'r14'+endcolor+']';
|
|
15: result:=getsegmentoverride(prefix)+'['+colorreg+'r15'+endcolor+']';
|
|
end;
|
|
|
|
if opperandsize<>0 then
|
|
LastDisassembleData.datasize:=opperandsize div 8;
|
|
|
|
result:=operandstring+result;
|
|
|
|
end;
|
|
1: begin
|
|
if showextrareg and opcodeflags.skipExtraRegOnMemoryAccess then showextrareg:=false;
|
|
|
|
if getrm(memory[modrmbyte])<>4 then
|
|
begin
|
|
LastDisassembleData.modrmValueType:=dvtValue;
|
|
LastDisassembleData.modrmValue:=ptruint(shortint(memory[modrmbyte+1]));
|
|
end;
|
|
|
|
case getrm(memory[modrmbyte]) of
|
|
0:
|
|
begin
|
|
if shortint(memory[modrmbyte+1])>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'ax'+endcolor+'+'+inttohexs(memory[modrmbyte+1],2)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'ax'+endcolor+inttohexs(ptruint(shortint(memory[modrmbyte+1])),2)+']';
|
|
end;
|
|
|
|
1:
|
|
if shortint(memory[modrmbyte+1])>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'cx'+endcolor+'+'+inttohexs(memory[modrmbyte+1],2)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'cx'+endcolor+inttohexs(ptruint(shortint(memory[modrmbyte+1])),2)+']';
|
|
|
|
|
|
2:
|
|
if shortint(memory[modrmbyte+1])>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'dx'+endcolor+'+'+inttohexs(memory[modrmbyte+1],2)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'dx'+endcolor+inttohexs(ptruint(shortint(memory[modrmbyte+1])),2)+']';
|
|
|
|
|
|
3:
|
|
if shortint(memory[modrmbyte+1])>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'bx'+endcolor+'+'+inttohexs(memory[modrmbyte+1],2)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'bx'+endcolor+inttohexs(ptruint(shortint(memory[modrmbyte+1])),2)+']';
|
|
|
|
|
|
4:
|
|
begin
|
|
result:=getsegmentoverride(prefix)+'['+sib(memory,modrmbyte+1,last, addressSize)+']';
|
|
dec(last);
|
|
|
|
{
|
|
if shortint(memory[last])>=0 then
|
|
result:=result+'+'+inttohexs(memory[last],2)+'],'
|
|
else
|
|
result:=result+'-'+inttohexs(-shortint(memory[last]),2)+'],';
|
|
}
|
|
|
|
end;
|
|
|
|
5:
|
|
if shortint(memory[modrmbyte+1])>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'bp'+endcolor+'+'+inttohexs(memory[modrmbyte+1],2)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'bp'+endcolor+inttohexs(ptruint(shortint(memory[modrmbyte+1])),2, true, 2)+']';
|
|
|
|
|
|
6:
|
|
if shortint(memory[modrmbyte+1])>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'si'+endcolor+'+'+inttohexs(memory[modrmbyte+1],2)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'si'+endcolor+inttohexs(ptruint(shortint(memory[modrmbyte+1])),2, true, 2)+']';
|
|
|
|
|
|
7:
|
|
if shortint(memory[modrmbyte+1])>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'di'+endcolor+'+'+inttohexs(memory[modrmbyte+1],2)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'di'+endcolor+inttohexs(ptruint(shortint(memory[modrmbyte+1])),2, true, 2)+']';
|
|
|
|
|
|
8:
|
|
if shortint(memory[modrmbyte+1])>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r8'+endcolor+'+'+inttohexs(memory[modrmbyte+1],2)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r8'+endcolor+inttohexs(ptruint(shortint(memory[modrmbyte+1])),2, true, 2)+']';
|
|
|
|
|
|
9:
|
|
if shortint(memory[modrmbyte+1])>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r9'+endcolor+'+'+inttohexs(memory[modrmbyte+1],2)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r9'+endcolor+inttohexs(ptruint(shortint(memory[modrmbyte+1])),2, true, 2)+']';
|
|
|
|
10:
|
|
if shortint(memory[modrmbyte+1])>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r10'+endcolor+'+'+inttohexs(memory[modrmbyte+1],2)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r10'+endcolor+inttohexs(ptruint(shortint(memory[modrmbyte+1])),2, true, 2)+']';
|
|
|
|
|
|
11:
|
|
if shortint(memory[modrmbyte+1])>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r11'+endcolor+'+'+inttohexs(memory[modrmbyte+1],2)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r11'+endcolor+inttohexs(ptruint(shortint(memory[modrmbyte+1])),2, true, 2)+']';
|
|
|
|
12:
|
|
if shortint(memory[modrmbyte+1])>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r12'+endcolor+'+'+inttohexs(memory[modrmbyte+1],2)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r12'+endcolor+inttohexs(ptruint(shortint(memory[modrmbyte+1])),2, true, 2)+']';
|
|
|
|
13:
|
|
if shortint(memory[modrmbyte+1])>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r13'+endcolor+'+'+inttohexs(memory[modrmbyte+1],2)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r13'+endcolor+inttohexs(ptruint(shortint(memory[modrmbyte+1])),2, true, 2)+']';
|
|
|
|
14:
|
|
if shortint(memory[modrmbyte+1])>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r14'+endcolor+'+'+inttohexs(memory[modrmbyte+1],2)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r14'+endcolor+inttohexs(ptruint(shortint(memory[modrmbyte+1])),2, true, 2)+']';
|
|
|
|
15:
|
|
if shortint(memory[modrmbyte+1])>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r15'+endcolor+'+'+inttohexs(memory[modrmbyte+1],2)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r15'+endcolor+inttohexs(ptruint(shortint(memory[modrmbyte+1])),2, true, 2)+']';
|
|
|
|
end;
|
|
|
|
inc(last);
|
|
LastDisassembleData.datasize:=opperandsize div 8;
|
|
result:=operandstring+result;
|
|
end;
|
|
|
|
2: begin
|
|
if showextrareg and opcodeflags.skipExtraRegOnMemoryAccess then showextrareg:=false;
|
|
|
|
if getrm(memory[modrmbyte])<>4 then
|
|
begin
|
|
LastDisassembleData.modrmValueType:=dvtValue;
|
|
LastDisassembleData.modrmValue:=ptruint(pinteger(dwordptr)^);
|
|
end;
|
|
|
|
case getrm(memory[modrmbyte]) of
|
|
0:
|
|
if integer(dwordptr^)>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'ax'+endcolor+'+'+inttohexs(dwordptr^,8)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'ax'+endcolor+'-'+inttohexs(-integer(dwordptr^),8)+']';
|
|
|
|
1:
|
|
if integer(dwordptr^)>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'cx'+endcolor+'+'+inttohexs(dwordptr^,8)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'cx'+endcolor+'-'+inttohexs(-integer(dwordptr^),8)+']';
|
|
|
|
2:
|
|
if integer(dwordptr^)>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'dx'+endcolor+'+'+inttohexs(dwordptr^,8)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'dx'+endcolor+'-'+inttohexs(-integer(dwordptr^),8)+']';
|
|
|
|
|
|
3:
|
|
if integer(dwordptr^)>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'bx'+endcolor+'+'+inttohexs(dwordptr^,8)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'bx'+endcolor+'-'+inttohexs(-integer(dwordptr^),8)+']';
|
|
|
|
|
|
4:
|
|
begin
|
|
result:=getsegmentoverride(prefix)+'['+sib(memory,modrmbyte+1,last, addresssize)+']';
|
|
dec(last,4);
|
|
end;
|
|
|
|
5:
|
|
if integer(dwordptr^)>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'bp'+endcolor+'+'+inttohexs(dwordptr^,8)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'bp'+endcolor+'-'+inttohexs(-integer(dwordptr^),8)+']';
|
|
|
|
|
|
6:
|
|
if integer(dwordptr^)>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'si'+endcolor+'+'+inttohexs(dwordptr^,8)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'si'+endcolor+'-'+inttohexs(-integer(dwordptr^),8)+']';
|
|
|
|
|
|
7:
|
|
if integer(dwordptr^)>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'di'+endcolor+'+'+inttohexs(dwordptr^,8)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+regprefix+'di'+endcolor+'-'+inttohexs(-integer(dwordptr^),8)+']';
|
|
|
|
|
|
8:
|
|
if integer(dwordptr^)>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r8'+endcolor+'+'+inttohexs(dwordptr^,8)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r8'+endcolor+'-'+inttohexs(-integer(dwordptr^),8)+']';
|
|
|
|
9:
|
|
if integer(dwordptr^)>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r9'+endcolor+'+'+inttohexs(dwordptr^,8)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r9'+endcolor+'-'+inttohexs(-integer(dwordptr^),8)+']';
|
|
|
|
10:
|
|
if integer(dwordptr^)>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r10'+endcolor+'+'+inttohexs(dwordptr^,8)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r10'+endcolor+'-'+inttohexs(-integer(dwordptr^),8)+']';
|
|
|
|
11:
|
|
if integer(dwordptr^)>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r11'+endcolor+'+'+inttohexs(dwordptr^,8)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r11'+endcolor+'-'+inttohexs(-integer(dwordptr^),8)+']';
|
|
|
|
12:
|
|
if integer(dwordptr^)>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r12'+endcolor+'+'+inttohexs(dwordptr^,8)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r12'+endcolor+'-'+inttohexs(-integer(dwordptr^),8)+']';
|
|
|
|
13:
|
|
if integer(dwordptr^)>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r13'+endcolor+'+'+inttohexs(dwordptr^,8)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r13'+endcolor+'-'+inttohexs(-integer(dwordptr^),8)+']';
|
|
|
|
14:
|
|
if integer(dwordptr^)>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r14'+endcolor+'+'+inttohexs(dwordptr^,8)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r14'+endcolor+'-'+inttohexs(-integer(dwordptr^),8)+']';
|
|
|
|
15:
|
|
if integer(dwordptr^)>=0 then
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r15'+endcolor+'+'+inttohexs(dwordptr^,8)+']' else
|
|
result:=getsegmentoverride(prefix)+'['+colorreg+'r15'+endcolor+'-'+inttohexs(-integer(dwordptr^),8)+']';
|
|
|
|
end;
|
|
inc(last,4);
|
|
|
|
LastDisassembleData.datasize:=opperandsize div 8;
|
|
result:=operandstring+result;
|
|
end;
|
|
|
|
3: begin
|
|
LastDisassembleData.datasize:=0;
|
|
case getrm(memory[modrmbyte]) of
|
|
0: case inst of
|
|
0: if rex_w or (opperandsize=64) then result:='rax' else result:='eax';
|
|
1: result:='ax';
|
|
2: result:='al';
|
|
3: result:='mm0';
|
|
4: if opcodeflags.L then result:='ymm0' else result:='xmm0';
|
|
end;
|
|
|
|
1: case inst of
|
|
0: if rex_w or (opperandsize=64) then result:='rcx' else result:='ecx';
|
|
1: result:='cx';
|
|
2: result:='cl';
|
|
3: result:='mm1';
|
|
4: if opcodeflags.L then result:='ymm1' else result:='xmm1';
|
|
end;
|
|
|
|
2: case inst of
|
|
0: if rex_w or (opperandsize=64) then result:='rdx' else result:='edx';
|
|
1: result:='dx';
|
|
2: result:='dl';
|
|
3: result:='mm2';
|
|
4: if opcodeflags.L then result:='ymm2' else result:='xmm2';
|
|
end;
|
|
|
|
3: case inst of
|
|
0: if rex_w or (opperandsize=64) then result:='rbx' else result:='ebx';
|
|
1: result:='bx';
|
|
2: result:='bl';
|
|
3: result:='mm3';
|
|
4: if opcodeflags.L then result:='ymm3' else result:='xmm3';
|
|
end;
|
|
|
|
4: case inst of
|
|
0: if rex_w or (opperandsize=64) then result:='rsp' else result:='esp';
|
|
1: result:='sp';
|
|
2: if rexprefix<>0 then result:='spl' else result:='ah';
|
|
3: result:='mm4';
|
|
4: if opcodeflags.L then result:='ymm4' else result:='xmm4';
|
|
end;
|
|
|
|
5: case inst of
|
|
0: if rex_w or (opperandsize=64) then result:='rbp' else result:='ebp';
|
|
1: result:='bp';
|
|
2: if rexprefix<>0 then result:='bpl' else result:='ch';
|
|
3: result:='mm5';
|
|
4: if opcodeflags.L then result:='ymm5' else result:='xmm5';
|
|
end;
|
|
|
|
6: case inst of
|
|
0: if rex_w or (opperandsize=64) then result:='rsi' else result:='esi';
|
|
1: result:='si';
|
|
2: if rexprefix<>0 then result:='sil' else result:='dh';
|
|
3: result:='mm6';
|
|
4: if opcodeflags.L then result:='ymm6' else result:='xmm6';
|
|
end;
|
|
|
|
7: case inst of
|
|
0: if rex_w or (opperandsize=64) then result:='rdi' else result:='edi';
|
|
1: result:='di';
|
|
2: if rexprefix<>0 then result:='dil' else result:='bh';
|
|
3: result:='mm7';
|
|
4: if opcodeflags.L then result:='ymm7' else result:='xmm7';
|
|
end;
|
|
|
|
8: case inst of
|
|
0: if rex_w or (opperandsize=64) then result:='r8' else result:='r8d';
|
|
1: result:='r8w';
|
|
2: result:='r8b';
|
|
3: result:='mm8';
|
|
4: if opcodeflags.L then result:='ymm8' else result:='xmm8';
|
|
end;
|
|
|
|
9: case inst of
|
|
0: if rex_w or (opperandsize=64) then result:='r9' else result:='r9d';
|
|
1: result:='r9w';
|
|
2: result:='r9b';
|
|
3: result:='mm9';
|
|
4: if opcodeflags.L then result:='ymm9' else result:='xmm9';
|
|
end;
|
|
|
|
10: case inst of
|
|
0: if rex_w or (opperandsize=64) then result:='r10' else result:='r10d';
|
|
1: result:='r10w';
|
|
2: result:='r10b';
|
|
3: result:='mm10';
|
|
4: if opcodeflags.L then result:='ymm10' else result:='xmm10';
|
|
end;
|
|
|
|
11: case inst of
|
|
0: if rex_w or (opperandsize=64) then result:='r11' else result:='r11d';
|
|
1: result:='r11w';
|
|
2: result:='r11b';
|
|
3: result:='mm11';
|
|
4: if opcodeflags.L then result:='ymm11' else result:='xmm11';
|
|
end;
|
|
|
|
12: case inst of
|
|
0: if rex_w or (opperandsize=64) then result:='r12' else result:='r12d';
|
|
1: result:='r12w';
|
|
2: result:='r12b';
|
|
3: result:='mm12';
|
|
4: if opcodeflags.L then result:='ymm12' else result:='xmm12';
|
|
end;
|
|
|
|
13: case inst of
|
|
0: if rex_w or (opperandsize=64) then result:='r13' else result:='r13d';
|
|
1: result:='r13w';
|
|
2: result:='r13b';
|
|
3: result:='mm13';
|
|
4: if opcodeflags.L then result:='ymm13' else result:='xmm13';
|
|
end;
|
|
|
|
14: case inst of
|
|
0: if rex_w or (opperandsize=64) then result:='r14' else result:='r14d';
|
|
1: result:='r14w';
|
|
2: result:='r14b';
|
|
3: result:='mm14';
|
|
4: if opcodeflags.L then result:='ymm14' else result:='xmm14';
|
|
end;
|
|
|
|
15: case inst of
|
|
0: if rex_w or (opperandsize=64) then result:='r15' else result:='r15d';
|
|
1: result:='r15w';
|
|
2: result:='r15b';
|
|
3: result:='mm15';
|
|
4: if opcodeflags.L then result:='ymm15' else result:='xmm15';
|
|
end;
|
|
end;
|
|
|
|
|
|
result:=colorreg+result+endcolor;
|
|
end;
|
|
end;
|
|
if showextrareg then
|
|
begin
|
|
case extrareginst of
|
|
0: if rex_w then ep:=regnrtostr(rt64, not opcodeflags.vvvv and $f) else ep:=regnrtostr(rt32, not opcodeflags.vvvv and $f);
|
|
1: ep:=regnrtostr(rt16, not opcodeflags.vvvv and $f);
|
|
2: ep:=regnrtostr(rt8, not opcodeflags.vvvv and $f);
|
|
3: ep:=regnrtostr(rtMM, not opcodeflags.vvvv and $f);
|
|
4: if opcodeflags.L and (not opcodeflags.ignoreLForExtraReg) then ep:=regnrtostr(rtYMM, not opcodeflags.vvvv and $f) else ep:=regnrtostr(rtXMM, not opcodeflags.vvvv and $f);
|
|
end;
|
|
|
|
case position of
|
|
mLeft,mNone: result:=result+','+colorreg+ep+endcolor;
|
|
mRight: result:=colorreg+ep+endcolor+','+result;
|
|
end;
|
|
end;
|
|
|
|
result:=prestr+result+poststr;
|
|
end;
|
|
|
|
if last<>(modrmbyte+1) then //add an extra seperator since some bytes have been added, usually the last one, except when the opcode has a immeadiate value followed, which this seperator will then separate
|
|
begin
|
|
LastDisassembleData.Seperators[LastDisassembleData.SeperatorCount]:=last;
|
|
inc(LastDisassembleData.SeperatorCount);
|
|
end;
|
|
end;
|
|
|
|
|
|
function tdisassembler.MODRM(memory:PByteArray; prefix: TPrefix; modrmbyte: integer; inst: integer; out last: dword; position: TMRPos=mLeft): string;
|
|
begin
|
|
case inst of
|
|
0: LastDisassembleData.datasize:=processhandler.pointersize;
|
|
1: LastDisassembleData.datasize:=2;
|
|
2: LastDisassembleData.datasize:=1;
|
|
3: LastDisassembleData.datasize:=4;
|
|
4: LastDisassembleData.datasize:=8
|
|
end;
|
|
result:=modrm2(memory,prefix,modrmbyte,inst,last,0,0,position);
|
|
end;
|
|
|
|
function TDisassembler.MODRM(memory:PByteArray; prefix: TPrefix; modrmbyte: integer; inst: integer; out last: dword;opperandsize:integer; addressSize: integer=0; position: TMRPos=mLeft): string;
|
|
begin
|
|
result:=modrm2(memory,prefix,modrmbyte,inst,last, opperandsize, addressSize, position);
|
|
end;
|
|
|
|
function TDisassembler.SIB(memory:PByteArray; sibbyte: integer; var last: dword; addresssize: integer=0): string;
|
|
var
|
|
dwordptr: ^dword;
|
|
byteptr: ^byte absolute dwordptr;
|
|
ss,index,base, _mod,_rm: integer;
|
|
offset: string;
|
|
|
|
indexstring: string;
|
|
displacementstring: string;
|
|
pref: char;
|
|
begin
|
|
result:='';
|
|
|
|
if is64bit then pref:='r' else pref:='e';
|
|
|
|
dwordptr:=@memory[sibbyte+1];
|
|
inc(last); //sib byte
|
|
|
|
LastDisassembleData.Seperators[LastDisassembleData.SeperatorCount]:=last;
|
|
inc(LastDisassembleData.SeperatorCount);
|
|
|
|
|
|
ss:=(memory[sibbyte] shr 6) and 3;
|
|
index:=(memory[sibbyte] shr 3) and 7;
|
|
if Rex_X then index:=index or 8;
|
|
|
|
_mod:=getmod(memory[sibbyte-1]);
|
|
_rm:=getrm(memory[sibbyte-1]);
|
|
|
|
base:=memory[sibbyte] and 7;
|
|
if Rex_B {and (_mod<>0)} then base:=base or 8;
|
|
|
|
|
|
|
|
offset:='';
|
|
|
|
case base of
|
|
0: result:='eax';
|
|
1: result:='ecx';
|
|
2: result:='edx';
|
|
3: result:='ebx';
|
|
4: result:='esp';
|
|
5:
|
|
begin
|
|
if _mod<>0 then result:='ebp';
|
|
end;
|
|
6: result:='esi';
|
|
7: result:='edi';
|
|
8: result:='r8';
|
|
9: result:='r9';
|
|
10: result:='r10';
|
|
11: result:='r11';
|
|
12: result:='r12';
|
|
13: result:='r13';
|
|
14: result:='r14';
|
|
15: result:='r15';
|
|
end;
|
|
if is64bit then
|
|
begin
|
|
if result<>'' then result[1]:='r'; //quick replace
|
|
|
|
|
|
end;
|
|
|
|
if result<>'' then
|
|
result:=colorreg+result+endcolor;
|
|
|
|
if hasvsib=false then
|
|
begin
|
|
case index of
|
|
0: indexstring:='eax';
|
|
1: indexstring:='ecx';
|
|
2: indexstring:='edx';
|
|
3: indexstring:='ebx';
|
|
4: indexstring:='';//'esp';
|
|
5: indexstring:='ebp';
|
|
6: indexstring:='esi';
|
|
7: indexstring:='edi';
|
|
8: indexstring:='r8';
|
|
9: indexstring:='r9';
|
|
10: indexstring:='r10';
|
|
11: indexstring:='r11';
|
|
12: indexstring:='r12';
|
|
13: indexstring:='r13';
|
|
14: indexstring:='r14';
|
|
15: indexstring:='r15';
|
|
else
|
|
indexstring:='';
|
|
end;
|
|
|
|
if is64bit and (addresssize<>32) and (indexstring<>'') then
|
|
indexstring[1]:='r'; //quick replace
|
|
end
|
|
else
|
|
begin
|
|
if opcodeflags.L then
|
|
indexstring:='ymm'+inttostr(index)
|
|
else
|
|
indexstring:='xmm'+inttostr(index);
|
|
end;
|
|
|
|
|
|
|
|
|
|
if indexstring<>'' then
|
|
indexstring:=colorreg+indexstring+endcolor;
|
|
|
|
if (is64bit) and ((base and 7)=5) and (index=4) and (_mod=0) then //disp32
|
|
begin
|
|
//special case for 64-bit
|
|
//sib has a 32-bit displacement value (starting at 0000000000000000)
|
|
LastDisassembleData.modrmValueType:=dvtAddress;
|
|
LastDisassembleData.modrmValue:=dwordptr^;
|
|
|
|
result:=inttohexs(dwordptr^,8);
|
|
last:=last+4;
|
|
exit;
|
|
end
|
|
else
|
|
begin
|
|
|
|
case ss of
|
|
0: LastDisassembleData.sibScaler:=1;
|
|
1: LastDisassembleData.sibScaler:=2;
|
|
2: LastDisassembleData.sibScaler:=4;
|
|
3: LastDisassembleData.sibScaler:=8;
|
|
end;
|
|
|
|
if (ss>0) and (index<>4) then
|
|
indexstring:=indexstring+'*'+colorhex+inttostr(LastDisassembleData.sibScaler)+endcolor;
|
|
|
|
if indexstring<>'' then
|
|
begin
|
|
if result='' then
|
|
result:=indexstring
|
|
else
|
|
result:=result+'+'+indexstring;
|
|
end;
|
|
end;
|
|
|
|
//
|
|
begin
|
|
//mod 0 : [scaled index]+disp32
|
|
//mod 1 : [scaled index]+disp8+ebp
|
|
//mod 2 : [scaled index]+disp32+ebp
|
|
|
|
displacementstring:='';
|
|
case _mod of
|
|
0: //sib with a mod of 0. scaled index + disp32
|
|
begin
|
|
//
|
|
if base=5 then
|
|
begin
|
|
LastDisassembleData.modrmValueType:=dvtValue;
|
|
LastDisassembleData.modrmValue:=ptruint(pinteger(dwordptr)^);
|
|
|
|
if pinteger(dwordptr)^<0 then
|
|
displacementstring:='-'+inttohexs(-pinteger(dwordptr)^,8)
|
|
else
|
|
displacementstring:=inttohexs(pinteger(dwordptr)^,8);
|
|
|
|
last:=last+4;
|
|
end;
|
|
end;
|
|
|
|
1: //scaled index + ebp+ disp 8
|
|
begin
|
|
//displacementstring:=colorreg+'EBP'+endcolor;
|
|
|
|
LastDisassembleData.modrmValueType:=dvtValue;
|
|
LastDisassembleData.modrmValue:=ptruint(pshortint(dwordptr)^);
|
|
|
|
|
|
if pshortint(dwordptr)^<0 then
|
|
displacementstring:='-'+inttohexs(-pshortint(dwordptr)^,2)
|
|
else
|
|
displacementstring:=inttohexs(pshortint(dwordptr)^,2);
|
|
|
|
last:=last+1;
|
|
end;
|
|
|
|
2: //scaled index + ebp+disp 32
|
|
begin
|
|
//displacementstring:=colorreg+'EBP'+endcolor;
|
|
LastDisassembleData.modrmValueType:=dvtValue;
|
|
LastDisassembleData.modrmValue:=ptruint(pinteger(dwordptr)^);
|
|
|
|
if pinteger(dwordptr)^<0 then
|
|
displacementstring:='-'+inttohexs(-pinteger(dwordptr)^,8)
|
|
else
|
|
displacementstring:=inttohexs(pinteger(dwordptr)^,8);
|
|
|
|
last:=last+4;
|
|
end;
|
|
|
|
end;
|
|
|
|
if result='' then
|
|
result:=displacementstring
|
|
else
|
|
begin
|
|
if (displacementstring<>'') then
|
|
begin
|
|
if (displacementstring[1] = '-') then
|
|
result:=result+displacementstring //already starts with a sign
|
|
else
|
|
result:=result+'+'+displacementstring;
|
|
end;
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
LastDisassembleData.hasSib:=true;
|
|
LastDisassembleData.sibIndex:=index;
|
|
|
|
|
|
{$ifdef disassemblerdebug}
|
|
result:=result+' ss='+inttostr(ss)+' index='+inttostr(index)+' base='+inttostr(base);
|
|
{$endif}
|
|
|
|
|
|
end;
|
|
|
|
{$ifndef jni}
|
|
procedure repairbreakbyte(address: ptruint; var b: byte);
|
|
{changes the given byte to the original byte if it is in fact a int3 breakpoint}
|
|
//pre: debuggerthread is valid
|
|
var
|
|
bp: pbreakpoint;
|
|
PA: qword;
|
|
BO: integer;
|
|
begin
|
|
if debuggerthread<>nil then
|
|
begin
|
|
debuggerthread.lockbplist;
|
|
bp:=debuggerthread.isBreakpoint(address);
|
|
if bp<>nil then
|
|
begin
|
|
if (bp.breakpointTrigger=bptExecute) and (bp.breakpointMethod in [bpmInt3, bpmGDB]) then
|
|
b:=bp.originalbyte;
|
|
end;
|
|
debuggerthread.unlockbplist;
|
|
|
|
{$ifdef windows}
|
|
if (frmCodeFilter<>nil) then frmcodefilter.isBreakpoint(address, b);
|
|
{$endif}
|
|
end;
|
|
|
|
{$ifdef windows}
|
|
dbvm_isbreakpoint(address,PA,BO,b);
|
|
{$endif}
|
|
end;
|
|
{$endif}
|
|
|
|
function disassemble(var offset: ptrUint; var description: string): string; overload;
|
|
begin
|
|
result:=defaultDisassembler.disassemble(offset,description);
|
|
end;
|
|
|
|
{$ifdef windows}
|
|
procedure TCR3Disassembler.setCR3(c: QWORD);
|
|
begin
|
|
fcr3:=c and MAXPHYADDRMASKPB;
|
|
end;
|
|
|
|
function TCR3Disassembler.readMemory(address: ptruint; destination: pointer; size: integer): integer;
|
|
var actualread: ptruint;
|
|
begin
|
|
ReadProcessMemoryCR3(fcr3,pointer(address), destination, size, actualread);
|
|
result:=actualread;
|
|
end;
|
|
{$endif}
|
|
|
|
function TDisassembler.readMemory(address: ptruint; destination: pointer; size: integer): integer;
|
|
//reads the bytes at the given address and returns the number of bytes read
|
|
//in regards to the cloaked memory support, this is ONLY for the disassembler, to show the fuckery that's going on
|
|
var
|
|
actualread: ptruint;
|
|
|
|
i,p1,p2,p3: integer;
|
|
begin
|
|
actualread:=0;
|
|
|
|
{$ifdef windows}
|
|
ReadProcessMemoryWithCloakSupport(processhandle,pointer(address),destination,size,actualread);
|
|
{$else}
|
|
ReadProcessMemory(processhandle,pointer(address),destination,size,actualread);
|
|
{$endif}
|
|
if (actualread=0) and ((address+size and qword($fffffffffffff000))>(address and qword($fffffffffffff000))) then //did not read a single byte and overlaps a pageboundary
|
|
begin
|
|
p1:=0;
|
|
repeat
|
|
i:=min(size, integer(4096-(address and $fff)));
|
|
actualread:=0;
|
|
{$ifdef windows}
|
|
ReadProcessMemoryWithCloakSupport(processhandle,pointer(address),destination,i,actualread);
|
|
{$else}
|
|
ReadProcessMemory(processhandle,pointer(address),destination,i,actualread);
|
|
{$endif}
|
|
|
|
inc(p1,actualread);
|
|
address:=address+actualread;
|
|
size:=size-actualread;
|
|
destination:=pointer(ptruint(destination)+actualread);
|
|
until (actualread=0) or (size=0);
|
|
|
|
exit(p1);
|
|
end
|
|
else
|
|
result:=actualread;
|
|
end;
|
|
|
|
function TDisassembler.disassemble(var offset: ptrUint): string;
|
|
var ignore: string;
|
|
begin
|
|
result:=disassemble(offset, ignore);
|
|
end;
|
|
|
|
function TDisassembler.disassemble(var offset: ptrUint; var description: string): string;
|
|
var
|
|
actualread: PtrUInt;
|
|
startoffset, initialoffset: ptrUint;
|
|
tempresult, tempdescription: string;
|
|
equationstr: string;
|
|
tempst: string;
|
|
wordptr: ^word;
|
|
dwordptr: ^dword;
|
|
dwordptr2: ^dword;
|
|
singleptr: ^single;
|
|
doubleptr: ^double;
|
|
extenedptr: ^extended;
|
|
int64ptr: ^int64;
|
|
i,j,k: integer;
|
|
|
|
|
|
isprefix: boolean;
|
|
|
|
last: dword;
|
|
foundit: boolean;
|
|
|
|
tempaddress: ptrUint;
|
|
prefixsize: integer;
|
|
mi: TModuleInfo;
|
|
VA,PA: QWORD;
|
|
noVEXPossible: boolean=false;
|
|
bytestomove: integer;
|
|
|
|
memory: PBytearray;
|
|
|
|
td: dword;
|
|
breaknow: boolean;
|
|
begin
|
|
|
|
hasvsib:=false;
|
|
ZeroMemory(@opcodeflags,sizeof(opcodeflags));
|
|
opcodeflags.extrareginstoverride:=-1;
|
|
|
|
if (self = visibleDisassembler) and (GetCurrentThreadId<>MainThreadID) then
|
|
begin
|
|
offset:=1;
|
|
description:='Should not happen';
|
|
exit('Visible disassembler used in an external thread');
|
|
end;
|
|
|
|
{
|
|
if firstthread=0 then
|
|
firstthread:=GetCurrentThreadId;
|
|
|
|
if firstthread<>GetCurrentThreadId then
|
|
asm
|
|
nop
|
|
end; }
|
|
|
|
try
|
|
{if cs.TryEnter=false then
|
|
begin
|
|
if GetCurrentThreadId=MainThreadID then
|
|
MessageDlg('Multiple threads have accessed the same disassembler object at the same time. Do not do this', mtError,[mbok],0);
|
|
|
|
OutputDebugString('Multiple threads are using the disassembler');
|
|
cs.enter;
|
|
end; }
|
|
|
|
// cs.enter;
|
|
|
|
//try
|
|
debugpart:=0;
|
|
|
|
LastDisassembleData.isfloat:=false;
|
|
LastDisassembleData.isfloat64:=false;
|
|
LastDisassembleData.iscloaked:=false;
|
|
LastDisassembleData.commentsoverride:='';
|
|
{$ifdef windows}
|
|
if defaultBinutils<>nil then
|
|
begin
|
|
//use this
|
|
LastDisassembleData.address:=offset;
|
|
LastDisassembleData.SeperatorCount:=0;
|
|
defaultBinutils.disassemble(LastDisassembleData);
|
|
|
|
result:=inttohex(LastDisassembleData.address,8);
|
|
result:=result+' - ';
|
|
for i:=0 to length(LastDisassembleData.bytes)-1 do
|
|
result:=result+inttohex(LastDisassembleData.Bytes[i],2)+' ';
|
|
|
|
result:=result+' - ';
|
|
result:=result+LastDisassembleData.opcode;
|
|
result:=result+' ';
|
|
result:=result+LastDisassembleData.parameters;
|
|
|
|
if length(LastDisassembleData.bytes)>0 then
|
|
inc(offset,length(LastDisassembleData.bytes))
|
|
else
|
|
begin
|
|
if processhandler.SystemArchitecture=archArm then
|
|
begin
|
|
if (offset or 1)=1 then
|
|
inc(offset,2)
|
|
else
|
|
inc(offset,4);
|
|
end
|
|
else
|
|
inc(offset,1);
|
|
end;
|
|
|
|
exit;
|
|
end;
|
|
{$endif}
|
|
if is64bitOverride then
|
|
is64bit:=is64BitOverrideState
|
|
else
|
|
begin
|
|
is64bit:=processhandler.is64bit;
|
|
{$ifdef cpu64}
|
|
if offset>=QWORD($100000000) then
|
|
is64bit:=true;
|
|
{$endif}
|
|
|
|
if symhandler.getmodulebyaddress(offset, mi) then
|
|
begin
|
|
is64bit:=mi.is64bitmodule;
|
|
if not is64bit then
|
|
asm
|
|
nop
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
if (architecture=darchARM) or ((processhandler.SystemArchitecture=archarm) and (architecture=darchAutoDetect) ) then //todo: look at the module info
|
|
begin
|
|
|
|
|
|
result:=ArmDisassembler.disassemble(offset);
|
|
LastDisassembleData:=armdisassembler.LastDisassembleData;
|
|
exit;
|
|
end;
|
|
|
|
modrmposition:=mNone;
|
|
|
|
debugpart:=1;
|
|
|
|
last:=0;
|
|
tempresult:='';
|
|
setlength(LastDisassembleData.bytes,0);
|
|
LastDisassembleData.address:=Offset;
|
|
LastDisassembleData.SeperatorCount:=0;
|
|
LastDisassembleData.prefix:='';
|
|
LastDisassembleData.PrefixSize:=0;
|
|
LastDisassembleData.opcode:='';
|
|
LastDisassembleData.parameters:='';
|
|
lastdisassembledata.isjump:=false;
|
|
lastdisassembledata.iscall:=false;
|
|
lastdisassembledata.isret:=false;
|
|
LastDisassembleData.isrep:=false;
|
|
lastdisassembledata.isconditionaljump:=false;
|
|
lastdisassembledata.modrmValueType:=dvtNone;
|
|
lastdisassembledata.parameterValueType:=dvtNone;
|
|
LastDisassembleData.hasSib:=false;
|
|
LastDisassembleData.datasize:=0;
|
|
LastDisassembleData.riprelative:=0;
|
|
|
|
if assigned(OnDisassembleOverride) then //check if the user has defined it's own disassembler
|
|
begin
|
|
//if so, call the OnDisassemble propery, and if it returns true don't handle the original
|
|
if OnDisassembleOverride(self, offset, LastDisassembleData, result, description) then
|
|
begin
|
|
if length(lastdisassembledata.Bytes)=0 then //BAD!
|
|
setlength(lastdisassembledata.Bytes,1);
|
|
|
|
inc(offset, length(lastdisassembledata.Bytes));
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
//also check global overrides
|
|
for i:=0 to length(GlobalDisassembleOverrides)-1 do
|
|
begin
|
|
if assigned(GlobalDisassembleOverrides[i]) then
|
|
begin
|
|
if GlobalDisassembleOverrides[i](self, offset, LastDisassembleData, result, description) then
|
|
begin
|
|
if length(lastdisassembledata.Bytes)=0 then //BAD!
|
|
setlength(lastdisassembledata.Bytes,1);
|
|
|
|
inc(offset, length(lastdisassembledata.Bytes));
|
|
exit;
|
|
end;
|
|
end;
|
|
end;
|
|
debugpart:=2;
|
|
|
|
|
|
|
|
if isdefault then
|
|
begin
|
|
showsymbols:=symhandler.showsymbols;
|
|
showmodules:=symhandler.showmodules;
|
|
end;
|
|
|
|
if showsymbols or showmodules then
|
|
intToHexs:=inttohexs_withsymbols
|
|
else
|
|
intToHexs:=inttohexs_withoutsymbols;
|
|
|
|
riprelative:=false;
|
|
|
|
if dataonly then
|
|
result:=''
|
|
else
|
|
result:=inttohex(offset,8)+' - ';
|
|
|
|
isprefix:=true;
|
|
|
|
|
|
prefix:=[$f0,$f2,$f3,$2e,$36,$3e,$26,$64,$65,$66,$67];
|
|
prefix2:=[];
|
|
|
|
startoffset:=offset;
|
|
initialoffset:=offset;
|
|
|
|
for i:=32 to 63 do //debug code
|
|
_memory[i]:=$ce;
|
|
|
|
actualRead:=readMemory(offset, @_memory[0], 32);
|
|
memory:=@_memory[0];
|
|
|
|
debugpart:=3;
|
|
|
|
if (actualread>0) and (actualread<=32) then
|
|
begin
|
|
|
|
{$ifndef jni}
|
|
if debuggerthread<>nil then
|
|
for i:=0 to actualread-1 do
|
|
if memory[i]=$cc then
|
|
repairbreakbyte(offset+i, memory[i]);
|
|
{$endif}
|
|
|
|
debugpart:=4;
|
|
|
|
while isprefix do
|
|
begin
|
|
inc(offset); //offset will always inc by 1
|
|
if memory[0] in prefix then
|
|
begin
|
|
if length(LastDisassembleData.bytes)>10 then
|
|
begin
|
|
//prevent a too long prefix from crashing the disassembler (e.g 12GB filled with one prefix....)
|
|
isprefix:=false;
|
|
break;
|
|
end;
|
|
setlength(LastDisassembleData.bytes,length(LastDisassembleData.bytes)+1);
|
|
LastDisassembleData.bytes[length(LastDisassembleData.bytes)-1]:=memory[0];
|
|
|
|
|
|
if not dataonly then
|
|
result:=result+inttohexs(memory[0],2)+' ';
|
|
|
|
isprefix:=true;
|
|
inc(startoffset);
|
|
prefix2:=prefix2+[memory[0]];
|
|
|
|
memory:=@memory[1];
|
|
if offset>initialoffset+24 then //too long
|
|
begin
|
|
description:='';
|
|
LastDisassembleData.opcode:='??';
|
|
offset:=initialoffset+1;
|
|
exit;
|
|
end;
|
|
|
|
end else isprefix:=false;
|
|
end;
|
|
|
|
if $F0 in prefix2 then
|
|
begin
|
|
tempresult:='lock ';
|
|
noVEXPossible:=true;
|
|
end;
|
|
|
|
if $F2 in prefix2 then
|
|
begin
|
|
tempresult:=tempresult+'repne ';
|
|
noVEXPossible:=true;
|
|
LastDisassembleData.isrep:=true;
|
|
end;
|
|
|
|
if $f3 in prefix2 then
|
|
begin
|
|
tempresult:=tempresult+'repe ';
|
|
noVEXPossible:=true;
|
|
LastDisassembleData.isrep:=true;
|
|
end;
|
|
|
|
LastDisassembleData.prefix:=tempresult;
|
|
|
|
debugpart:=5;
|
|
|
|
|
|
|
|
RexPrefix:=0;
|
|
if is64bit then
|
|
begin
|
|
if memory[0] in [$40..$4f] then //does it start with a rex prefix ?
|
|
begin
|
|
debugpart:=6;
|
|
setlength(LastDisassembleData.bytes,length(LastDisassembleData.bytes)+1);
|
|
LastDisassembleData.bytes[length(LastDisassembleData.bytes)-1]:=memory[0];
|
|
|
|
RexPrefix:=memory[0];
|
|
opcodeflags.B:=(RexPrefix and BIT_REX_B)=BIT_REX_B;
|
|
opcodeflags.X:=(RexPrefix and BIT_REX_X)=BIT_REX_X;
|
|
opcodeflags.R:=(RexPrefix and BIT_REX_R)=BIT_REX_R;
|
|
opcodeflags.W:=(RexPrefix and BIT_REX_W)=BIT_REX_W;
|
|
|
|
|
|
if not dataonly then
|
|
result:=result+inttohexs(RexPrefix,2)+' ';
|
|
|
|
inc(offset);
|
|
inc(startoffset);
|
|
prefix2:=prefix2+[RexPrefix];
|
|
|
|
memory:=@memory[1];
|
|
noVEXPossible:=true;
|
|
debugpart:=7;
|
|
|
|
if offset>initialoffset+24 then
|
|
begin
|
|
description:='';
|
|
LastDisassembleData.opcode:='??';
|
|
offset:=initialoffset+1;
|
|
exit;
|
|
end;
|
|
end
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
prefixsize:=length(LastDisassembleData.bytes);
|
|
LastDisassembleData.prefixsize:=prefixsize;
|
|
|
|
debugpart:=8;
|
|
if (noVEXPossible=false) and (memory[0] in [$c4,$c5]) then
|
|
begin
|
|
debugpart:=9;
|
|
hasVEX:=true;
|
|
|
|
if memory[0]=$c5 then
|
|
begin
|
|
//2 byte VEX
|
|
inc(prefixsize,2);
|
|
opcodeflags.pp:=PVex2Byte(@memory[1])^.pp;
|
|
opcodeflags.L:=PVex2Byte(@memory[1])^.L=1;
|
|
opcodeflags.vvvv:=PVex2Byte(@memory[1])^.vvvv;
|
|
opcodeflags.R:=PVex2Byte(@memory[1])^.R=0;
|
|
opcodeflags.mmmmm:=1;
|
|
|
|
i:=length(LastDisassembleData.bytes);
|
|
|
|
setlength(LastDisassembleData.bytes,length(LastDisassembleData.bytes)+2);
|
|
LastDisassembleData.bytes[i]:=memory[0];
|
|
LastDisassembleData.bytes[i+1]:=memory[1];
|
|
|
|
memory[1]:=$0f;
|
|
bytestomove:=1;
|
|
memory:=@memory[1];
|
|
|
|
inc(offset,1);
|
|
end
|
|
else
|
|
begin
|
|
//3 byte vex
|
|
inc(prefixsize,3);
|
|
opcodeflags.pp:=PVex3Byte(@memory[1])^.pp;
|
|
opcodeflags.L:=PVex3Byte(@memory[1])^.L=1;
|
|
opcodeflags.vvvv:=PVex3Byte(@memory[1])^.vvvv;
|
|
opcodeflags.W:=PVex3Byte(@memory[1])^.W=1; //this one is NOT inverted
|
|
opcodeflags.mmmmm:=PVex3Byte(@memory[1])^.mmmmm;
|
|
opcodeflags.B:=PVex3Byte(@memory[1])^.B=0;
|
|
opcodeflags.X:=PVex3Byte(@memory[1])^.X=0;
|
|
opcodeflags.R:=PVex3Byte(@memory[1])^.R=0;
|
|
|
|
i:=length(LastDisassembleData.bytes);
|
|
setlength(LastDisassembleData.bytes,i+3);
|
|
LastDisassembleData.bytes[i]:=memory[0];
|
|
LastDisassembleData.bytes[i+1]:=memory[1];
|
|
LastDisassembleData.bytes[i+2]:=memory[2];
|
|
|
|
{ mmmmm:
|
|
00000: Reserved for future use (will #UD)
|
|
00001: implied 0F leading opcode byte
|
|
00010: implied 0F 38 leading opcode bytes
|
|
00011: implied 0F 3A leading opcode bytes
|
|
00100-11111: Reserved for future use (will #UD)
|
|
}
|
|
|
|
bytestomove:=3; //number of bytes to shift
|
|
case opcodeflags.mmmmm of
|
|
1:
|
|
begin
|
|
bytestomove:=2;
|
|
memory[2]:=$0f;
|
|
end;
|
|
|
|
2:
|
|
begin
|
|
bytestomove:=1;
|
|
memory[1]:=$0f;
|
|
memory[2]:=$38;
|
|
end;
|
|
|
|
3:
|
|
begin
|
|
bytestomove:=1;
|
|
memory[1]:=$0f;
|
|
memory[2]:=$3a;
|
|
end; //else invalid
|
|
end;
|
|
|
|
memory:=@memory[bytestomove];
|
|
inc(offset,bytestomove);
|
|
end;
|
|
|
|
case opcodeflags.pp of
|
|
1: prefix2:=prefix2+[$66];
|
|
2: prefix2:=prefix2+[$f3];
|
|
3: prefix2:=prefix2+[$f2];
|
|
end;
|
|
end else hasVEX:=false;
|
|
|
|
debugpart:=10;
|
|
|
|
//compatibility fix for code that still checks for rex.* or sets it as a temporary flag replacement
|
|
RexPrefix:=ifthen(opcodeflags.B, rexprefix or BIT_REX_B, rexprefix);
|
|
RexPrefix:=ifthen(opcodeflags.X, rexprefix or BIT_REX_X, rexprefix);
|
|
RexPrefix:=ifthen(opcodeflags.R, rexprefix or BIT_REX_R, rexprefix);
|
|
RexPrefix:=ifthen(opcodeflags.W, rexprefix or BIT_REX_W, rexprefix);
|
|
|
|
debugpart:=11;
|
|
case memory[0] of //opcode
|
|
$00 : begin
|
|
|
|
|
|
if (aggressivealignment and (((offset) and $f)=0) and (memory[1]<>0) ) or ((memory[1]=$55) and (memory[2]=$89) and (memory[3]=$e5)) then
|
|
begin
|
|
description:='Filler';
|
|
lastdisassembledata.opcode:='db';
|
|
LastDisassembleData.parameters:=inttohex(memory[0],2);
|
|
end
|
|
else
|
|
begin
|
|
description:='Add';
|
|
|
|
lastdisassembledata.opcode:='add';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last)+r8(memory[1]);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$01 : begin
|
|
description:='Add';
|
|
|
|
lastdisassembledata.opcode:='add';
|
|
if $66 in prefix2 then lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last)+r16(memory[1]) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last)+r32(memory[1]);
|
|
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$02 : begin
|
|
description:='Add';
|
|
|
|
LastDisassembleData.opcode:='add';
|
|
LastDisassembleData.parameters:=r8(memory[1])+MODRM(memory,prefix2,1,2,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$03 : begin
|
|
description:='Add';
|
|
LastDisassembleData.opcode:='add';
|
|
if $66 in prefix2 then LastDisassembleData.parameters:=r16(memory[1])+MODRM(memory,prefix2,1,1,last, mright) else
|
|
LastDisassembleData.parameters:=r32(memory[1])+MODRM(memory,prefix2,1,0,last, mright);
|
|
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
|
|
|
|
$04 : begin
|
|
description:='Add '+inttohex(memory[1],2)+' to AL';
|
|
LastDisassembleData.opcode:='add';
|
|
LastDisassembleData.parameterValueType:=dvtValue;
|
|
LastDisassembleData.parameterValue:=memory[1];
|
|
LastDisassembleData.parameters:=colorreg+'al'+endcolor+','+inttohexs(memory[1],2);
|
|
|
|
LastDisassembleData.Seperators[LastDisassembleData.SeperatorCount]:=1;
|
|
inc(LastDisassembleData.SeperatorCount);
|
|
|
|
inc(offset);
|
|
end;
|
|
|
|
$05 : begin
|
|
lastdisassembledata.opcode:='add';
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
|
|
|
|
wordptr:=@memory[1];
|
|
dwordptr:=@memory[1];
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
lastdisassembledata.parameters:=colorreg+'ax'+endcolor+','+inttohexs(wordptr^,4);
|
|
|
|
description:='add '+inttohex(wordptr^,4)+' to ax';
|
|
|
|
|
|
|
|
inc(offset,2);
|
|
end else
|
|
begin
|
|
if rex_w then
|
|
begin
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
lastdisassembledata.parameters:=colorreg+'rax'+endcolor+','+inttohexs(longint(dwordptr^),8);
|
|
|
|
description:='add '+inttohex(dwordptr^,8)+' to rax (sign extended)';
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
lastdisassembledata.parameters:=colorreg+'eax'+endcolor+','+inttohexs(dwordptr^,8);
|
|
|
|
description:='add '+inttohex(dwordptr^,8)+' to eax';
|
|
end;
|
|
inc(offset,4);
|
|
end;
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
end;
|
|
|
|
$06 : begin
|
|
lastdisassembledata.opcode:='push';
|
|
lastdisassembledata.parameters:=colorreg+'es'+endcolor;
|
|
description:='place es on the stack';
|
|
end;
|
|
|
|
$07 : begin
|
|
lastdisassembledata.opcode:='pop';
|
|
lastdisassembledata.parameters:=colorreg+'es'+endcolor;
|
|
description:='remove es from the stack';
|
|
end;
|
|
|
|
$08 : begin
|
|
description:='logical inclusive or';
|
|
lastdisassembledata.opcode:='or';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last)+r8(memory[1]);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$09 : begin
|
|
description:='logical inclusive or';
|
|
lastdisassembledata.opcode:='or';
|
|
if $66 in prefix2 then lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last)+r16(memory[1]) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last)+r32(memory[1]);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$0a : begin
|
|
description:='logical inclusive or';
|
|
lastdisassembledata.opcode:='or';
|
|
lastdisassembledata.parameters:=r8(memory[1])+modrm(memory,prefix2,1,2,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$0b : begin
|
|
description:='logical inclusive or';
|
|
lastdisassembledata.opcode:='or';
|
|
if $66 in prefix2 then lastdisassembledata.parameters:=r16(memory[1])+modrm(memory,prefix2,1,1,last, mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[1])+modrm(memory,prefix2,1,0,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$0c : begin
|
|
description:='logical inclusive or';
|
|
lastdisassembledata.opcode:='or';
|
|
lastdisassembledata.parameters:=colorreg+'al'+endcolor+','+inttohexs(memory[1],2);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[1];
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
inc(offset);
|
|
end;
|
|
|
|
$0d : begin
|
|
description:='logical inclusive or';
|
|
lastdisassembledata.opcode:='or';
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
|
|
if $66 in prefix2 then
|
|
begin
|
|
wordptr:=@memory[1];
|
|
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
lastdisassembledata.parameters:=colorreg+'ax'+endcolor+','+inttohexs(lastdisassembledata.parametervalue,4);
|
|
|
|
inc(offset,2);
|
|
end
|
|
else
|
|
begin
|
|
dwordptr:=@memory[1];
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
|
|
if rex_w then
|
|
begin
|
|
lastdisassembledata.parameters:=colorreg+'rax'+endcolor+','+inttohexs(longint(lastdisassembledata.parametervalue),8);
|
|
description:=description+' (sign-extended)';
|
|
end
|
|
else
|
|
lastdisassembledata.parameters:=colorreg+'eax'+endcolor+','+inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
inc(offset,4);
|
|
end;
|
|
end;
|
|
|
|
$0e : begin
|
|
description:='place cs on the stack';
|
|
lastdisassembledata.opcode:='push';
|
|
lastdisassembledata.parameters:=colorreg+'cs'+endcolor;
|
|
end;
|
|
|
|
$0f : begin //simd extensions
|
|
if $f0 in prefix2 then
|
|
lastdisassembledata.prefix:='lock '
|
|
else
|
|
lastdisassembledata.prefix:=''; //these usually treat the f2/f3 prefix differently
|
|
|
|
case memory[1] of
|
|
$00 : begin
|
|
case getreg(memory[2]) of
|
|
0: begin
|
|
lastdisassembledata.opcode:='sldt';
|
|
description:='store local descriptor table register';
|
|
if $66 in prefix2 then lastdisassembledata.parameters:=modrm(memory,prefix2,2,1,last,16) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
1: begin
|
|
description:='store task register';
|
|
lastdisassembledata.opcode:='str';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,1,last,16);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
2: begin
|
|
description:='load local descriptor table register';
|
|
lastdisassembledata.opcode:='lldt';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,1,last,16);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
3: begin
|
|
description:='load task register';
|
|
lastdisassembledata.opcode:='ltr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,1,last,16);
|
|
inc(offset,last-1); ;
|
|
end;
|
|
|
|
4: begin
|
|
description:='verify a segment for reading';
|
|
lastdisassembledata.opcode:='verr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,1,last,16);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
5: begin
|
|
description:='verify a segment for writing';
|
|
lastdisassembledata.opcode:='verw';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,1,last,16);
|
|
inc(offset,last-1);
|
|
end;
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='db';
|
|
LastDisassembleData.parameters:=inttohex(memory[0],2);
|
|
description:='not specified by the intel documentation';
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
$01 : begin
|
|
case memory[2] of
|
|
$c1:
|
|
begin
|
|
description:='call to vm monitor by causing vm exit';
|
|
lastdisassembledata.opcode:='vmcall';
|
|
inc(offset,2);
|
|
end;
|
|
|
|
$c2:
|
|
begin
|
|
description:='launch virtual machine managed by current vmcs';
|
|
lastdisassembledata.opcode:='vmlaunch';
|
|
inc(offset,2);
|
|
end;
|
|
|
|
$c3:
|
|
begin
|
|
description:='resume virtual machine managed by current vmcs';
|
|
lastdisassembledata.opcode:='vmresume';
|
|
inc(offset,2);
|
|
end;
|
|
|
|
$c4:
|
|
begin
|
|
description:='leaves vmx operation';
|
|
lastdisassembledata.opcode:='vmxoff';
|
|
inc(offset,2);
|
|
end;
|
|
|
|
$c8:
|
|
begin
|
|
description:='set up monitor address';
|
|
lastdisassembledata.opcode:='monitor';
|
|
inc(offset,2);
|
|
end;
|
|
|
|
$c9:
|
|
begin
|
|
description:='Monitor wait';
|
|
lastdisassembledata.opcode:='mwait';
|
|
inc(offset,2);
|
|
end;
|
|
|
|
$ca:
|
|
begin
|
|
description:='Clear AC flag in EFLAGS register';
|
|
lastdisassembledata.opcode:='clac';
|
|
inc(offset,2);
|
|
end;
|
|
|
|
$d0:
|
|
begin
|
|
description:='Get value of extended control register';
|
|
lastdisassembledata.opcode:='xgetbv';
|
|
inc(offset,2);
|
|
end;
|
|
|
|
$d1:
|
|
begin
|
|
description:='Set value of extended control register';
|
|
lastdisassembledata.opcode:='xsetbv';
|
|
inc(offset,2);
|
|
end;
|
|
|
|
$d5:
|
|
begin
|
|
description:='Transactional end';
|
|
lastdisassembledata.opcode:='xend';
|
|
inc(offset,2);
|
|
end;
|
|
|
|
$d6:
|
|
begin
|
|
description:='Test if in transactional execution';
|
|
lastdisassembledata.opcode:='xtest';
|
|
inc(offset,2);
|
|
end;
|
|
|
|
$f8:
|
|
begin
|
|
description:='Swap GS base register';
|
|
lastdisassembledata.opcode:='swapgs';
|
|
inc(offset,2);
|
|
end;
|
|
|
|
$f9:
|
|
begin
|
|
description:='Read time-stamp counter and processor ID';
|
|
lastdisassembledata.opcode:='rdtscp';
|
|
inc(offset,2);
|
|
end;
|
|
|
|
else
|
|
begin
|
|
case getreg(memory[2]) of
|
|
0:
|
|
begin
|
|
description:='store global descriptor table register';
|
|
lastdisassembledata.opcode:='sgdt';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
1:
|
|
begin
|
|
description:='store interrupt descriptor table register';
|
|
lastdisassembledata.opcode:='sidt';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
2:
|
|
begin
|
|
description:='load global descriptor table register';
|
|
lastdisassembledata.opcode:='lgdt';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
3:
|
|
begin
|
|
description:='load interupt descriptor table register';
|
|
lastdisassembledata.opcode:='lidt';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
4:
|
|
begin
|
|
description:='store machine status word';
|
|
lastdisassembledata.opcode:='smsw';
|
|
|
|
if $66 in prefix2 then lastdisassembledata.parameters:=modrm(memory,prefix2,2,1,last)
|
|
else lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
6:
|
|
begin
|
|
description:='load machine status word';
|
|
lastdisassembledata.opcode:='lmsw';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,1,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
7:
|
|
begin
|
|
description:='invalidate tlb entry';
|
|
lastdisassembledata.opcode:='invplg';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$02 : begin
|
|
description:='load access rights byte';
|
|
lastdisassembledata.opcode:='lar';
|
|
if $66 in prefix2 then lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last, mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,2,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
{0f}$03 : begin
|
|
description:='load segment limit';
|
|
lastdisassembledata.opcode:='lsl';
|
|
if $66 in prefix2 then lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last, mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,2,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$05 : begin
|
|
description:='fast system call';
|
|
lastdisassembledata.opcode:='syscall';
|
|
inc(offset);
|
|
end;
|
|
|
|
$06 : begin
|
|
description:='clear task-switched flag in cr0';
|
|
lastdisassembledata.opcode:='clts';
|
|
inc(offset);
|
|
end;
|
|
|
|
$07 : begin
|
|
description:='return from fast system call';
|
|
lastdisassembledata.opcode:='sysret';
|
|
inc(offset);
|
|
end;
|
|
|
|
$08 : begin
|
|
description:='invalidate internal caches';
|
|
lastdisassembledata.opcode:='invd';
|
|
inc(offset);
|
|
end;
|
|
|
|
$09 : begin
|
|
description:='write back and invalidate cache';
|
|
lastdisassembledata.opcode:='wbinvd';
|
|
inc(offset);
|
|
end;
|
|
|
|
$0b : begin
|
|
description:='undefined instruction(yes, this one really excists..)';
|
|
lastdisassembledata.opcode:='ud2';
|
|
inc(offset);
|
|
end;
|
|
|
|
$0d : begin
|
|
case getreg(memory[2]) of
|
|
1: begin
|
|
description:='Prefetch Data into Caches in Anticipation of a Write';
|
|
lastdisassembledata.opcode:='prefetchw';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,2,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
2: begin
|
|
description:='Prefetch Vector Data Into Caches with Intent to Write and T1 Hint';
|
|
lastdisassembledata.opcode:='prefetchwt1';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,2,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
$10 : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
|
|
if $f2 in prefix2 then
|
|
begin
|
|
description:='move scalar double-fp';
|
|
opcodeflags.L:=false; //LIG
|
|
opcodeflags.skipExtraRegOnMemoryAccess:=true;
|
|
lastdisassembledata.isfloat64:=true;
|
|
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovsd'
|
|
else
|
|
lastdisassembledata.opcode:='movsd';
|
|
|
|
opcodeflags.skipExtraRegOnMemoryAccess:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $f3 in prefix2 then
|
|
begin
|
|
description:='move scalar single-fp';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovss'
|
|
else
|
|
lastdisassembledata.opcode:='movss';
|
|
|
|
opcodeflags.skipExtraRegOnMemoryAccess:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mright);
|
|
lastdisassembledata.datasize:=4;
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='move unaligned packed double-fp';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='lmovupd'
|
|
else
|
|
lastdisassembledata.opcode:='movupd';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='move unaligned four packed single-fp';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovups'
|
|
else
|
|
lastdisassembledata.opcode:='movups';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mright);
|
|
lastdisassembledata.datasize:=4;
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$11 : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
if $f2 in prefix2 then
|
|
begin
|
|
description:='move scalar double-fp';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovsd'
|
|
else
|
|
lastdisassembledata.opcode:='movsd';
|
|
|
|
lastdisassembledata.isfloat64:=true;
|
|
|
|
opcodeflags.skipExtraRegOnMemoryAccess:=true;
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,4,last,mLeft)+xmm(memory[2]);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $f3 in prefix2 then
|
|
begin
|
|
description:='move scalar single-fp';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovss'
|
|
else
|
|
lastdisassembledata.opcode:='movss';
|
|
|
|
opcodeflags.skipExtraRegOnMemoryAccess:=true;
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,4,last)+xmm(memory[2]);
|
|
lastdisassembledata.datasize:=4;
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='move unaligned packed double-fp';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='lmovupd'
|
|
else
|
|
lastdisassembledata.opcode:='movupd';
|
|
|
|
opcodeflags.skipExtraRegOnMemoryAccess:=true;
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,4,last)+xmm(memory[2]);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='move unaligned four packed single-fp';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovups'
|
|
else
|
|
lastdisassembledata.opcode:='movups';
|
|
|
|
opcodeflags.skipExtraRegOnMemoryAccess:=true;
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,4,last)+xmm(memory[2]);
|
|
lastdisassembledata.datasize:=4;
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
end;
|
|
|
|
{0f}$12 : begin
|
|
if $f2 in prefix2 then
|
|
begin
|
|
description:='move one double-fp and duplicate';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovddup'
|
|
else
|
|
lastdisassembledata.opcode:='movddup';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $f3 in prefix2 then
|
|
begin
|
|
description:='move packed single-fp Low and duplicate';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovsldup'
|
|
else
|
|
lastdisassembledata.opcode:='movsldup';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='move low packed double-precision floating-point value';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovlpd'
|
|
else
|
|
lastdisassembledata.opcode:='movlpd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='high to low packed single-fp';
|
|
|
|
if getmod(memory[2])=3 then
|
|
lastdisassembledata.opcode:='movhlps'
|
|
else
|
|
lastdisassembledata.opcode:='movlps';
|
|
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='v'+lastdisassembledata.opcode;
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$13 : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='move low packed double-fp';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovlpd'
|
|
else
|
|
lastdisassembledata.opcode:='movlpd';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,4,last)+xmm(memory[2]);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='move low packed single-fp';
|
|
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovlps'
|
|
else
|
|
lastdisassembledata.opcode:='movlps';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,4,last)+xmm(memory[2]);
|
|
lastdisassembledata.datasize:=4;
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}$14 : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='unpack low packed single-fp';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vunpcklpd'
|
|
else
|
|
lastdisassembledata.opcode:='unpcklpd';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='unpack low packed single-fp';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vunpcklps'
|
|
else
|
|
lastdisassembledata.opcode:='unpcklps';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$15 : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='unpack and interleave high packed double-fp';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vunpckhpd'
|
|
else
|
|
lastdisassembledata.opcode:='unpckhpd';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='unpack high packed single-fp';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='unpckhps'
|
|
else
|
|
lastdisassembledata.opcode:='unpckhps';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$16 : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
if $f3 in prefix2 then
|
|
begin
|
|
description:='move packed single-fp high and duplicate';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovshdup'
|
|
else
|
|
lastdisassembledata.opcode:='movshdup';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='move high packed double-precision floating-point value';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovhpd'
|
|
else
|
|
lastdisassembledata.opcode:='movhpd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='high to low packed single-fp';
|
|
|
|
if getmod(memory[2])=3 then
|
|
lastdisassembledata.opcode:='movlhps'
|
|
else
|
|
lastdisassembledata.opcode:='movhps';
|
|
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='v'+lastdisassembledata.opcode;
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$17 : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='move high packed double-precision floating-point value';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovhpd'
|
|
else
|
|
lastdisassembledata.opcode:='movhpd';
|
|
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,4,last)+xmm(memory[2]);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='high to low packed single-fp';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovhps'
|
|
else
|
|
lastdisassembledata.opcode:='movhps';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,4,last)+xmm(memory[2]);
|
|
lastdisassembledata.datasize:=4;
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$18 : begin
|
|
case getreg(memory[2]) of
|
|
0: begin
|
|
description:='prefetch';
|
|
lastdisassembledata.opcode:='prefetchnta';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,2,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
1: begin
|
|
description:='prefetch';
|
|
lastdisassembledata.opcode:='prefetchto';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,2,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
2: begin
|
|
description:='prefetch';
|
|
lastdisassembledata.opcode:='prefetcht1';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,2,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
3: begin
|
|
description:='prefetch';
|
|
lastdisassembledata.opcode:='prefetcht2';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,2,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
|
|
$1f: begin
|
|
case getreg(memory[2]) of
|
|
0: begin
|
|
description:='multibyte nop';
|
|
lastdisassembledata.opcode:='nop';
|
|
|
|
|
|
if Rex_W then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last,64)
|
|
else
|
|
begin
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last,16)
|
|
else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last,32)
|
|
end;
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
$20 : begin
|
|
description:='move from control register';
|
|
lastdisassembledata.opcode:='mov';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last)+cr(memory[2]);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$21 : begin
|
|
description:='move from debug register';
|
|
lastdisassembledata.opcode:='mov';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last)+dr(memory[2]);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$22 : begin
|
|
description:='move to control register';
|
|
lastdisassembledata.opcode:='mov';
|
|
lastdisassembledata.parameters:=cr(memory[2])+modrm(memory,prefix2,2,0,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$23 : begin
|
|
description:='move to debug register';
|
|
lastdisassembledata.opcode:='mov';
|
|
lastdisassembledata.parameters:=dr(memory[2])+modrm(memory,prefix2,2,0,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$28 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='move aligned packed double-fp values';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovapd'
|
|
else
|
|
lastdisassembledata.opcode:='movapd';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='move aligned four packed single-fp';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovaps'
|
|
else
|
|
lastdisassembledata.opcode:='movaps';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$29 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='move aligned packed double-fp values';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovapd'
|
|
else
|
|
lastdisassembledata.opcode:='movapd';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,4,last)+xmm(memory[2]);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='move aligned four packed single-fp';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovaps'
|
|
else
|
|
lastdisassembledata.opcode:='movaps';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,4,last)+xmm(memory[2]);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
|
|
$2a : begin
|
|
if $f2 in prefix2 then
|
|
begin
|
|
|
|
description:='convert doubleword integer to scalar doubleprecision floating-point value';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vcvtsi2sd'
|
|
else
|
|
lastdisassembledata.opcode:='cvtsi2sd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,0,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $f3 in prefix2 then
|
|
begin
|
|
|
|
description:='scalar signed int32 to single-fp conversion';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vcvtsi2ss'
|
|
else
|
|
lastdisassembledata.opcode:='cvtsi2ss';
|
|
|
|
opcodeflags.extrareginstoverride:=4;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,0,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='convert packed dword''s to packed dp-fp''s';
|
|
lastdisassembledata.opcode:='cvtpi2pd';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed signed int32 to packed single-fp conversion';
|
|
lastdisassembledata.opcode:='cvtpi2ps';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$2b : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovntpd'
|
|
else
|
|
lastdisassembledata.opcode:='movntpd';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,4,last)+xmm(memory[2]);
|
|
description:='move packed double-precision floating-point using non-temporal hint';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovntps'
|
|
else
|
|
lastdisassembledata.opcode:='movntps';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,4,last)+xmm(memory[2]);
|
|
description:='move aligned four packed single-fp non temporal';
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$2c : begin
|
|
if $f2 in prefix2 then
|
|
begin
|
|
|
|
description:='convert with truncation scalar double-precision floating point value to signed doubleword integer';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vcvttsd2si'
|
|
else
|
|
lastdisassembledata.opcode:='cvttsd2si';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $f3 in prefix2 then
|
|
begin
|
|
description:='scalar single-fp to signed int32 conversion (truncate)';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vcvttss2si'
|
|
else
|
|
lastdisassembledata.opcode:='cvttss2si';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed doubleprecision-fp to packed dword conversion (truncate)';
|
|
lastdisassembledata.opcode:='cvttpd2pi';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed single-fp to packed int32 conversion (truncate)';
|
|
lastdisassembledata.opcode:='cvttps2pi';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$2d : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
if $f2 in prefix2 then
|
|
begin
|
|
description:='convert scalar double-precision floating-point value to doubleword integer';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vcvtsd2si'
|
|
else
|
|
lastdisassembledata.opcode:='cvtsd2si';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $f3 in prefix2 then
|
|
begin
|
|
description:='scalar single-fp to signed int32 conversion';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vcvtss2si'
|
|
else
|
|
lastdisassembledata.opcode:='cvtss2si';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,4,last, mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='convert 2 packed dp-fp''s from param 2 to packed signed dword in param1';
|
|
lastdisassembledata.opcode:='cvtpi2ps';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed single-fp to packed int32 conversion';
|
|
lastdisassembledata.opcode:='cvtps2pi';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,4,last, mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$2e : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='unordered scalar double-fp compare and set eflags';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vucomisd'
|
|
else
|
|
lastdisassembledata.opcode:='ucomisd';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='unordered scalar single-fp compare and set eflags';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vucomiss'
|
|
else
|
|
lastdisassembledata.opcode:='ucomiss';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
|
|
$2f : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='compare scalar ordered double-precision floating point values and set eflags';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vcomisd'
|
|
else
|
|
lastdisassembledata.opcode:='comisd';
|
|
opcodeflags.skipExtraReg:=true;
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='scalar ordered single-fp compare and set eflags';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vcomiss'
|
|
else
|
|
lastdisassembledata.opcode:='comiss';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$30 : begin
|
|
description:='write to model specific register';
|
|
lastdisassembledata.opcode:='wrmsr';
|
|
inc(offset);
|
|
end;
|
|
|
|
$31 : begin
|
|
description:='read time-stamp counter';
|
|
lastdisassembledata.opcode:='rdtsc';
|
|
inc(offset);
|
|
end;
|
|
|
|
$32 : begin
|
|
description:='read from model specific register';
|
|
lastdisassembledata.opcode:='rdmsr';
|
|
inc(offset);
|
|
end;
|
|
|
|
$33: begin
|
|
description:='read performance-monitoring counters';
|
|
lastdisassembledata.opcode:='rdpmc';
|
|
inc(offset);
|
|
end;
|
|
|
|
$34: begin
|
|
description:='fast transistion to system call entry point';
|
|
lastdisassembledata.opcode:='sysenter';
|
|
lastdisassembledata.isret:=true;
|
|
inc(offset);
|
|
end;
|
|
|
|
$35: begin
|
|
description:='fast transistion from system call entry point';
|
|
lastdisassembledata.opcode:='sysexit';
|
|
inc(offset);
|
|
end;
|
|
|
|
$37: begin
|
|
description:='Safermode multipurpose function';
|
|
lastdisassembledata.opcode:='getsec';
|
|
inc(offset);
|
|
end;
|
|
|
|
{0f} $38: begin
|
|
case memory[2] of
|
|
$00: begin
|
|
description:='Packed shuffle bytes';
|
|
LastDisassembleData.opcode:='pshufb';
|
|
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='v'+LastDisassembleData.opcode;
|
|
end
|
|
else
|
|
lastdisassembledata.parameters:=mm(memory[3])+modrm(memory,prefix2,3,3,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$01: begin
|
|
description:='Packed horizontal add';
|
|
LastDisassembleData.opcode:='phaddw';
|
|
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='v'+LastDisassembleData.opcode;
|
|
end
|
|
else
|
|
lastdisassembledata.parameters:=mm(memory[3])+modrm(memory,prefix2,3,3,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
{0f}{38} $02: begin
|
|
description:='Packed horizontal add';
|
|
LastDisassembleData.opcode:='phaddd';
|
|
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='v'+LastDisassembleData.opcode;
|
|
end
|
|
else
|
|
lastdisassembledata.parameters:=mm(memory[3])+modrm(memory,prefix2,3,3,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$03: begin
|
|
description:='Packed horizontal add and saturate';
|
|
LastDisassembleData.opcode:='phaddsw';
|
|
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='v'+LastDisassembleData.opcode;
|
|
end
|
|
else
|
|
lastdisassembledata.parameters:=mm(memory[3])+modrm(memory,prefix2,3,3,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$04: begin
|
|
description:='Multiply and add signed and unsigned bytes';
|
|
LastDisassembleData.opcode:='pmaddubsw';
|
|
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='v'+LastDisassembleData.opcode;
|
|
end
|
|
else
|
|
lastdisassembledata.parameters:=mm(memory[3])+modrm(memory,prefix2,3,3,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
{0f}{38} $05: begin
|
|
description:='Packed horizontal subtract';
|
|
LastDisassembleData.opcode:='phsubw';
|
|
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='v'+LastDisassembleData.opcode;
|
|
end
|
|
else
|
|
lastdisassembledata.parameters:=mm(memory[3])+modrm(memory,prefix2,3,3,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$06: begin
|
|
description:='Packed horizontal subtract';
|
|
LastDisassembleData.opcode:='phsubd';
|
|
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='v'+LastDisassembleData.opcode;
|
|
end
|
|
else
|
|
lastdisassembledata.parameters:=mm(memory[3])+modrm(memory,prefix2,3,3,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$07: begin
|
|
description:='Packed horizontal subtract';
|
|
LastDisassembleData.opcode:='phsubsw';
|
|
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='v'+LastDisassembleData.opcode;
|
|
end
|
|
else
|
|
lastdisassembledata.parameters:=mm(memory[3])+modrm(memory,prefix2,3,3,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$08: begin
|
|
description:='Packed SIGN';
|
|
LastDisassembleData.opcode:='psignb';
|
|
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='v'+LastDisassembleData.opcode;
|
|
end
|
|
else
|
|
lastdisassembledata.parameters:=mm(memory[3])+modrm(memory,prefix2,3,3,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$09: begin
|
|
description:='Packed SIGN';
|
|
LastDisassembleData.opcode:='psignw';
|
|
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='v'+LastDisassembleData.opcode;
|
|
end
|
|
else
|
|
lastdisassembledata.parameters:=mm(memory[3])+modrm(memory,prefix2,3,3,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$0a: begin
|
|
description:='Packed SIGN';
|
|
LastDisassembleData.opcode:='psignd';
|
|
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='v'+LastDisassembleData.opcode;
|
|
end
|
|
else
|
|
lastdisassembledata.parameters:=mm(memory[3])+modrm(memory,prefix2,3,3,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
{0f}{38} $0b: begin
|
|
description:='Packed multiply high with round and scale';
|
|
LastDisassembleData.opcode:='phmulhrsw';
|
|
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='v'+LastDisassembleData.opcode;
|
|
end
|
|
else
|
|
lastdisassembledata.parameters:=mm(memory[3])+modrm(memory,prefix2,3,3,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
{0f}{38} $0c: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='permute single-precision floating-point values';
|
|
LastDisassembleData.opcode:='vpermilps';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
end;
|
|
|
|
end;
|
|
|
|
{0f}{38} $0d: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='permute double-precision floating-point values';
|
|
LastDisassembleData.opcode:='vpermilpd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
end;
|
|
|
|
end;
|
|
|
|
{0f}{38} $0e: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Packed bit test';
|
|
LastDisassembleData.opcode:='vtestps';
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $0f: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Packed bit test';
|
|
LastDisassembleData.opcode:='vtestpd';
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
end;
|
|
end;
|
|
|
|
$10: begin
|
|
description:='Variable blend packed bytes';
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
LastDisassembleData.opcode:='vpblendvb';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+','+regnrtostr(rtXMM,memory[last]);
|
|
inc(offset,1);
|
|
end
|
|
else
|
|
begin
|
|
LastDisassembleData.opcode:='pblendvb';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight)+','+regnrtostr(rtXMM,0);
|
|
end;
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $13: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Convert 16-bit FP values to single-precision FP values';
|
|
LastDisassembleData.opcode:='vcvtph2ps';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
|
|
$14: begin
|
|
description:='Variable blend packed single precision floating-point values';
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
LastDisassembleData.opcode:='vblendvps';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+','+regnrtostr(rtXMM,memory[last]);
|
|
inc(offset,1);
|
|
end
|
|
else
|
|
begin
|
|
LastDisassembleData.opcode:='blendvps';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight)+','+regnrtostr(rtXMM,0);
|
|
end;
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$15: begin
|
|
description:='Variable blend packed double precision floating-point values';
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
LastDisassembleData.opcode:='vblendvpd invalid';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+','+regnrtostr(rtXMM,memory[last]);
|
|
inc(offset,1);
|
|
end
|
|
else
|
|
begin
|
|
LastDisassembleData.opcode:='blendvpd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight)+','+colorreg+regnrtostr(rtXMM,0)+endcolor;
|
|
end;
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$16: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Permute single-precision floating-point elements';
|
|
LastDisassembleData.opcode:='vpermps';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end
|
|
end;
|
|
|
|
$17: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Logical compare';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vptest'
|
|
else
|
|
LastDisassembleData.opcode:='ptest';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
end;
|
|
|
|
$18: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Broadcast floating-point-data';
|
|
LastDisassembleData.opcode:='vbroadcastss';
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end
|
|
end;
|
|
|
|
$19: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Broadcast floating-point-data';
|
|
LastDisassembleData.opcode:='vbroadcastsd';
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end
|
|
end;
|
|
|
|
$1a: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Broadcast floating-point-data';
|
|
LastDisassembleData.opcode:='vbroadcastf128';
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end
|
|
end;
|
|
|
|
{0f}{38} $1c: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Packed absolute value';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpabsb'
|
|
else
|
|
LastDisassembleData.opcode:='pabsb';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Packed absolute value';
|
|
LastDisassembleData.opcode:='pabsb';
|
|
lastdisassembledata.parameters:=mm(memory[3])+modrm(memory,prefix2,3,3,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $1d: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Packed absolute value';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpabsw'
|
|
else
|
|
LastDisassembleData.opcode:='pabsw';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Packed absolute value';
|
|
LastDisassembleData.opcode:='pabsw';
|
|
lastdisassembledata.parameters:=mm(memory[3])+modrm(memory,prefix2,3,3,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $1e: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Packed absolute value';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpabsd'
|
|
else
|
|
LastDisassembleData.opcode:='pabsd';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Packed absolute value';
|
|
LastDisassembleData.opcode:='pabsd';
|
|
lastdisassembledata.parameters:=mm(memory[3])+modrm(memory,prefix2,3,3,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $20: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Packed move with sign extend';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpmovsxbw'
|
|
else
|
|
LastDisassembleData.opcode:='pmovsxbw';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $21: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Packed move with sign extend';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpmovsxbd'
|
|
else
|
|
LastDisassembleData.opcode:='pmovsxbd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $22: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Packed move with sign extend';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpmovsxbq'
|
|
else
|
|
LastDisassembleData.opcode:='pmovsxbq';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $23: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Packed move with sign extend';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpmovsxwd'
|
|
else
|
|
LastDisassembleData.opcode:='pmovsxwd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $24: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Packed move with sign extend';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpmovsxwq'
|
|
else
|
|
LastDisassembleData.opcode:='pmovsxwq';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $25: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Packed move with sign extend';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpmovsxdq'
|
|
else
|
|
LastDisassembleData.opcode:='pmovsxdq';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $28: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Multiple packed signed dword integers';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpmuldq'
|
|
else
|
|
LastDisassembleData.opcode:='pmuldq';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $29: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Compare packed qword data for equal';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpcmpeqq'
|
|
else
|
|
LastDisassembleData.opcode:='pcmpeqq';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $2a: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Load double quadword non-temporal aligned hint';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vmovntdqa'
|
|
else
|
|
LastDisassembleData.opcode:='movntdqa';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $2b: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Pack with unsigned saturation';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpackusdw'
|
|
else
|
|
LastDisassembleData.opcode:='packusdw';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $2c: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Conditional SIMD packed loads and stores';
|
|
LastDisassembleData.opcode:='vmaskmovps';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $2d: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Conditional SIMD packed loads and stores';
|
|
LastDisassembleData.opcode:='vmaskmovpd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $2e: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Conditional SIMD packed loads and stores';
|
|
LastDisassembleData.opcode:='vmaskmovps';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,3,4,last, mLeft)+xmm(memory[3]);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $2f: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Conditional SIMD packed loads and stores';
|
|
LastDisassembleData.opcode:='vmaskmovpd';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,3,4,last, mLeft)+xmm(memory[3]);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $30: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Packed move with zero extend';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpmovzxbw'
|
|
else
|
|
LastDisassembleData.opcode:='pmovzxbw';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $31: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Packed move with zero extend';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpmovzxbd'
|
|
else
|
|
LastDisassembleData.opcode:='pmovzxbd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $32: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Packed move with zero extend';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpmovzxbq'
|
|
else
|
|
LastDisassembleData.opcode:='pmovzxbq';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $33: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Packed move with zero extend';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpmovzxwd'
|
|
else
|
|
LastDisassembleData.opcode:='pmovzxwd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $34: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Packed move with zero extend';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpmovzxwq'
|
|
else
|
|
LastDisassembleData.opcode:='pmovzxwq';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $35: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Packed move with zero extend';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpmovzxdq'
|
|
else
|
|
LastDisassembleData.opcode:='pmovzxdq';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $36: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Full doublewords element permutation';
|
|
LastDisassembleData.opcode:='vpermd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
{0f}{38} $37: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Compare packed data for greater than';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpcmpgtq'
|
|
else
|
|
LastDisassembleData.opcode:='pcmpgtq';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $38: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Minimum of packed signed byte integers';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpminsb'
|
|
else
|
|
LastDisassembleData.opcode:='pminsb';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $39: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Minimum of packed dword integers';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpminsd'
|
|
else
|
|
LastDisassembleData.opcode:='pminsd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $3a: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Minimum of packed word integers';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpminuw'
|
|
else
|
|
LastDisassembleData.opcode:='pminuw';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $3b: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Minimum of packed dword integers';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpminud'
|
|
else
|
|
LastDisassembleData.opcode:='pminud';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $3c: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Maximum of packed signed byte integers';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpmaxsb'
|
|
else
|
|
LastDisassembleData.opcode:='pmaxsb';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $3d: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Maximum of packed signed dword integers';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpmaxsd'
|
|
else
|
|
LastDisassembleData.opcode:='pmaxsd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $3e: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Maximum of packed word integers';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpmaxuw'
|
|
else
|
|
LastDisassembleData.opcode:='pmaxuw';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $3f: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Maximum of packed unsigned dword integers';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpmaxud'
|
|
else
|
|
LastDisassembleData.opcode:='pmaxud';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $40: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Multiply Packed Signed Dword Integers and Store Low Result';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpmulld'
|
|
else
|
|
LastDisassembleData.opcode:='pmulld';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $41: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Packed horitontal word minimum';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='phminposuw'
|
|
else
|
|
LastDisassembleData.opcode:='vphminposuw';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$45: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Variable Bit Shift Right Logical';
|
|
|
|
if Rex_W then
|
|
LastDisassembleData.opcode:='vpsrlvq'
|
|
else
|
|
LastDisassembleData.opcode:='vpsrlvd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $46: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Variable bit shift right arithmetic';
|
|
LastDisassembleData.opcode:='vpsravd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$47: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Variable Bit Shift Left Logical';
|
|
|
|
if Rex_W then
|
|
LastDisassembleData.opcode:='vpsllvq'
|
|
else
|
|
LastDisassembleData.opcode:='vpsllvd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
{0f}{38} $58: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Broadcast integer data';
|
|
LastDisassembleData.opcode:='vpbroadcastd';
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $59: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Broadcast integer data';
|
|
LastDisassembleData.opcode:='vpbroadcastq';
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $5a: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Broadcast integer data';
|
|
LastDisassembleData.opcode:='vpbroadcasti128';
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $78: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Broadcast integer data';
|
|
LastDisassembleData.opcode:='vpbroadcastb';
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $79: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Broadcast integer data';
|
|
LastDisassembleData.opcode:='vpbroadcastw';
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$82: begin
|
|
description:='Invalidate process-context-identifier';
|
|
LastDisassembleData.opcode:='invpcid';
|
|
if processhandler.is64Bit then
|
|
lastdisassembledata.parameters:=r64(memory[3])+modrm(memory,prefix2,3,0,last,128,0, mRight)
|
|
else
|
|
lastdisassembledata.parameters:=r32(memory[3])+modrm(memory,prefix2,3,0,last,128,0,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$8c: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Conditional SIMD Integer Packed Loads and Stores';
|
|
LastDisassembleData.opcode:='vpmaskmovq';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Conditional SIMD Integer Packed Loads and Stores';
|
|
LastDisassembleData.opcode:='vpmaskmovd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$8e: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Conditional SIMD Integer Packed Loads and Stores';
|
|
LastDisassembleData.opcode:='vpmaskmovq';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,3,4,last,mleft)+xmm(memory[3]);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Conditional SIMD Integer Packed Loads and Stores';
|
|
LastDisassembleData.opcode:='vpmaskmovd';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,3,4,last,mleft)+xmm(memory[3]);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$92: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Gather Packed DP FP Values Using Signed Dword/Qword Indices';
|
|
hasvsib:=true;
|
|
LastDisassembleData.opcode:='vgatherdpd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+','+modrm(memory,prefix2,3,4,last,32);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Gather Packed SP FP values Using Signed Dword/Qword Indices';
|
|
hasvsib:=true;
|
|
LastDisassembleData.opcode:='vgatherdps';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+','+modrm(memory,prefix2,3,4,last,32);
|
|
inc(offset,last-1);
|
|
end
|
|
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$93: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Gather Packed SP FP values Using Signed Dword/Qword Indices';
|
|
hasvsib:=true;
|
|
LastDisassembleData.opcode:='vgatherqpd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+','+modrm(memory,prefix2,3,4,last,mLeft);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Gather Packed SP FP values Using Signed Dword/Qword Indices';
|
|
hasvsib:=true;
|
|
LastDisassembleData.opcode:='vgatherqps';
|
|
opcodeflags.ignoreLForExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm_ignoreL(memory[3])+','+modrm(memory,prefix2,3,4,last,mLeft);
|
|
inc(offset,last-1);
|
|
end
|
|
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
$96: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Fused multiple-alnterating add/subtract of packed double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmaddsub132pd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused multiple-alnterating add/subtract of precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmaddsub132ps';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$97: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Fused multiple-alnterating subtract/add of packed double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsubadd132pd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused multiple-alnterating subtract/add of precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsubadd132ps';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$98: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Fused multiple-add of packed double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmadd132pd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused multiple-add of packed single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmadd132ps';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$99: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Fused multiple-add of scalar double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmadd132sd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused multiple-add of scalar single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmadd132ss';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$9a: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Fused multiple-subtract of packed double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsub132pd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused multiple-subtract of packed single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsub132ps';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$9B: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Fused multiple-subtract of scalar double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsub132sd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused multiple-subtract of scalar single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsub132ss';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $9c: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Fused negative multiply-add of packed double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfnmadd132pd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused negative multiply-add of packed single-precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfnmadd132ps';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$9D: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Fused negative multiply-add of scalar double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfnmadd132sd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused negative multiply-add of scalar single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfnmadd132ss';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$9e: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Fused negative multiply-subtract of packed double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsub132pd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused negative multiply-subtract of packed single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsub132ps';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$9f: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Fused negative multiply-subtract of scalar double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsub132sd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused begative multiply-subtract of scalar single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsub132ss';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$a6: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if rex_w then
|
|
begin
|
|
description:='Fused multiply-alternating add/subtract of packed double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmaddsub213pd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused multiply-alternating add/subtract of packed single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmaddsub213ps';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$a7: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if rex_w then
|
|
begin
|
|
description:='Fused multiply-alternating subtract/add of packed double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsubadd213pd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused multiply-alternating subtract/add of packed single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsubadd213ps';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$a8: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if rex_w then
|
|
begin
|
|
description:='Fused multiple-add of packed double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmadd213pd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused multiple-add of packed single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmadd213ps';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $a9: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if rex_w then
|
|
begin
|
|
description:='Fused multiple-add of scalar double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmadd213sd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused multiple-add of scalar single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmadd213ss';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$aa: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if rex_w then
|
|
begin
|
|
description:='Fused multiple-subtract of packed double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsub213pd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused multiple-subtract of packed single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsub213ps';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
$ab: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Fused multiple-subtract of scalar double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsub213sd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused multiple-subtract of scalar single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsub213ss';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$ac: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Fused negative multiply-add of packed double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfnmadd213pd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused negative multiply-add of packed single-precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfnmadd213ps';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$ad: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Fused negative multiply-add of scalar double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfnmadd213sd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused negative multiply-add of scalar single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfnmadd213ss';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $ae: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Fused negative multiply-subtract of packed double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsub213pd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused negative multiply-subtract of packed single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsub213ps';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$af: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Fused negative multiply-subtract of scalar double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfnmsub213sd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused begative multiply-subtract of scalar single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfnmsub213ss';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$b6: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if rex_w then
|
|
begin
|
|
description:='Fused multiply-alternating add/subtract of packed double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmaddsub231pd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused multiply-alternating add/subtract of packed single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmaddsub231ps';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$b7: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if rex_w then
|
|
begin
|
|
description:='Fused multiply-alternating subtract/add of packed double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsubadd231pd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused multiply-alternating add/subtract of packed single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsubadd231ps';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$b8: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if rex_w then
|
|
begin
|
|
description:='Fused multiple-add of packed double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmadd231pd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused multiple-add of packed single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmadd231ps';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$b9: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if rex_w then
|
|
begin
|
|
description:='Fused multiple-add of scalar double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmadd231sd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused multiple-add of scalar single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmadd231ss';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$ba: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if rex_w then
|
|
begin
|
|
description:='Fused multiple-subtract of packed double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsub231pd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused multiple-subtract of packed single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsub231ps';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$bb: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Fused multiple-subtract of scalar double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsub231sd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused multiple-subtract of scalar single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsub231ss';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $bc: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Fused negative multiply-add of packed double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfnmadd231pd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused negative multiply-add of packed single-precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfnmadd231ps';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$bd: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Fused negative multiply-add of scalar double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfnmadd231sd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused negative multiply-add of scalar single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfnmadd231ss';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
$be: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Fused negative multiply-subtract of packed double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsub231pd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused negative multiply-subtract of packed single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsub231ps';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$bf: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Fused negative multiply-subtract of scalar double precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsub231sd';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Fused begative multiply-subtract of scalar single precision floating-point-values';
|
|
LastDisassembleData.opcode:='vfmsub231ss';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
$db: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Perform the AES InvMixColumn transformation';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vaesimc'
|
|
else
|
|
LastDisassembleData.opcode:='aesimc';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$dc: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Perform one round of an AES encryption flow';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vaesenc'
|
|
else
|
|
LastDisassembleData.opcode:='aesenc';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$dd: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Perform last round of an AES encryption flow';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='caesenclast'
|
|
else
|
|
LastDisassembleData.opcode:='aesenclast';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $de: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Perform one round of an AES decryption flow';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vaesdec'
|
|
else
|
|
LastDisassembleData.opcode:='aesdec';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$df: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Perform last round of an AES decryption flow';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='caesdeclast'
|
|
else
|
|
LastDisassembleData.opcode:='aesdeclast';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mright);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $f0: begin
|
|
if $f2 in prefix2 then
|
|
begin
|
|
description:='Accumulate CRC32 value';
|
|
LastDisassembleData.opcode:='crc32';
|
|
lastdisassembledata.parameters:=r32(memory[3])+modrm(memory,prefix2,3,2,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Move data after swapping bytes';
|
|
LastDisassembleData.opcode:='movbe';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[3])+modrm(memory,prefix2,3,2,last,mRight)
|
|
else
|
|
lastdisassembledata.parameters:=r32(memory[3])+modrm(memory,prefix2,3,0,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$f1: begin
|
|
if $f2 in prefix2 then
|
|
begin
|
|
description:='Accumulate CRC32 value';
|
|
LastDisassembleData.opcode:='crc32';
|
|
lastdisassembledata.parameters:=r32(memory[3])+modrm(memory,prefix2,3,0,last, mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Move data after swapping bytes';
|
|
LastDisassembleData.opcode:='movbe';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,3,0,last, mLeft)+r32(memory[3]);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$f2: begin
|
|
if hasvex then
|
|
begin
|
|
description:='Logical AND NOT';
|
|
LastDisassembleData.opcode:='andn';
|
|
lastdisassembledata.parameters:=r32(memory[3])+modrm(memory,prefix2,3,0,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $f3: begin
|
|
case getreg(memory[3]) of
|
|
1:
|
|
begin
|
|
description:='Reset lowerst set bit';
|
|
LastDisassembleData.opcode:='blsr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,3,0,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
2:
|
|
begin
|
|
description:='Get mask up to lowest set bit';
|
|
LastDisassembleData.opcode:='blsmsk';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,3,0,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
3:
|
|
begin
|
|
description:='Extract lowest set isolated bit';
|
|
LastDisassembleData.opcode:='blsi';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,3,0,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$f5: begin
|
|
if $f2 in prefix2 then
|
|
begin
|
|
description:='Parallel bits deposit';
|
|
LastDisassembleData.opcode:='pdep';
|
|
lastdisassembledata.parameters:=r32(memory[3])+modrm(memory,prefix2,3,0,last,mLeft);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='Zero high bits starting with specified bit position';
|
|
LastDisassembleData.opcode:='bzhi';
|
|
lastdisassembledata.parameters:=r32(memory[3])+modrm(memory,prefix2,3,0,last,mLeft);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
|
|
$f6: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='ADX: Unsigned Integer Addition of Two Operands with Carry Flag';
|
|
LastDisassembleData.opcode:='adcx';
|
|
lastdisassembledata.parameters:=r32(memory[3])+modrm(memory,prefix2,3,0,last, mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $f3 in prefix2 then
|
|
begin
|
|
description:='ADX: Unsigned Integer Addition of Two Operands with Overflow Flag';
|
|
LastDisassembleData.opcode:='adox';
|
|
lastdisassembledata.parameters:=r32(memory[3])+modrm(memory,prefix2,3,0,last, mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Unsigned multiple without affecting flags';
|
|
LastDisassembleData.opcode:='mulx';
|
|
lastdisassembledata.parameters:=r32(memory[3])+modrm(memory,prefix2,3,0,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{0f}{38} $f7: begin
|
|
if hasvex then
|
|
begin
|
|
if $f3 in prefix2 then
|
|
begin
|
|
description:='Shift arithmetically right without affecting flags';
|
|
LastDisassembleData.opcode:='SARX';
|
|
lastdisassembledata.parameters:=r32(memory[3])+modrm(memory,prefix2,3,0,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $f2 in prefix2 then
|
|
begin
|
|
description:='Shift logically right without affecting flags';
|
|
LastDisassembleData.opcode:='SHRX';
|
|
lastdisassembledata.parameters:=r32(memory[3])+modrm(memory,prefix2,3,0,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Shift logically left without affecting flags';
|
|
LastDisassembleData.opcode:='SHLX';
|
|
lastdisassembledata.parameters:=r32(memory[3])+modrm(memory,prefix2,3,0,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
description:='Bit field extract';
|
|
LastDisassembleData.opcode:='BEXTR';
|
|
lastdisassembledata.parameters:=r32(memory[3])+modrm(memory,prefix2,3,0,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
else
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
LastDisassembleData.opcode:='unknown avx 0F38 '+inttohex(memory[2],2);
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$3a : begin
|
|
case memory[2] of
|
|
$00: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Qwords element permutation';
|
|
LastDisassembleData.opcode:='vpermq';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$01: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Permute double-precision floating-point elements';
|
|
LastDisassembleData.opcode:='vpermpd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$02: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Blend packed dwords';
|
|
LastDisassembleData.opcode:='vblenddd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$04: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Permute single-prevision floating-point values';
|
|
LastDisassembleData.opcode:='vpermilps';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
$05: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Permute double-prevision floating-point values';
|
|
LastDisassembleData.opcode:='vpermilpd';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{0f}{3a} $06: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Permute floating-point values';
|
|
LastDisassembleData.opcode:='vperm2f128';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
{0f}{3a} $08: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Round scalar single precision floating-point values';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vroundps'
|
|
else
|
|
LastDisassembleData.opcode:='roundps';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$09: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Round packed double precision floating-point values';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vroundpd'
|
|
else
|
|
LastDisassembleData.opcode:='roundpd';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$0a: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Round scalar single precision floating-point values';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vroundss'
|
|
else
|
|
LastDisassembleData.opcode:='roundss';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$0b: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Round packed single precision floating-point values';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vroundsd'
|
|
else
|
|
LastDisassembleData.opcode:='roundsd';
|
|
|
|
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{3a} $0c: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Blend packed single precision floating-point values';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vblendps'
|
|
else
|
|
LastDisassembleData.opcode:='blendps';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{3a} $0d: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Blend packed double precision floating-point values';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vblendpd'
|
|
else
|
|
LastDisassembleData.opcode:='blendpd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{3a} $0e: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Blend packed words';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpblendw'
|
|
else
|
|
LastDisassembleData.opcode:='pblendw';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{3a} $0f: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Packed align right';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpalignr'
|
|
else
|
|
LastDisassembleData.opcode:='palignr';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
LastDisassembleData.opcode:='palignr';
|
|
lastdisassembledata.parameters:=mm(memory[3])+modrm(memory,prefix2,3,3,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{3a} $14: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Extract byte';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpextrb'
|
|
else
|
|
LastDisassembleData.opcode:='pextrb';
|
|
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,3,2,last,mleft)+xmm(memory[3])+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{3a} $15: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Extract word';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpextrw'
|
|
else
|
|
LastDisassembleData.opcode:='pextrw';
|
|
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,3,1,last,mleft)+xmm(memory[3])+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{3a} $16: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Extract qword';
|
|
LastDisassembleData.opcode:='pextrq';
|
|
end
|
|
else
|
|
begin
|
|
description:='Extract dword';
|
|
LastDisassembleData.opcode:='pextrd';
|
|
end;
|
|
|
|
if hasvex then LastDisassembleData.opcode:='v'+LastDisassembleData.opcode;
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,3,2,last,mleft)+xmm(memory[3])+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$17: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Extract packed single precision floating-point value';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vextractps'
|
|
else
|
|
LastDisassembleData.opcode:='extractps';
|
|
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,3,4,last,mleft)+xmm(memory[3])+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
|
|
$18: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Insert packed floating-point values';
|
|
LastDisassembleData.opcode:='vinsertf128';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$19: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Extract packed floating-point values';
|
|
LastDisassembleData.opcode:='vextractf128';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
{0f}{3a} $1d: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Convert single-precision FP value to 16-bit FP value';
|
|
LastDisassembleData.opcode:='vcvtps2ph';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{0f}{3a} $20: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Insert Byte';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpinsrb'
|
|
else
|
|
LastDisassembleData.opcode:='pinsrb';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,0,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{3a} $21: begin //C4 E3 79 21 80 B8 00 00 00 20
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Insert Scalar Single-Precision Floating-Point Value';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vinsertps'
|
|
else
|
|
LastDisassembleData.opcode:='insertps';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$22: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='Insert qword';
|
|
LastDisassembleData.opcode:='pinsrq';
|
|
end
|
|
else
|
|
begin
|
|
description:='Insert dword';
|
|
LastDisassembleData.opcode:='pinsrd';
|
|
end;
|
|
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='v'+LastDisassembleData.opcode;
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,0,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$38: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Insert packed integer values';
|
|
LastDisassembleData.opcode:='vinserti128';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$39: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Extract packed integer values';
|
|
LastDisassembleData.opcode:='vextracti128';
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$40: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Dot product of packed single precision floating-point values';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vdpps'
|
|
else
|
|
LastDisassembleData.opcode:='dpps';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$41: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Dot product of packed double precision floating-point values';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vdppd'
|
|
else
|
|
LastDisassembleData.opcode:='dppd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{3a} $42: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Compute multiple packed sums of absolute difference';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vmpsadbw'
|
|
else
|
|
LastDisassembleData.opcode:='mpsadbw';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{3a} $44: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Carry-less multiplication quadword';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpclmulqdq'
|
|
else
|
|
LastDisassembleData.opcode:='pclmulqdq';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{3a} $46: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Permute integer values';
|
|
LastDisassembleData.opcode:='vperm2i128';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{0f}{3a} $4a: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Variable Blend Packed Single Precision Floating-Point Values';
|
|
LastDisassembleData.opcode:='vblendvps';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
if opcodeflags.L then
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+colorreg+regnrtostr(rtYMM, memory[last] shr 4 and $f)+endcolor
|
|
else
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+colorreg+regnrtostr(rtXMM, memory[last] shr 4 and $f)+endcolor;
|
|
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{0f}{3a} $4b: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Variable Blend Packed Double Precision Floating-Point Values';
|
|
LastDisassembleData.opcode:='vblendvpd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
if opcodeflags.L then
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+colorreg+regnrtostr(rtYMM, memory[last] shr 4 and $f)+endcolor
|
|
else
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+colorreg+regnrtostr(rtXMM, memory[last] shr 4 and $f)+endcolor;
|
|
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
{0f}{3a} $60: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Packed compare explicit length string, return mask';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpcmpestrm'
|
|
else
|
|
LastDisassembleData.opcode:='pcmpestrm';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{3a} $61: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Packed compare explicit length string, return index';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpcmpestri'
|
|
else
|
|
LastDisassembleData.opcode:='pcmpestri';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{3a} $62: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Packed compare implicit length string, return mask';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpcmpistrm'
|
|
else
|
|
LastDisassembleData.opcode:='pcmpistrm';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
{0f}{3a} $63: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Packed compare implicit length string, return index';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vpcmpistri'
|
|
else
|
|
LastDisassembleData.opcode:='pcmpistri';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$df: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='AES round key generation assist';
|
|
if hasvex then
|
|
LastDisassembleData.opcode:='vaeskeygenassist'
|
|
else
|
|
LastDisassembleData.opcode:='aeskeygenassist';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$f0: begin
|
|
if $f2 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
description:='Rotate right logical without affecting flags';
|
|
LastDisassembleData.opcode:='rorx';
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=r32(memory[3])+modrm(memory,prefix2,3,0,last, mRight)+',';
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+','+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
else
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
LastDisassembleData.opcode:='unknown avx 0F3A '+inttohex(memory[2],2);
|
|
lastdisassembledata.parameters:=xmm(memory[3])+modrm(memory,prefix2,3,4,last,mRight);
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+','+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
$40 : begin
|
|
description:='move if overflow';
|
|
lastdisassembledata.opcode:='cmovo';
|
|
if $66 in prefix2 then lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last, mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last, mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$41 : begin
|
|
description:='move if not overflow';
|
|
lastdisassembledata.opcode:='cmovno';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last, mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$42 : begin
|
|
description:='move if below/ move if carry';
|
|
lastdisassembledata.opcode:='cmovb';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last, mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$43 : begin
|
|
description:='move if above or equal/ move if not carry';
|
|
lastdisassembledata.opcode:='cmovae';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last, mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$44 : begin
|
|
description:='move if equal/move if zero';
|
|
lastdisassembledata.opcode:='cmove';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last, mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$45 : begin
|
|
description:='move if not equal/move if not zero';
|
|
lastdisassembledata.opcode:='cmovne';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last, mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$46 : begin
|
|
description:='move if below or equal';
|
|
lastdisassembledata.opcode:='cmovbe';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last, mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
|
|
$47 : begin
|
|
description:='move if above';
|
|
lastdisassembledata.opcode:='cmova';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last, mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$48 : begin
|
|
description:='move if sign';
|
|
lastdisassembledata.opcode:='cmovs';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last, mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$49 : begin
|
|
description:='move if not sign';
|
|
lastdisassembledata.opcode:='cmovns';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last, mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$4a : begin
|
|
description:='move if parity even';
|
|
lastdisassembledata.opcode:='cmovpe';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last, mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$4b : begin
|
|
description:='move if not parity/move if parity odd';
|
|
lastdisassembledata.opcode:='cmovnp';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last, mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$4c : begin
|
|
description:='move if less';
|
|
lastdisassembledata.opcode:='cmovl';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last, mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$4d : begin
|
|
description:='move if greater or equal';
|
|
lastdisassembledata.opcode:='cmovge';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last, mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$4e : begin
|
|
description:='move if less or equal';
|
|
lastdisassembledata.opcode:='cmovle';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last, mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last, mRight);
|
|
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$4f : begin
|
|
description:='move if greater';
|
|
lastdisassembledata.opcode:='cmovg';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last, mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$50 : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovmskpd'
|
|
else
|
|
lastdisassembledata.opcode:='movmskpd';
|
|
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
description:='extract packed double-precision floating-point sign mask';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovmskps'
|
|
else
|
|
lastdisassembledata.opcode:='movmskps';
|
|
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
|
|
description:='move mask to integer';
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$51 : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
if $f2 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vsqrtsd'
|
|
else
|
|
lastdisassembledata.opcode:='sqrtsd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
description:='scalar double-fp square root';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $f3 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vsqrtss'
|
|
else
|
|
lastdisassembledata.opcode:='sqrtss';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
description:='scalar single-fp square root';
|
|
lastdisassembledata.datasize:=4;
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vsqrtpd'
|
|
else
|
|
lastdisassembledata.opcode:='sqrtpd';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
description:='packed double-fp square root';
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vsqrtps'
|
|
else
|
|
lastdisassembledata.opcode:='sqrtps';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
description:='packed single-fp square root';
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$52 : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
if $f3 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vrsqrtss'
|
|
else
|
|
lastdisassembledata.opcode:='rsqrtss';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
description:='packed single-fp square root reciprocal';
|
|
lastdisassembledata.datasize:=4;
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vrsqrtps'
|
|
else
|
|
lastdisassembledata.opcode:='rsqrtps';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
description:='scalar single-fp square root reciprocal';
|
|
lastdisassembledata.datasize:=4;
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$53 : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
if $f3 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vrcpss'
|
|
else
|
|
lastdisassembledata.opcode:='rcpss';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
description:='Compute Reciprocal of Scalar Single-Precision Floating-Point Values';
|
|
lastdisassembledata.datasize:=4;
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vrcpps'
|
|
else
|
|
lastdisassembledata.opcode:='rcpps';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
description:='Compute Reciprocals of Packed Single-Precision Floating-Point Values';
|
|
lastdisassembledata.datasize:=4;
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$54 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vandpd'
|
|
else
|
|
lastdisassembledata.opcode:='andpd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
description:='bit-wise logical and of xmm2/m128 and xmm1';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vandps'
|
|
else
|
|
lastdisassembledata.opcode:='andps';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
|
|
description:='bit-wise logical and for single fp';
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$55 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='bit-wise logical and not of packed double-precision fp values';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vandnpd'
|
|
else
|
|
lastdisassembledata.opcode:='andnpd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='bit-wise logical and not for single-fp';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vandnps'
|
|
else
|
|
lastdisassembledata.opcode:='andnps';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$56 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='bit-wise logical or of double-fp';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vorpd'
|
|
else
|
|
lastdisassembledata.opcode:='orpd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='bit-wise logical or for single-fp';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vorps'
|
|
else
|
|
lastdisassembledata.opcode:='orps';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$57 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='bit-wise logical xor for double-fp data';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vxorpd'
|
|
else
|
|
lastdisassembledata.opcode:='xorpd';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='bit-wise logical xor for single-fp data';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vxorps'
|
|
else
|
|
lastdisassembledata.opcode:='xorps';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$58 : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
if $f2 in prefix2 then
|
|
begin
|
|
//delete the repne from the tempresult
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vaddsd'
|
|
else
|
|
lastdisassembledata.opcode:='addsd';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
description:='add the lower sp fp number from xmm2/mem to xmm1.';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $f3 in prefix2 then
|
|
begin
|
|
//delete the repe from the tempresult
|
|
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vaddss'
|
|
else
|
|
lastdisassembledata.opcode:='addss';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
|
|
description:='add the lower sp fp number from xmm2/mem to xmm1.';
|
|
inc(offset,last-1);
|
|
end else
|
|
begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vaddpd'
|
|
else
|
|
lastdisassembledata.opcode:='addpd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mright);
|
|
|
|
description:='add packed double-precision floating-point values from xmm2/mem to xmm1';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vaddps'
|
|
else
|
|
lastdisassembledata.opcode:='addps';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
|
|
description:='add packed sp fp numbers from xmm2/mem to xmm1';
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$59 : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
if $f2 in prefix2 then
|
|
begin
|
|
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmulsd'
|
|
else
|
|
lastdisassembledata.opcode:='mulsd';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
description:='scalar double-fp multiply';
|
|
inc(offset,last-1);
|
|
end else
|
|
if $f3 in prefix2 then
|
|
begin
|
|
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmulss'
|
|
else
|
|
lastdisassembledata.opcode:='mulss';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
|
|
description:='scalar single-fp multiply';
|
|
inc(offset,last-1);
|
|
end else
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmulpd'
|
|
else
|
|
lastdisassembledata.opcode:='mulpd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
description:='packed double-fp multiply';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmulps'
|
|
else
|
|
lastdisassembledata.opcode:='mulps';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
|
|
description:='packed single-fp multiply';
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$5a : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
if $f2 in prefix2 then
|
|
begin
|
|
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vcvtsd2ss'
|
|
else
|
|
lastdisassembledata.opcode:='cvtsd2ss';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mright);
|
|
|
|
description:='convert scalar double-precision floating-point value to scalar single-precision floating-point value';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $f3 in prefix2 then
|
|
begin
|
|
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vcvtss2sd'
|
|
else
|
|
lastdisassembledata.opcode:='cvtss2sd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
|
|
description:='convert scalar single-precision floating-point value to scalar double-precision floating-point value';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vcvtpd2ps'
|
|
else
|
|
lastdisassembledata.opcode:='cvtpd2ps';
|
|
opcodeflags.skipExtraReg:=true;
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
description:='convert packed double precision fp values to packed single precision fp values';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vcvtps2pd'
|
|
else
|
|
lastdisassembledata.opcode:='cvtps2pd';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
|
|
description:='convert packed single precision fp values to packed double precision fp values';
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$5b : begin
|
|
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.isfloat:=true;
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vcvtps2dq'
|
|
else
|
|
lastdisassembledata.opcode:='cvtps2dq';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
|
|
description:='convert ps-precision fpoint values to packed dword''s ';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $f3 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vcvttps2dq'
|
|
else
|
|
lastdisassembledata.opcode:='cvttps2dq';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
description:='Convert with Truncation Packed Single-Precision FP Values to Packed Dword Integers';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vcvtdq2ps'
|
|
else
|
|
lastdisassembledata.opcode:='cvtdq2ps';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
description:='convert packed dword''s to ps-precision fpoint values';
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$5c : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
if $f2 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vsubsd'
|
|
else
|
|
lastdisassembledata.opcode:='subsd';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
description:='scalar double-fp subtract';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $f3 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vsubss'
|
|
else
|
|
lastdisassembledata.opcode:='subss';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
|
|
description:='scalar single-fp subtract';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vsubpd'
|
|
else
|
|
lastdisassembledata.opcode:='subpd';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
description:='packed double-fp subtract';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vsubps'
|
|
else
|
|
lastdisassembledata.opcode:='subps';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.datasize:=4; //4*4 actually
|
|
|
|
description:='packed single-fp subtract';
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
|
|
$5d : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
if $f2 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vminsd'
|
|
else
|
|
lastdisassembledata.opcode:='minsd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
description:='scalar single-fp minimum';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $f3 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vminss'
|
|
else
|
|
lastdisassembledata.opcode:='minss';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
|
|
description:='scalar single-fp minimum';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vminpd'
|
|
else
|
|
lastdisassembledata.opcode:='minpd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
description:='packed double-fp minimum';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vminps'
|
|
else
|
|
lastdisassembledata.opcode:='minps';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
description:='packed single-fp minimum';
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$5e : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
if $f2 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='divsd'
|
|
else
|
|
lastdisassembledata.opcode:='divsd';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
description:='scalar double-precision-fp divide';
|
|
inc(offset,last-1);
|
|
end else
|
|
if $f3 in prefix2 then
|
|
begin
|
|
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vdivss'
|
|
else
|
|
LastDisassembleData.opcode:='divss';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
|
|
description:='scalar single-fp divide';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vdivpd'
|
|
else
|
|
lastdisassembledata.opcode:='divpd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last, mRight);
|
|
|
|
description:='packed double-precision fp divide';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vdivps'
|
|
else
|
|
lastdisassembledata.opcode:='divps';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
|
|
description:='packed single-fp divide';
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$5f : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
if $f2 in prefix2 then
|
|
begin
|
|
|
|
description:='scalar double-fp maximum';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmaxsd'
|
|
else
|
|
lastdisassembledata.opcode:='maxsd';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end else
|
|
if $f3 in prefix2 then
|
|
begin
|
|
|
|
description:='scalar single-fp maximum';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmaxss'
|
|
else
|
|
lastdisassembledata.opcode:='maxss';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
|
|
inc(offset,last-1);
|
|
end else
|
|
begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed double-fp maximum';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmaxpd'
|
|
else
|
|
lastdisassembledata.opcode:='maxpd';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed single-fp maximum';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmaxps'
|
|
else
|
|
lastdisassembledata.opcode:='maxps';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.datasize:=4;
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$60 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='unpack low packed data';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpunpcklbw'
|
|
else
|
|
lastdisassembledata.opcode:='punpcklbw';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='unpack low packed data';
|
|
lastdisassembledata.opcode:='punpcklbw';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$61 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='unpack low packed data';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='punpcklwd'
|
|
else
|
|
lastdisassembledata.opcode:='punpcklwd';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='unpack low packed data';
|
|
lastdisassembledata.opcode:='punpcklwd';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$62 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='unpack low packed data';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpunpckldq'
|
|
else
|
|
lastdisassembledata.opcode:='punpckldq';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='unpack low packed data';
|
|
lastdisassembledata.opcode:='punpckldq';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$63 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='pack with signed saturation';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='packsswb'
|
|
else
|
|
lastdisassembledata.opcode:='vpacksswb';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='pack with signed saturation';
|
|
lastdisassembledata.opcode:='packsswb';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$64 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed compare for greater than';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpcmpgtb'
|
|
else
|
|
lastdisassembledata.opcode:='pcmpgtb';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed compare for greater than';
|
|
lastdisassembledata.opcode:='pcmpgtb';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$65 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed compare for greater than';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpcmpgtw'
|
|
else
|
|
lastdisassembledata.opcode:='pcmpgtw';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed compare for greater than';
|
|
lastdisassembledata.opcode:='pcmpgtw';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$66 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed compare for greater than';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpcmpgtd'
|
|
else
|
|
lastdisassembledata.opcode:='pcmpgtd';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed compare for greater than';
|
|
lastdisassembledata.opcode:='pcmpgtd';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
|
|
$67 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='pack with unsigned saturation';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpackuswb'
|
|
else
|
|
lastdisassembledata.opcode:='packuswb';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='pack with unsigned saturation';
|
|
lastdisassembledata.opcode:='packuswb';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$68 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='unpack high packed data';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpunpckhbw'
|
|
else
|
|
lastdisassembledata.opcode:='punpckhbw';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='unpack high packed data';
|
|
lastdisassembledata.opcode:='punpckhbw';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$69 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='unpack high packed data';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpunpckhwd'
|
|
else
|
|
lastdisassembledata.opcode:='punpckhwd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='unpack high packed data';
|
|
lastdisassembledata.opcode:='punpckhwd';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$6a : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='unpack high packed data';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpunpckhdq'
|
|
else
|
|
lastdisassembledata.opcode:='punpckhdq';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='unpack high packed data';
|
|
lastdisassembledata.opcode:='punpckhdq';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$6b : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='pack with signed saturation';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='packssdw'
|
|
else
|
|
lastdisassembledata.opcode:='packssdw';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='pack with signed saturation';
|
|
lastdisassembledata.opcode:='packssdw';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$6c : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='unpack low packed data';
|
|
lastdisassembledata.opcode:='punpcklqdq';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
end;
|
|
|
|
$6d : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='unpack high packed data';
|
|
lastdisassembledata.opcode:='punpckhqdq';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
end;
|
|
|
|
|
|
$6e : begin
|
|
//lastdisassembledata.isfloat:=true; //not sure
|
|
if rex_w then
|
|
begin
|
|
description:='move quadword';
|
|
lastdisassembledata.opcode:='movq';
|
|
end
|
|
else
|
|
begin
|
|
description:='move doubleword';
|
|
lastdisassembledata.opcode:='movd';
|
|
end;
|
|
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='v'+lastdisassembledata.opcode;
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,0,last,mRight)
|
|
else
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,0,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$6f : begin
|
|
if $f3 in prefix2 then
|
|
begin
|
|
|
|
description:='move unaligned double quadword';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovdqu'
|
|
else
|
|
lastdisassembledata.opcode:='movdqu';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='move aligned double quadword';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovdqa'
|
|
else
|
|
lastdisassembledata.opcode:='movdqa';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='move 64 bits';
|
|
lastdisassembledata.opcode:='movq';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,4,last);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$70 : begin
|
|
if $f2 in prefix2 then
|
|
begin
|
|
|
|
description:='shuffle packed low words';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpshuflw'
|
|
else
|
|
lastdisassembledata.opcode:='pshuflw';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(lastdisassembledata.parametervalue,2);
|
|
inc(offset,last);
|
|
end
|
|
else
|
|
if $f3 in prefix2 then
|
|
begin
|
|
|
|
description:='shuffle packed high words';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpshufhw'
|
|
else
|
|
lastdisassembledata.opcode:='pshufhw';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(lastdisassembledata.parametervalue,2);
|
|
inc(offset,last);
|
|
end
|
|
else
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed shuffle doubleword';
|
|
lastdisassembledata.opcode:='pshufd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(lastdisassembledata.parametervalue,2);
|
|
inc(offset,last);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed shuffle word';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpshufw'
|
|
else
|
|
lastdisassembledata.opcode:='pshufw';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(lastdisassembledata.parametervalue,2);
|
|
inc(offset,last);
|
|
end;
|
|
end;
|
|
|
|
$71 : begin
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[3];
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=3;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
case getreg(memory[2]) of
|
|
2 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed shift right logical';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpsrlw'
|
|
else
|
|
lastdisassembledata.opcode:='psrlw';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+','+inttohexs(memory[3],2);
|
|
inc(offset,3);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed shift right logical';
|
|
lastdisassembledata.opcode:='psrlw';
|
|
lastdisassembledata.parameters:=mm(memory[2])+','+inttohexs(memory[3],2);
|
|
inc(offset,3);
|
|
end;
|
|
end;
|
|
|
|
4 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='shift packed data right arithmetic';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpsraw'
|
|
else
|
|
LastDisassembleData.opcode:='psraw';
|
|
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,4,last);
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
|
|
inc(offset,last-1+1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed shift left logical';
|
|
LastDisassembleData.opcode:='psraw';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,3,last);
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
|
|
inc(offset,last-1+1);
|
|
end;
|
|
end;
|
|
|
|
6 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed shift left logical';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpsllw'
|
|
else
|
|
LastDisassembleData.opcode:='psllw';
|
|
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,4,last);
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
|
|
inc(offset,last-1+1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed shift left logical';
|
|
LastDisassembleData.opcode:='psllw';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,3,last);
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
|
|
inc(offset,last-1+1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$72 : begin
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[3];
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=3;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
case getreg(memory[2]) of
|
|
2 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed shift right logical';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpsrld'
|
|
else
|
|
lastdisassembledata.opcode:='psrld';
|
|
lastdisassembledata.parameters:= modrm(memory,prefix2,2,4,last);
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
inc(offset,3);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed shift right logical';
|
|
lastdisassembledata.opcode:='psrld';
|
|
lastdisassembledata.parameters:= modrm(memory,prefix2,2,3,last);
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
inc(offset,3);
|
|
end;
|
|
end;
|
|
|
|
4 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed shift right arithmetic';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpsrad'
|
|
else
|
|
lastdisassembledata.opcode:='psrad';
|
|
lastdisassembledata.parameters:= modrm(memory,prefix2,2,4,last);
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
|
|
inc(offset,3);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed shift right arithmetic';
|
|
lastdisassembledata.opcode:='psrad';
|
|
lastdisassembledata.parameters:= modrm(memory,prefix2,2,3,last);
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
|
|
inc(offset,3);
|
|
end;
|
|
end;
|
|
|
|
6 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed shift left logical';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='pslld'
|
|
else
|
|
lastdisassembledata.opcode:='pslld';
|
|
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,4,last);
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+','+inttohexs(memory[last],2);
|
|
inc(offset,3);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed shift left logical';
|
|
lastdisassembledata.opcode:='pslld';
|
|
lastdisassembledata.parameters:= modrm(memory,prefix2,2,3,last);
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
inc(offset,3);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$73 : begin
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[3];
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=3;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
case getreg(memory[2]) of
|
|
2 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed shift right logical';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpsrlq'
|
|
else
|
|
lastdisassembledata.opcode:='psrlq';
|
|
lastdisassembledata.parameters:= modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+','+inttohexs(memory[last],2);
|
|
inc(offset,3);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed shift right logical';
|
|
lastdisassembledata.opcode:='psrlq';
|
|
lastdisassembledata.parameters:= modrm(memory,prefix2,2,3,last,mRight);
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+','+inttohexs(memory[last],2);
|
|
inc(offset,3);
|
|
end;
|
|
delete(lastdisassembledata.parameters,1,1);
|
|
end;
|
|
|
|
3 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='shift double quadword right logical';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpsrldq'
|
|
else
|
|
lastdisassembledata.opcode:='psrldq';
|
|
|
|
lastdisassembledata.parameters:= modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+','+inttohexs(memory[last],2);
|
|
inc(offset,3);
|
|
end;
|
|
delete(lastdisassembledata.parameters,1,1);
|
|
end;
|
|
|
|
6 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed shift left logical';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpsllq'
|
|
else
|
|
lastdisassembledata.opcode:='psllq';
|
|
lastdisassembledata.parameters:= modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+','+inttohexs(memory[last],2);
|
|
inc(offset,3);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed shift left logical';
|
|
lastdisassembledata.opcode:='psllq';
|
|
lastdisassembledata.parameters:= modrm(memory,prefix2,2,3,last,mRight);
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+','+inttohexs(memory[last],2);
|
|
inc(offset,3);
|
|
end;
|
|
delete(lastdisassembledata.parameters,1,1);
|
|
end;
|
|
|
|
7 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='shift double quadword left logical';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpslldq'
|
|
else
|
|
lastdisassembledata.opcode:='pslldq';
|
|
lastdisassembledata.parameters:= modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+','+inttohexs(memory[last],2);
|
|
|
|
delete(lastdisassembledata.parameters,1,1);
|
|
inc(offset,3);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
$74 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed compare for equal';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpcmpeqb'
|
|
else
|
|
lastdisassembledata.opcode:='pcmpeqb';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed compare for equal';
|
|
lastdisassembledata.opcode:='pcmpeqb';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$75 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed compare for equal';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpcmpeqw'
|
|
else
|
|
lastdisassembledata.opcode:='pcmpeqw';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed compare for equal';
|
|
lastdisassembledata.opcode:='pcmpeqw';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$76 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed compare for equal';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpcmpeqd'
|
|
else
|
|
lastdisassembledata.opcode:='pcmpeqd';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed compare for equal';
|
|
lastdisassembledata.opcode:='pcmpeqd';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
|
|
$77 : begin
|
|
if hasvex then
|
|
begin
|
|
if opcodeflags.L then
|
|
begin
|
|
description:='Zero all YMM registers';
|
|
lastdisassembledata.opcode:='vzeroall';
|
|
inc(offset);
|
|
end
|
|
else
|
|
begin
|
|
description:='Zero upper bits of YMM registers';
|
|
lastdisassembledata.opcode:='vzeroupper';
|
|
inc(offset);
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
description:='empty mmx™ state';
|
|
lastdisassembledata.opcode:='emms';
|
|
inc(offset);
|
|
end;
|
|
end;
|
|
|
|
$78 : begin
|
|
description:='reads a specified vmcs field (32 bits)';
|
|
lastdisassembledata.opcode:='vmread';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last)+r32(memory[2]);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$79 : begin
|
|
description:='writes a specified vmcs field (32 bits)';
|
|
lastdisassembledata.opcode:='vmwrite';
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$7c : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vhaddpd'
|
|
else
|
|
lastdisassembledata.opcode:='haddpd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mright);
|
|
|
|
description:='packed double-fp horizontal add';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $f2 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vhaddps'
|
|
else
|
|
lastdisassembledata.opcode:='haddps';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mright);
|
|
|
|
description:='packed single-fp horizontal add';
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$7d : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vhsubpd'
|
|
else
|
|
lastdisassembledata.opcode:='hsubpd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mright);
|
|
|
|
description:='packed double-fp horizontal subtract';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $f2 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vhsubps'
|
|
else
|
|
lastdisassembledata.opcode:='hsubps';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mright);
|
|
|
|
description:='packed single-fp horizontal subtract';
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$7e : begin
|
|
|
|
if $f3 in prefix2 then
|
|
begin
|
|
|
|
description:='move quadword';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovq'
|
|
else
|
|
lastdisassembledata.opcode:='movq';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $66 in prefix2 then
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='move 64 bits';
|
|
lastdisassembledata.opcode:='movq';
|
|
end
|
|
else
|
|
begin
|
|
description:='move 32 bits';
|
|
lastdisassembledata.opcode:='movd';
|
|
end;
|
|
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='v'+lastdisassembledata.opcode;
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last)+xmm(memory[2]); //r32/rm32,xmm
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
if Rex_W then
|
|
begin
|
|
description:='move 64 bits';
|
|
lastdisassembledata.opcode:='movq';
|
|
end
|
|
else
|
|
begin
|
|
description:='move 32 bits';
|
|
lastdisassembledata.opcode:='movd';
|
|
end;
|
|
|
|
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last)+mm(memory[2]); //r32/rm32,mm
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$7f : begin
|
|
if $f3 in prefix2 then
|
|
begin
|
|
|
|
description:='move unaligned double quadword';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovdqu'
|
|
else
|
|
lastdisassembledata.opcode:='movdqu';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,4,last)+xmm(memory[2]);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='move aligned double quadword';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovdqa'
|
|
else
|
|
lastdisassembledata.opcode:='movdqa';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,4,last)+xmm(memory[2]);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='move 64 bits';
|
|
lastdisassembledata.opcode:='movq';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,3,last)+mm(memory[2]);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$80 : begin
|
|
description:='jump near if overflow (OF=1)';
|
|
lastdisassembledata.opcode:='jo';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_OF)<>0;
|
|
|
|
inc(offset,1+4);
|
|
if MarkIPRelativeInstructions then
|
|
begin
|
|
LastDisassembleData.riprelative:=2;
|
|
riprelative:=true;
|
|
end;
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(pint(@memory[2])^))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(pint(@memory[2])^));
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=2;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
end;
|
|
|
|
$81 : begin
|
|
description:='jump near if not overflow (OF=0)';
|
|
lastdisassembledata.opcode:='jno';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_OF)=0;
|
|
|
|
inc(offset,1+4);
|
|
if MarkIPRelativeInstructions then
|
|
begin
|
|
LastDisassembleData.riprelative:=2;
|
|
riprelative:=true;
|
|
end;
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(pint(@memory[2])^))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(pint(@memory[2])^));
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=2;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
end;
|
|
|
|
$82 : begin
|
|
description:='jump near if below/carry (CF=1)';
|
|
|
|
lastdisassembledata.opcode:='jb';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_CF)<>0;
|
|
|
|
inc(offset,1+4);
|
|
if MarkIPRelativeInstructions then
|
|
begin
|
|
LastDisassembleData.riprelative:=2;
|
|
riprelative:=true;
|
|
end;
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(pint(@memory[2])^))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(pint(@memory[2])^));
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=2;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
end;
|
|
|
|
$83 : begin
|
|
description:='jump near if above or equal (CF=0)';
|
|
lastdisassembledata.opcode:='jae';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_CF)=0;
|
|
|
|
inc(offset,1+4);
|
|
if MarkIPRelativeInstructions then
|
|
begin
|
|
LastDisassembleData.riprelative:=2;
|
|
riprelative:=true;
|
|
end;
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(pint(@memory[2])^))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(pint(@memory[2])^));
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=2;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
end;
|
|
|
|
$84 : begin
|
|
description:='jump near if equal (ZF=1)';
|
|
|
|
lastdisassembledata.opcode:='je';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_ZF)<>0;
|
|
|
|
inc(offset,1+4);
|
|
if MarkIPRelativeInstructions then
|
|
begin
|
|
LastDisassembleData.riprelative:=2;
|
|
riprelative:=true;
|
|
end;
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(pint(@memory[2])^))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(pint(@memory[2])^));
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=2;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
end;
|
|
|
|
|
|
$85 : begin
|
|
description:='jump near if not equal (ZF=0)';
|
|
lastdisassembledata.opcode:='jne';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_ZF)=0;
|
|
|
|
inc(offset,1+4);
|
|
if MarkIPRelativeInstructions then
|
|
begin
|
|
LastDisassembleData.riprelative:=2;
|
|
riprelative:=true;
|
|
end;
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(pint(@memory[2])^))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(pint(@memory[2])^));
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=2;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
end;
|
|
|
|
$86 : begin
|
|
description:='jump near if below or equal (CF=1 or ZF=1)';
|
|
lastdisassembledata.opcode:='jbe';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and (EFLAGS_CF or EFLAGS_ZF))<>0;
|
|
|
|
inc(offset,1+4);
|
|
if MarkIPRelativeInstructions then
|
|
begin
|
|
LastDisassembleData.riprelative:=2;
|
|
riprelative:=true;
|
|
end;
|
|
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(pint(@memory[2])^))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(pint(@memory[2])^));
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=2;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
end;
|
|
|
|
$87 : begin
|
|
description:='jump near if above (CF=0 and ZF=0)';
|
|
lastdisassembledata.opcode:='ja';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and (EFLAGS_CF or EFLAGS_ZF))=0;
|
|
|
|
|
|
inc(offset,1+4);
|
|
if MarkIPRelativeInstructions then
|
|
begin
|
|
LastDisassembleData.riprelative:=2;
|
|
riprelative:=true;
|
|
end;
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(pint(@memory[2])^))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(pint(@memory[2])^));
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=2;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
end;
|
|
|
|
$88 : begin
|
|
description:='jump near if sign (SF=1)';
|
|
lastdisassembledata.opcode:='js';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_SF)<>0;
|
|
|
|
inc(offset,1+4);
|
|
if MarkIPRelativeInstructions then
|
|
begin
|
|
LastDisassembleData.riprelative:=2;
|
|
riprelative:=true;
|
|
end;
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(pint(@memory[2])^))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(pint(@memory[2])^));
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=2;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
end;
|
|
|
|
$89 : begin
|
|
description:='jump near if not sign (SF=0)';
|
|
lastdisassembledata.opcode:='jns';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_SF)=0;
|
|
|
|
inc(offset,1+4);
|
|
if MarkIPRelativeInstructions then
|
|
begin
|
|
LastDisassembleData.riprelative:=2;
|
|
riprelative:=true;
|
|
end;
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(pint(@memory[2])^))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(pint(@memory[2])^));
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=2;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
end;
|
|
|
|
$8a : begin
|
|
description:='jump near if parity (PF=1)';
|
|
lastdisassembledata.opcode:='jp';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_PF)<>0;
|
|
|
|
inc(offset,1+4);
|
|
if MarkIPRelativeInstructions then
|
|
begin
|
|
LastDisassembleData.riprelative:=2;
|
|
riprelative:=true;
|
|
end;
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(pint(@memory[2])^))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(pint(@memory[2])^));
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=2;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
end;
|
|
|
|
$8b : begin
|
|
description:='jump near if not parity (PF=0)';
|
|
lastdisassembledata.opcode:='jnp';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_PF)=0;
|
|
|
|
inc(offset,1+4);
|
|
if MarkIPRelativeInstructions then
|
|
begin
|
|
LastDisassembleData.riprelative:=2;
|
|
riprelative:=true;
|
|
end;
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(pint(@memory[2])^))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(pint(@memory[2])^));
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=2;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
end;
|
|
|
|
$8c : begin
|
|
description:='jump near if less (SF~=OF)';
|
|
lastdisassembledata.opcode:='jl';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_SF)<>(context^.EFlags and EFLAGS_OF);
|
|
|
|
inc(offset,1+4);
|
|
if MarkIPRelativeInstructions then
|
|
begin
|
|
LastDisassembleData.riprelative:=2;
|
|
riprelative:=true;
|
|
end;
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(pint(@memory[2])^))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(pint(@memory[2])^));
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=2;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
end;
|
|
|
|
$8d : begin
|
|
description:='jump near if not less (SF=OF)';
|
|
lastdisassembledata.opcode:='jnl';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_SF)=(context^.EFlags and EFLAGS_OF);
|
|
|
|
inc(offset,1+4);
|
|
if MarkIPRelativeInstructions then
|
|
begin
|
|
LastDisassembleData.riprelative:=2;
|
|
riprelative:=true;
|
|
end;
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(pint(@memory[2])^))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(pint(@memory[2])^));
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=2;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
end;
|
|
|
|
$8e : begin
|
|
description:='jump near if not greater (ZF=1 or SF~=OF)';
|
|
lastdisassembledata.opcode:='jng';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=((context^.EFlags and EFLAGS_SF)<>(context^.EFlags and EFLAGS_OF)) or ((context^.EFlags and EFLAGS_ZF)<>0);
|
|
|
|
|
|
inc(offset,1+4);
|
|
if MarkIPRelativeInstructions then
|
|
begin
|
|
LastDisassembleData.riprelative:=2;
|
|
riprelative:=true;
|
|
end;
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(pint(@memory[2])^))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(pint(@memory[2])^));
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=2;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
end;
|
|
|
|
$8f : begin
|
|
description:='jump near if greater (ZF=0 and SF=OF)';
|
|
lastdisassembledata.opcode:='jg';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=((context^.EFlags and EFLAGS_SF)=(context^.EFlags and EFLAGS_OF)) and ((context^.EFlags and EFLAGS_ZF)=0);
|
|
|
|
|
|
inc(offset,1+4);
|
|
if MarkIPRelativeInstructions then
|
|
begin
|
|
LastDisassembleData.riprelative:=2;
|
|
riprelative:=true;
|
|
end;
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(pint(@memory[2])^))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(pint(@memory[2])^));
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=2;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
end;
|
|
|
|
$90 : begin
|
|
description:='set byte if overflow';
|
|
lastdisassembledata.opcode:='seto';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,2,last,8);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$91 : begin
|
|
description:='set byte if not overfloww';
|
|
lastdisassembledata.opcode:='setno';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,2,last,8);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$92 : begin
|
|
description:='set byte if below/carry';
|
|
lastdisassembledata.opcode:='setb';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,2,last,8);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$93 : begin
|
|
description:='set byte if above or equal';
|
|
lastdisassembledata.opcode:='setae';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,2,last,8);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$94 : begin
|
|
description:='set byte if equal';
|
|
lastdisassembledata.opcode:='sete';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,2,last,8);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$95 : begin
|
|
description:='set byte if not equal';
|
|
lastdisassembledata.opcode:='setne';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,2,last,8);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$96 : begin
|
|
description:='set byte if below or equal';
|
|
lastdisassembledata.opcode:='setbe';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,2,last,8);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$97 : begin
|
|
description:='set byte if above';
|
|
lastdisassembledata.opcode:='seta';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,2,last,8);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$98 : begin
|
|
description:='set byte if sign';
|
|
lastdisassembledata.opcode:='sets';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,2,last,8);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$99 : begin
|
|
description:='set byte if not sign';
|
|
lastdisassembledata.opcode:='setns';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,2,last,8);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$9a : begin
|
|
description:='set byte if parity';
|
|
lastdisassembledata.opcode:='setp';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,2,last,8);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$9b : begin
|
|
description:='set byte if not parity';
|
|
lastdisassembledata.opcode:='setnp';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,2,last,8);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$9c : begin
|
|
description:='set byte if less';
|
|
lastdisassembledata.opcode:='setl';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,2,last,8);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$9d : begin
|
|
description:='set byte if greater or equal';
|
|
lastdisassembledata.opcode:='setge';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,2,last,8);
|
|
inc(offset,last-1);
|
|
|
|
end;
|
|
|
|
$9e : begin
|
|
description:='set byte if less or equal';
|
|
lastdisassembledata.opcode:='setle';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,2,last,8);
|
|
inc(offset,last-1);
|
|
|
|
end;
|
|
|
|
$9f : begin
|
|
description:='set byte if greater';
|
|
lastdisassembledata.opcode:='setg';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,2,last,8);
|
|
inc(offset,last-1);
|
|
|
|
|
|
end;
|
|
|
|
$a0 : begin
|
|
description:='push word or doubleword onto the stack';
|
|
lastdisassembledata.opcode:='push';
|
|
lastdisassembledata.parameters:='fs';
|
|
inc(offset);
|
|
end;
|
|
|
|
$a1 : begin
|
|
description:='pop a value from the stack';
|
|
lastdisassembledata.opcode:='pop';
|
|
lastdisassembledata.parameters:='fs';
|
|
inc(offset);
|
|
end;
|
|
|
|
|
|
$a2 : begin
|
|
description:='cpu identification';
|
|
lastdisassembledata.opcode:='cpuid';
|
|
inc(offset);
|
|
end;
|
|
|
|
$a3 : begin
|
|
description:='bit test';
|
|
lastdisassembledata.opcode:='bt';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,1,last)+r16(memory[2]) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last)+r32(memory[2]);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$a4 : begin
|
|
description:='double precision shift left';
|
|
lastdisassembledata.opcode:='shld';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,1,last)+r16(memory[2]) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last)+r32(memory[2]);
|
|
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+','+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
|
|
end;
|
|
|
|
$a5 : begin
|
|
description:='double precision shift left';
|
|
lastdisassembledata.opcode:='shld';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,1,last)+r16(memory[2])+','+colorreg+'cl'+endcolor else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last)+r32(memory[2])+','+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
|
|
end;
|
|
|
|
$a8 : begin
|
|
description:='push word or doubleword onto the stack';
|
|
lastdisassembledata.opcode:='push';
|
|
lastdisassembledata.parameters:='gs';
|
|
inc(offset);
|
|
end;
|
|
|
|
$a9 : begin
|
|
description:='pop a value from the stack';
|
|
lastdisassembledata.opcode:='pop';
|
|
lastdisassembledata.parameters:='gs';
|
|
inc(offset);
|
|
end;
|
|
|
|
$aa : begin
|
|
description:='resume from system management mode';
|
|
lastdisassembledata.opcode:='rsm';
|
|
inc(offset);
|
|
end;
|
|
|
|
$ab : begin
|
|
description:='bit test and set';
|
|
lastdisassembledata.opcode:='bts';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,1,last)+r16(memory[2]) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last)+r32(memory[2]);
|
|
inc(offset,last-1);
|
|
|
|
end;
|
|
|
|
$ac : begin
|
|
description:='double precision shift right';
|
|
lastdisassembledata.opcode:='shrd';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,1,last)+r16(memory[2]) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last)+r32(memory[2]);
|
|
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+','+inttohex(memory[last],2);
|
|
inc(last);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$ad : begin
|
|
description:='double precision shift right';
|
|
lastdisassembledata.opcode:='shrd';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,1,last)+r16(memory[2])+','+colorreg+'cl'+endcolor else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last)+r32(memory[2])+','+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
|
|
end;
|
|
|
|
$ae : begin
|
|
case memory[2] of
|
|
$f0: begin
|
|
description:='memory fence';
|
|
lastdisassembledata.opcode:='mfence';
|
|
inc(offset,1);
|
|
end;
|
|
|
|
$f8: begin
|
|
description:='store fence';
|
|
lastdisassembledata.opcode:='sfence';
|
|
inc(offset,1);
|
|
end;
|
|
|
|
else
|
|
case getreg(memory[2]) of
|
|
0: begin
|
|
if $f3 in prefix2 then
|
|
begin
|
|
description:='read fs base address';
|
|
lastdisassembledata.opcode:='rdfsbase';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='store fp and mmx state and streaming simd extension state';
|
|
lastdisassembledata.opcode:='fxsave';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
1: begin
|
|
if $f3 in prefix2 then
|
|
begin
|
|
description:='read gs base address';
|
|
lastdisassembledata.opcode:='rdgsbase';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='restore fp and mmx state and streaming simd extension state';
|
|
lastdisassembledata.opcode:='fxrstor';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
2: begin
|
|
if $f3 in prefix2 then
|
|
begin
|
|
description:='write fs base address';
|
|
lastdisassembledata.opcode:='wrfsbase';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='load streaming simd extension control/status';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vldmxcsr'
|
|
else
|
|
lastdisassembledata.opcode:='ldmxcsr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
3: begin
|
|
if $f3 in prefix2 then
|
|
begin
|
|
description:='write gs base address';
|
|
lastdisassembledata.opcode:='wrgsbase';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='store streaming simd extension control/status';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='stmxcsr'
|
|
else
|
|
lastdisassembledata.opcode:='stmxcsr';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
4: begin
|
|
description:='save processor extended state';
|
|
if Rex_W then
|
|
lastdisassembledata.opcode:='xsave64'
|
|
else
|
|
lastdisassembledata.opcode:='xsave';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
5: begin
|
|
if getmod(memory[2])=3 then
|
|
begin
|
|
description:='Load Fence';
|
|
lastdisassembledata.opcode:='lfence';
|
|
inc(offset,2);
|
|
end
|
|
else
|
|
begin
|
|
description:='restore processor extended state';
|
|
if Rex_W then
|
|
lastdisassembledata.opcode:='xrstor64'
|
|
else
|
|
lastdisassembledata.opcode:='xrstor';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
6: begin
|
|
description:='save processor extended status optimized';
|
|
if Rex_W then
|
|
lastdisassembledata.opcode:='xsaveopt64'
|
|
else
|
|
lastdisassembledata.opcode:='xsaveopt';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
7: begin
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
end;
|
|
|
|
$af : begin
|
|
description:='signed multiply';
|
|
lastdisassembledata.opcode:='imul';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last,mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$b0 : begin
|
|
description:='compare and exchange';
|
|
lastdisassembledata.opcode:='cmpxchg';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,2,last)+r8(memory[2]);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$b1 : begin
|
|
description:='compare and exchange';
|
|
lastdisassembledata.opcode:='cmpxchg';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,1,last)+r16(memory[2]) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last)+r32(memory[2]);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$b2 : begin
|
|
description:='load far pointer';
|
|
lastdisassembledata.opcode:='lss';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last,mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$b3 : begin
|
|
description:='bit test and reset';
|
|
lastdisassembledata.opcode:='btr';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,1,last)+r16(memory[2]) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last)+r32(memory[2]);
|
|
inc(offset,last-1);
|
|
|
|
end;
|
|
|
|
$b4 : begin
|
|
description:='load far pointer';
|
|
lastdisassembledata.opcode:='lfs';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last,mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$b5 : begin
|
|
description:='load far pointer';
|
|
lastdisassembledata.opcode:='lgs';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last,mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$b6 : begin
|
|
description:='Move with zero-extend';
|
|
lastdisassembledata.opcode:='movzx';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,2,last,8,0,mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,2,last,8,0,mRight);
|
|
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$b7 : begin
|
|
description:='Move with zero-extend';
|
|
lastdisassembledata.opcode:='movzx';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last,16,0,mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,1,last,16,0,mRight);
|
|
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$b8 : begin
|
|
if $f3 in prefix2 then
|
|
begin
|
|
description:='Return the Count of Number of Bits Set to 1';
|
|
lastdisassembledata.opcode:='popcnt';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last,mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,1,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
|
|
$ba : begin
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
|
|
|
|
case getreg(memory[2]) of
|
|
4: begin
|
|
//bt
|
|
description:='bit test';
|
|
lastdisassembledata.opcode:='bt';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,1,last) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last); //notice the difference in the modrm 4th parameter
|
|
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
|
|
inc(offset,last-1+1);
|
|
end;
|
|
|
|
5: begin
|
|
//bts
|
|
description:='bit test and set';
|
|
lastdisassembledata.opcode:='bts';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,1,last) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last); //notice the difference in the modrm 4th parameter
|
|
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
inc(offset,last-1+1);
|
|
end;
|
|
|
|
6: begin
|
|
//btr
|
|
description:='bit test and reset';
|
|
lastdisassembledata.opcode:='btr';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,1,last) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last); //notice the difference in the modrm 4th parameter
|
|
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
|
|
inc(offset,last-1+1);
|
|
end;
|
|
|
|
7: begin
|
|
//btc
|
|
description:='bit test and complement';
|
|
lastdisassembledata.opcode:='btc';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,1,last) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last); //notice the difference in the modrm 4th parameter
|
|
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
|
|
inc(offset,last-1+1);
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
$bb : begin
|
|
description:='bit test and complement';
|
|
lastdisassembledata.opcode:='btc';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,1,last)+r16(memory[2]) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last)+r32(memory[2]);
|
|
inc(offset,last-1);
|
|
|
|
end;
|
|
|
|
|
|
$bc : begin
|
|
if $f3 in prefix2 then
|
|
begin
|
|
description:='count the number of trailing zero bits';
|
|
lastdisassembledata.opcode:='tzcnt';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last,mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
//bsf
|
|
description:='bit scan forward';
|
|
lastdisassembledata.opcode:='bsf';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last,mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last,mRight);
|
|
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$bd : begin
|
|
if $f3 in prefix2 then
|
|
begin
|
|
description:='count the number of leading zero bits';
|
|
lastdisassembledata.opcode:='lzcnt';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last,mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
//bsf
|
|
description:='bit scan reverse';
|
|
lastdisassembledata.opcode:='bsr';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,1,last,mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,0,last,mRight);
|
|
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$be : begin
|
|
description:='move with sign-extension';
|
|
lastdisassembledata.opcode:='movsx';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[2])+modrm(memory,prefix2,2,2,last,8,0,mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,2,last,8,0,mRight);
|
|
|
|
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$bf : begin
|
|
description:='move with sign-extension';
|
|
lastdisassembledata.opcode:='movsx';
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,1,last,16,0,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$c0 : begin
|
|
description:='exchange and add';
|
|
lastdisassembledata.opcode:='xadd';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,2,last)+r8(memory[2]);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$c1 : begin
|
|
description:='exchange and add';
|
|
lastdisassembledata.opcode:='xadd';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,1,last)+r16(memory[2]) else
|
|
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last)+r32(memory[2]);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$c2 : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,128,0,mRight);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
|
|
equationstr:='';
|
|
|
|
case lastdisassembledata.parametervalue of
|
|
0: equationstr:='eq';
|
|
1: equationstr:='lt';
|
|
2: equationstr:='le';
|
|
3: equationstr:='unord';
|
|
4: equationstr:='neq';
|
|
5: equationstr:='nlt';
|
|
6: equationstr:='nle';
|
|
7: equationstr:='ord';
|
|
else
|
|
begin
|
|
if hasvex then
|
|
begin
|
|
case lastdisassembledata.parametervalue of
|
|
$8: equationstr:='eq_uq';
|
|
$9: equationstr:='nge';
|
|
$a: equationstr:='ngt';
|
|
$b: equationstr:='false';
|
|
$c: equationstr:='neq_oq';
|
|
$d: equationstr:='ge';
|
|
$e: equationstr:='gt';
|
|
$f: equationstr:='true';
|
|
$10: equationstr:='eq_os';
|
|
$11: equationstr:='lt_oq';
|
|
$12: equationstr:='le_oq';
|
|
$13: equationstr:='unord_s';
|
|
$14: equationstr:='neq_us';
|
|
$15: equationstr:='nlt_uq';
|
|
$16: equationstr:='nle_uq';
|
|
$17: equationstr:='ord_s';
|
|
$18: equationstr:='eq_us';
|
|
$19: equationstr:='nge_uq';
|
|
$1a: equationstr:='ngt_uq';
|
|
$1b: equationstr:='false_os';
|
|
$1c: equationstr:='neq_os';
|
|
$1d: equationstr:='ge_oq';
|
|
$1e: equationstr:='gt_oq';
|
|
$1f: equationstr:='true_us';
|
|
end;
|
|
end
|
|
end;
|
|
end;
|
|
|
|
if $f2 in prefix2 then
|
|
begin
|
|
description:='compare scalar double-precision floating-point values';
|
|
lastdisassembledata.opcode:='cmp'+equationstr+'sd';
|
|
if equationstr='' then
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+','+inttohexs(lastdisassembledata.parametervalue,2);
|
|
|
|
lastdisassembledata.datasize:=8;
|
|
end
|
|
else
|
|
if $f3 in prefix2 then
|
|
begin
|
|
description:='packed single-fp compare';
|
|
lastdisassembledata.opcode:='cmp'+equationstr+'ss';
|
|
if equationstr='' then
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+','+inttohexs(lastdisassembledata.parametervalue,2);
|
|
|
|
lastdisassembledata.datasize:=4;
|
|
end
|
|
else
|
|
begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='compare packed double-precision floating-point values';
|
|
lastdisassembledata.opcode:='cmp'+equationstr+'pd';
|
|
if equationstr='' then
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+','+inttohexs(lastdisassembledata.parametervalue,2);
|
|
|
|
end
|
|
else
|
|
begin
|
|
description:='packed single-fp compare';
|
|
lastdisassembledata.opcode:='cmp'+equationstr+'ps';
|
|
if equationstr='' then
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+','+inttohexs(lastdisassembledata.parametervalue,2);
|
|
|
|
lastdisassembledata.datasize:=4;
|
|
end;
|
|
end;
|
|
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='v'+lastdisassembledata.opcode;
|
|
|
|
inc(offset,last);
|
|
end;
|
|
|
|
$c3 : begin
|
|
description:='store doubleword using non-temporal hint';
|
|
lastdisassembledata.opcode:='movnti';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last)+r32(memory[2]);
|
|
inc(offset,last);
|
|
end;
|
|
|
|
$c4 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='insert word';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpinsrw'
|
|
else
|
|
lastdisassembledata.opcode:='pinsrw';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,0,last,mRight);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(lastdisassembledata.parametervalue,2);
|
|
inc(offset,last);
|
|
end
|
|
else
|
|
begin
|
|
description:='insert word';
|
|
lastdisassembledata.opcode:='pinsrw';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,0,last,mRight);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(lastdisassembledata.parametervalue,2);
|
|
inc(offset,last);
|
|
end;
|
|
end;
|
|
|
|
$c5 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='extract word';
|
|
lastdisassembledata.opcode:='pextrw';
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,4,last);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(lastdisassembledata.parametervalue,2);
|
|
inc(offset,3);
|
|
end
|
|
else
|
|
begin
|
|
description:='extract word';
|
|
lastdisassembledata.opcode:='pextrw';
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(lastdisassembledata.parametervalue,2);
|
|
inc(offset,3);
|
|
end;
|
|
end;
|
|
|
|
$c6 : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='shuffle double-fp';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vshufpd'
|
|
else
|
|
lastdisassembledata.opcode:='shufpd';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+','+inttohexs(lastdisassembledata.parametervalue,2);
|
|
inc(offset,last);
|
|
end
|
|
else
|
|
begin
|
|
description:='shuffle single-fp';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vshufps'
|
|
else
|
|
lastdisassembledata.opcode:='shufps';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+','+inttohexs(lastdisassembledata.parametervalue,2);
|
|
lastdisassembledata.datasize:=4;
|
|
inc(offset,last);
|
|
end;
|
|
end;
|
|
|
|
$c7 : begin
|
|
case getreg(memory[2]) of
|
|
1: begin
|
|
description:='compare and exchange 8 bytes';
|
|
lastdisassembledata.opcode:='cmpxchg8b';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
3: begin
|
|
description:='restore processor extended status supervisor';
|
|
if Rex_W then
|
|
lastdisassembledata.opcode:='xrstors64'
|
|
else
|
|
lastdisassembledata.opcode:='xrstors';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
4: begin
|
|
description:='save processor extended state with compaction';
|
|
if Rex_W then
|
|
lastdisassembledata.opcode:='xsavec'
|
|
else
|
|
lastdisassembledata.opcode:='xsavec64';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
5: begin
|
|
description:='save processor extended state supervisor';
|
|
if Rex_W then
|
|
lastdisassembledata.opcode:='xsaves'
|
|
else
|
|
lastdisassembledata.opcode:='xsaves64';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
|
|
6: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if getmod(memory[2])=3 then //reg
|
|
begin
|
|
description:='read random numer';
|
|
lastdisassembledata.opcode:='rdrand';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,1,last);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='copy vmcs data to vmcs region in memory';
|
|
lastdisassembledata.opcode:='vmclear';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end
|
|
else
|
|
if $f3 in prefix2 then
|
|
begin
|
|
description:='enter vmx root operation';
|
|
lastdisassembledata.opcode:='vmxon';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
//check if it's a memory or register access
|
|
//if register it's rdrand else vmptrld
|
|
if getmod(memory[2])=3 then //reg
|
|
begin
|
|
description:='read random numer';
|
|
lastdisassembledata.opcode:='rdrand';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='loads the current vmcs pointer from memory';
|
|
lastdisassembledata.opcode:='vmptrld';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
|
|
end;
|
|
end;
|
|
|
|
7: begin
|
|
if getmod(memory[2])=3 then //reg
|
|
begin
|
|
description:='read random SEED';
|
|
lastdisassembledata.opcode:='rdseed';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,1,last)
|
|
else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='stores the current vmcs pointer into memory';
|
|
lastdisassembledata.opcode:='vmptrst';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
|
|
$c8..$cf : begin
|
|
//bswap
|
|
description:='byte swap';
|
|
lastdisassembledata.opcode:='bswap';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=rd16(memory[1]-$c8)
|
|
else
|
|
lastdisassembledata.parameters:=rd(memory[1]-$c8);
|
|
|
|
inc(offset);
|
|
end;
|
|
|
|
$d0 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='Packed Double-FP Add/Subtract';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vaddsubpd'
|
|
else
|
|
lastdisassembledata.opcode:='addsubpd';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $f2 in prefix2 then
|
|
begin
|
|
description:='Packed Single-FP Add/Subtract';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vaddsubps'
|
|
else
|
|
lastdisassembledata.opcode:='addsubps';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$d1 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed shift right logical';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpsrlw'
|
|
else
|
|
lastdisassembledata.opcode:='psrlw';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed shift right logical';
|
|
lastdisassembledata.opcode:='psrlw';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$d2 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed shift right logical';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpsrld'
|
|
else
|
|
lastdisassembledata.opcode:='psrld';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed shift right logical';
|
|
lastdisassembledata.opcode:='psrld';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$d3 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed shift right logical';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpsrlq'
|
|
else
|
|
lastdisassembledata.opcode:='psrlq';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed shift right logical';
|
|
lastdisassembledata.opcode:='psrlq';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$d4 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='add packed quadword integers';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpaddq'
|
|
else
|
|
lastdisassembledata.opcode:='paddq';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='add packed quadword integers';
|
|
lastdisassembledata.opcode:='paddq';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
|
|
$d5 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed multiply low';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpmullw'
|
|
else
|
|
lastdisassembledata.opcode:='pmullw';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed multiply low';
|
|
lastdisassembledata.opcode:='pmullw';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$d6 : begin
|
|
if $f2 in prefix2 then
|
|
begin
|
|
|
|
description:='move low quadword from xmm to mmx technology register';
|
|
lastdisassembledata.opcode:='movdq2q';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $f3 in prefix2 then
|
|
begin
|
|
|
|
description:='move low quadword from xmm to mmx technology register';
|
|
lastdisassembledata.opcode:='movq2dq';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='move low quadword from xmm to mmx technology register';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmovq'
|
|
else
|
|
lastdisassembledata.opcode:='movq';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,4,last)+xmm(memory[2]);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='move quadword from mmx technology to xmm register';
|
|
lastdisassembledata.opcode:='movq2dq';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,4,last)+mm(memory[2]);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
$d7 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='move byte mask to integer';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpmovmskb'
|
|
else
|
|
lastdisassembledata.opcode:='pmovmskb';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,4,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='move byte mask to integer';
|
|
lastdisassembledata.opcode:='pmovmskb';
|
|
lastdisassembledata.parameters:=r32(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$d8 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed subtract unsigned with saturation';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpsubusb'
|
|
else
|
|
lastdisassembledata.opcode:='psubusb';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed subtract unsigned with saturation';
|
|
lastdisassembledata.opcode:='psubusb';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$d9 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed subtract unsigned with saturation';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpsubusw'
|
|
else
|
|
lastdisassembledata.opcode:='psubusw';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed subtract unsigned with saturation';
|
|
lastdisassembledata.opcode:='psubusw';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$da : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed unsigned integer byte minimum';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpminub'
|
|
else
|
|
lastdisassembledata.opcode:='pminub';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed unsigned integer byte minimum';
|
|
lastdisassembledata.opcode:='pminub';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$db : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='logical and';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpand'
|
|
else
|
|
lastdisassembledata.opcode:='pand';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='logical and';
|
|
lastdisassembledata.opcode:='pand';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$dc : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed add unsigned with saturation';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpaddusb'
|
|
else
|
|
lastdisassembledata.opcode:='paddusb';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed add unsigned with saturation';
|
|
lastdisassembledata.opcode:='paddusb';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$dd : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed add unsigned with saturation';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpaddusw'
|
|
else
|
|
lastdisassembledata.opcode:='paddusw';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed add unsigned with saturation';
|
|
lastdisassembledata.opcode:='paddusw';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$de : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed unsigned integer byte maximum';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpmaxub'
|
|
else
|
|
lastdisassembledata.opcode:='pmaxub';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last, mLeft);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed unsigned integer byte maximum';
|
|
lastdisassembledata.opcode:='pmaxub';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$df : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='logical and not';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpandn'
|
|
else
|
|
lastdisassembledata.opcode:='pandn';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='logical and not';
|
|
lastdisassembledata.opcode:='pandn';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$e0 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed average';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpavgb'
|
|
else
|
|
lastdisassembledata.opcode:='pavgb';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed average';
|
|
lastdisassembledata.opcode:='pavgb';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$e1 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed shift right arithmetic';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpsraw'
|
|
else
|
|
lastdisassembledata.opcode:='psraw';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed shift right arithmetic';
|
|
lastdisassembledata.opcode:='psraw';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$e2 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed shift left logical';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpsrad'
|
|
else
|
|
lastdisassembledata.opcode:='psrad';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed shift left logical';
|
|
lastdisassembledata.opcode:='psrad';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$e3 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed average';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpavgw'
|
|
else
|
|
lastdisassembledata.opcode:='pavgw';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed average';
|
|
lastdisassembledata.opcode:='pavgw';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$e4 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed multiply high unsigned';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpmulhuw'
|
|
else
|
|
lastdisassembledata.opcode:='pmulhuw';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed multiply high unsigned';
|
|
lastdisassembledata.opcode:='pmulhuw';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$e5 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed multiply high';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpmulhw'
|
|
else
|
|
lastdisassembledata.opcode:='pmulhw';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed multiply high';
|
|
lastdisassembledata.opcode:='pmulhw';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$e6 : begin
|
|
if $f2 in prefix2 then
|
|
begin
|
|
|
|
description:='convert two packed signed dwords from param2 to two packed dp-floating point values in param1';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vcvtpd2dq'
|
|
else
|
|
lastdisassembledata.opcode:='cvtpd2dq';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
if $f3 in prefix2 then
|
|
begin
|
|
|
|
description:='convert two packed signed dwords from param2 to two packed dp-floating point values in param1';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vcvtdq2pd'
|
|
else
|
|
lastdisassembledata.opcode:='cvtdq2pd';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='convert with truncation packed double-precision floating-point values to packed doubleword integers';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vcvttpd2dq'
|
|
else
|
|
lastdisassembledata.opcode:='cvttpd2dq';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$e7 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='movntdq'
|
|
else
|
|
lastdisassembledata.opcode:='vmovntdq';
|
|
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,4,last)+xmm(memory[2]);
|
|
description:='move double quadword using non-temporal hint';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='movntq';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,3,last)+mm(memory[2]);
|
|
description:='move 64 bits non temporal';
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$e8 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed subtract with saturation';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpsubsb'
|
|
else
|
|
lastdisassembledata.opcode:='psubsb';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed subtract with saturation';
|
|
lastdisassembledata.opcode:='psubsb';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$e9 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed subtract with saturation';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpsubsw'
|
|
else
|
|
lastdisassembledata.opcode:='psubsw';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed subtract with saturation';
|
|
lastdisassembledata.opcode:='psubsw';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$ea : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed signed integer word minimum';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpminsw'
|
|
else
|
|
lastdisassembledata.opcode:='pminsw';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed signed integer word minimum';
|
|
lastdisassembledata.opcode:='pminsw';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$eb : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='bitwise logical or';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpor'
|
|
else
|
|
lastdisassembledata.opcode:='por';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='bitwise logical or';
|
|
lastdisassembledata.opcode:='por';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$ec : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed add with saturation';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpaddsb'
|
|
else
|
|
lastdisassembledata.opcode:='paddsb';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed add with saturation';
|
|
lastdisassembledata.opcode:='paddsb';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$ed : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed add with saturation';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpaddsw'
|
|
else
|
|
lastdisassembledata.opcode:='paddsw';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed add with saturation';
|
|
lastdisassembledata.opcode:='paddsw';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$ee : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed signed integer word maximum';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpmaxsw'
|
|
else
|
|
lastdisassembledata.opcode:='pmaxsw';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed signed integer word maximum';
|
|
lastdisassembledata.opcode:='pmaxsw';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$ef : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='logical exclusive or';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpxor'
|
|
else
|
|
lastdisassembledata.opcode:='pxor';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='logical exclusive or';
|
|
lastdisassembledata.opcode:='pxor';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$f0 : begin
|
|
if $f2 in prefix2 then
|
|
begin
|
|
description:='load unaligned integer 128 bits';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vlddqu'
|
|
else
|
|
lastdisassembledata.opcode:='lddqu';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
inc(offset);
|
|
end;
|
|
|
|
|
|
$f1 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed shift left logical';
|
|
lastdisassembledata.opcode:='psllw';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed shift left logical';
|
|
lastdisassembledata.opcode:='psllw';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$f2 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed shift left logical';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpslld'
|
|
else
|
|
lastdisassembledata.opcode:='pslld';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed shift left logical';
|
|
lastdisassembledata.opcode:='pslld';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$f3 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed shift left logical';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpsllq'
|
|
else
|
|
lastdisassembledata.opcode:='psllq';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed shift left logical';
|
|
lastdisassembledata.opcode:='psllq';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$f4 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='multiply packed unsigned doubleword integers';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='pmuludq'
|
|
else
|
|
lastdisassembledata.opcode:='vpmuludq';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='multiply packed unsigned doubleword integers';
|
|
lastdisassembledata.opcode:='pmuludq';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
|
|
$f5 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed multiply and add';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpmaddwd'
|
|
else
|
|
lastdisassembledata.opcode:='pmaddwd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed multiply and add';
|
|
lastdisassembledata.opcode:='pmaddwd';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$f6 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed sum of absolute differences';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpsadbw'
|
|
else
|
|
lastdisassembledata.opcode:='psadbw';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed sum of absolute differences';
|
|
lastdisassembledata.opcode:='psadbw';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$f7 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='store selected bytes of double quadword';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vmaskmovdqu'
|
|
else
|
|
lastdisassembledata.opcode:='maskmovdqu';
|
|
|
|
opcodeflags.skipExtraReg:=true;
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='byte mask write';
|
|
lastdisassembledata.opcode:='maskmovq';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$f8 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed subtract';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpsubb'
|
|
else
|
|
lastdisassembledata.opcode:='psubb';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed subtract';
|
|
lastdisassembledata.opcode:='psubb';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$f9 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed subtract';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpsubw'
|
|
else
|
|
lastdisassembledata.opcode:='psubw';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed subtract';
|
|
lastdisassembledata.opcode:='psubw';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$fa : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed subtract';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpsubd'
|
|
else
|
|
lastdisassembledata.opcode:='psubd';
|
|
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed subtract';
|
|
lastdisassembledata.opcode:='psubd';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$fb : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed subtract';
|
|
lastdisassembledata.opcode:='psubq';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed subtract';
|
|
lastdisassembledata.opcode:='psubq';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$fc : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed add';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpaddb'
|
|
else
|
|
lastdisassembledata.opcode:='paddb';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed add';
|
|
lastdisassembledata.opcode:='paddb';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$fd : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed add';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpaddw'
|
|
else
|
|
lastdisassembledata.opcode:='paddw';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last, mRight);
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed add';
|
|
lastdisassembledata.opcode:='paddw';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$fe : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='packed add';
|
|
if hasvex then
|
|
lastdisassembledata.opcode:='vpaddd'
|
|
else
|
|
lastdisassembledata.opcode:='paddd';
|
|
lastdisassembledata.parameters:=xmm(memory[2])+modrm(memory,prefix2,2,4,last, mRight);
|
|
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='packed add';
|
|
lastdisassembledata.opcode:='paddd';
|
|
lastdisassembledata.parameters:=mm(memory[2])+modrm(memory,prefix2,2,3,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
end;
|
|
|
|
//
|
|
|
|
//
|
|
|
|
$10 : begin
|
|
description:='add with carry';
|
|
lastdisassembledata.opcode:='adc';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last)+r8(memory[1]);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$11 : begin
|
|
description:='add with carry';
|
|
lastdisassembledata.opcode:='adc';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last)+r16(memory[1]) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last)+r32(memory[1]);
|
|
inc(offset,last-1);
|
|
|
|
end;
|
|
|
|
$12 : begin
|
|
description:='add with carry';
|
|
lastdisassembledata.opcode:='adc';
|
|
lastdisassembledata.parameters:=r8(memory[1])+modrm(memory,prefix2,1,2,last,8,0,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$13 : begin
|
|
description:='add with carry';
|
|
lastdisassembledata.opcode:='adc';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[1])+modrm(memory,prefix2,1,1,last,mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[1])+modrm(memory,prefix2,1,0,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$14 : begin
|
|
description:='add with carry';
|
|
lastdisassembledata.opcode:='adc';
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[1];
|
|
lastdisassembledata.parameters:=colorreg+'al'+endcolor+','+inttohexs(lastdisassembledata.parametervalue,2);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
inc(offset);
|
|
end;
|
|
|
|
$15 : begin
|
|
description:='add with carry';
|
|
lastdisassembledata.opcode:='adc';
|
|
if $66 in prefix2 then
|
|
begin
|
|
wordptr:=@memory[1];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
|
|
lastdisassembledata.parameters:=colorreg+'ax'+endcolor+','+inttohexs(lastdisassembledata.parametervalue,4);
|
|
inc(offset,2);
|
|
end
|
|
else
|
|
begin
|
|
dwordptr:=@memory[1];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
|
|
if rex_w then
|
|
lastdisassembledata.parameters:=colorreg+'rax'+endcolor+','+inttohexs(longint(lastdisassembledata.parametervalue),8)
|
|
else
|
|
lastdisassembledata.parameters:=colorreg+'eax'+endcolor+','+inttohexs(lastdisassembledata.parametervalue,8);
|
|
inc(offset,4);
|
|
end;
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
end;
|
|
|
|
$16 : begin
|
|
description:='place ss on the stack';
|
|
lastdisassembledata.opcode:='push';
|
|
lastdisassembledata.parameters:=colorreg+'ss'+endcolor;
|
|
end;
|
|
|
|
$17 : begin
|
|
description:='remove ss from the stack';
|
|
lastdisassembledata.opcode:='pop';
|
|
lastdisassembledata.parameters:=colorreg+'ss'+endcolor;
|
|
end;
|
|
|
|
$18 : begin
|
|
description:='integer subtraction with borrow';
|
|
lastdisassembledata.opcode:='sbb';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last)+r8(memory[1]);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$19 : begin
|
|
description:='integer subtraction with borrow';
|
|
lastdisassembledata.opcode:='sbb';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last)+r16(memory[1]) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last)+r32(memory[1]);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$1a : begin
|
|
description:='integer subtraction with borrow';
|
|
lastdisassembledata.opcode:='sbb';
|
|
lastdisassembledata.parameters:=r8(memory[1])+modrm(memory,prefix2,1,2,last,8,0,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$1b : begin
|
|
description:='integer subtraction with borrow';
|
|
lastdisassembledata.opcode:='sbb';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[1])+modrm(memory,prefix2,1,1,last,mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[1])+modrm(memory,prefix2,1,0,last,mRight);
|
|
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$1c : begin
|
|
description:='integer subtraction with borrow';
|
|
lastdisassembledata.opcode:='sbb';
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[1];
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.parameters:=colorreg+'al'+endcolor+','+inttohexs(memory[1],2);
|
|
|
|
|
|
inc(offset);
|
|
end;
|
|
|
|
$1d : begin
|
|
lastdisassembledata.opcode:='sbb';
|
|
description:='integer subtraction with borrow';
|
|
if $66 in prefix2 then
|
|
begin
|
|
wordptr:=@memory[1];
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
|
|
lastdisassembledata.parameters:=colorreg+'ax'+endcolor+','+inttohexs(wordptr^,4);
|
|
inc(offset,2);
|
|
end
|
|
else
|
|
begin
|
|
dwordptr:=@memory[1];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
|
|
if rex_w then
|
|
lastdisassembledata.parameters:=colorreg+'rax'+endcolor+','+inttohexs(longint(lastdisassembledata.parametervalue),8)
|
|
else
|
|
lastdisassembledata.parameters:=colorreg+'eax'+endcolor+','+inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
inc(offset,4);
|
|
end;
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
end;
|
|
|
|
$1e : begin
|
|
description:='place ds on the stack';
|
|
lastdisassembledata.opcode:='push';
|
|
lastdisassembledata.parameters:=colorreg+'ds'+endcolor;
|
|
end;
|
|
|
|
$1f : begin
|
|
description:='remove ds from the stack';
|
|
lastdisassembledata.opcode:='pop';
|
|
lastdisassembledata.parameters:=colorreg+'ds'+endcolor;
|
|
end;
|
|
|
|
$20 : begin
|
|
description:='logical and';
|
|
lastdisassembledata.opcode:='and';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last)+r8(memory[1]);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$21 : begin
|
|
description:='logical and';
|
|
lastdisassembledata.opcode:='and';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last)+r16(memory[1]) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last)+r32(memory[1]);
|
|
inc(offset,last-1);
|
|
|
|
end;
|
|
|
|
$22 : begin
|
|
description:='logical and';
|
|
lastdisassembledata.opcode:='and';
|
|
lastdisassembledata.parameters:=r8(memory[1])+modrm(memory,prefix2,1,2,last,mRight);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$23 : begin
|
|
description:='logical and';
|
|
lastdisassembledata.opcode:='and';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[1])+modrm(memory,prefix2,1,1,last,mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[1])+modrm(memory,prefix2,1,0,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
|
|
$24 : begin
|
|
description:='logical and';
|
|
lastdisassembledata.opcode:='and';
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[1];
|
|
lastdisassembledata.parameters:=colorreg+'al'+endcolor+','+inttohexs(memory[1],2);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
inc(offset);
|
|
end;
|
|
|
|
$25 : begin
|
|
description:='logical and';
|
|
lastdisassembledata.opcode:='and';
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
if $66 in prefix2 then
|
|
begin
|
|
wordptr:=@memory[1];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
lastdisassembledata.parameters:=colorreg+'ax'+endcolor+','+inttohexs(lastdisassembledata.parametervalue,4);
|
|
inc(offset,2);
|
|
end
|
|
else
|
|
begin
|
|
dwordptr:=@memory[1];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
|
|
if rex_w then
|
|
lastdisassembledata.parameters:=colorreg+'rax'+endcolor+','+inttohexs(longint(lastdisassembledata.parametervalue),8)
|
|
else
|
|
lastdisassembledata.parameters:=colorreg+'eax'+endcolor+','+inttohexs(lastdisassembledata.parametervalue,8);
|
|
inc(offset,4);
|
|
end;
|
|
end;
|
|
|
|
$27 : begin
|
|
description:='decimal adjust al after addition';
|
|
lastdisassembledata.opcode:='daa';
|
|
end;
|
|
|
|
$28 : begin
|
|
description:='subtract';
|
|
lastdisassembledata.opcode:='sub';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last)+r8(memory[1]);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$29 : begin
|
|
description:='subtract';
|
|
lastdisassembledata.opcode:='sub';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last)+r16(memory[1]) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last)+r32(memory[1]);
|
|
inc(offset,last-1);
|
|
|
|
end;
|
|
|
|
$2a : begin
|
|
description:='subtract';
|
|
lastdisassembledata.opcode:='sub';
|
|
lastdisassembledata.parameters:=r8(memory[1])+modrm(memory,prefix2,1,2,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$2b : begin
|
|
description:='subtract';
|
|
lastdisassembledata.opcode:='sub';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[1])+modrm(memory,prefix2,1,1,last,mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[1])+modrm(memory,prefix2,1,0,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$2c : begin
|
|
description:='subtract';
|
|
lastdisassembledata.opcode:='sub';
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[1];
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.parameters:=colorreg+'al'+endcolor+','+inttohexs(memory[1],2);
|
|
|
|
|
|
|
|
inc(offset);
|
|
end;
|
|
|
|
$2d : begin
|
|
description:='subtract';
|
|
lastdisassembledata.opcode:='sub';
|
|
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
if $66 in prefix2 then
|
|
begin
|
|
wordptr:=@memory[1];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
|
|
lastdisassembledata.parameters:=colorreg+'ax'+endcolor+','+inttohexs(wordptr^,4);
|
|
inc(offset,2);
|
|
end
|
|
else
|
|
begin
|
|
dwordptr:=@memory[1];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
|
|
|
|
if rex_w then
|
|
lastdisassembledata.parameters:=colorreg+'rax'+endcolor+','+IntToHexs(longint(dwordptr^),8)
|
|
else
|
|
lastdisassembledata.parameters:=colorreg+'eax'+endcolor+','+inttohexs(dwordptr^,8);
|
|
inc(offset,4);
|
|
end;
|
|
end;
|
|
|
|
|
|
$2f : begin
|
|
description:='decimal adjust al after subtraction';
|
|
lastdisassembledata.opcode:='das';
|
|
end;
|
|
|
|
$30 : begin
|
|
description:='logical exclusive or';
|
|
lastdisassembledata.opcode:='xor';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last)+r8(memory[1]);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$31 : begin
|
|
description:='logical exclusive or';
|
|
lastdisassembledata.opcode:='xor';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last)+r16(memory[1]) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last)+r32(memory[1]);
|
|
inc(offset,last-1);
|
|
|
|
end;
|
|
|
|
$32 : begin
|
|
description:='logical exclusive or';
|
|
lastdisassembledata.opcode:='xor';
|
|
lastdisassembledata.parameters:=r8(memory[1])+modrm(memory,prefix2,1,2,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$33 : begin
|
|
description:='logical exclusive or';
|
|
lastdisassembledata.opcode:='xor';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[1])+modrm(memory,prefix2,1,1,last,mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[1])+modrm(memory,prefix2,1,0,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$34 : begin
|
|
description:='logical exclusive or';
|
|
lastdisassembledata.opcode:='xor';
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[1];
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.parameters:=colorreg+'al'+endcolor+','+inttohexs(memory[1],2);
|
|
inc(offset);
|
|
end;
|
|
|
|
$35 : begin
|
|
description:='logical exclusive or';
|
|
lastdisassembledata.opcode:='xor';
|
|
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
if $66 in prefix2 then
|
|
begin
|
|
wordptr:=@memory[1];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
|
|
lastdisassembledata.parameters:=colorreg+'ax'+endcolor+','+inttohexs(wordptr^,4);
|
|
inc(offset,2);
|
|
end
|
|
else
|
|
begin
|
|
dwordptr:=@memory[1];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
|
|
if rex_w then
|
|
lastdisassembledata.parameters:=colorreg+'rax'+endcolor+','+inttohexs(longint(dwordptr^),8)
|
|
else
|
|
lastdisassembledata.parameters:=colorreg+'eax'+endcolor+','+inttohexs(dwordptr^,8);
|
|
inc(offset,4);
|
|
end;
|
|
end;
|
|
|
|
|
|
$37 : begin //aaa
|
|
lastdisassembledata.opcode:='aaa';
|
|
description:='ascii adjust al after addition'
|
|
end;
|
|
|
|
//---------
|
|
$38 : begin//cmp
|
|
description:='compare two operands';
|
|
lastdisassembledata.opcode:='cmp';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last)+r8(memory[1]);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$39 : begin
|
|
description:='compare two operands';
|
|
lastdisassembledata.opcode:='cmp';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last)+r16(memory[1]) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last)+r32(memory[1]);
|
|
|
|
inc(offset,last-1);
|
|
|
|
end;
|
|
|
|
$3a : begin
|
|
description:='compare two operands';
|
|
lastdisassembledata.opcode:='cmp';
|
|
lastdisassembledata.parameters:=r8(memory[1])+modrm(memory,prefix2,1,2,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$3b : begin
|
|
description:='compare two operands';
|
|
lastdisassembledata.opcode:='cmp';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[1])+modrm(memory,prefix2,1,1,last,mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[1])+modrm(memory,prefix2,1,0,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
//---------
|
|
|
|
$3c : begin
|
|
description:='compare two operands';
|
|
lastdisassembledata.opcode:='cmp';
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[1];
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.parameters:=colorreg+'al'+endcolor+','+inttohexs(memory[1],2);
|
|
inc(offset);
|
|
end;
|
|
|
|
$3d : begin
|
|
description:='compare two operands';
|
|
lastdisassembledata.opcode:='cmp';
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
if $66 in prefix2 then
|
|
begin
|
|
wordptr:=@memory[1];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
|
|
lastdisassembledata.parameters:=colorreg+'ax'+endcolor+','+inttohexs(wordptr^,4);
|
|
inc(offset,2);
|
|
end
|
|
else
|
|
begin
|
|
dwordptr:=@memory[1];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
|
|
|
|
if rex_w then
|
|
lastdisassembledata.parameters:=colorreg+'rax'+endcolor+','+inttohexs(longint(dwordptr^),8)
|
|
else
|
|
lastdisassembledata.parameters:=colorreg+'eax'+endcolor+','+inttohexs(dwordptr^,8);
|
|
inc(offset,4);
|
|
end;
|
|
end;
|
|
|
|
//prefix bytes need fixing
|
|
$3f : begin //aas
|
|
if processhandler.is64bit then
|
|
begin
|
|
lastdisassembledata.opcode:='db';
|
|
lastdisassembledata.parameters:=inttohexs($3f,1);
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='aas';
|
|
description:='ascii adjust al after subtraction';
|
|
end;
|
|
end;
|
|
|
|
$40..$47 :
|
|
begin
|
|
description:='increment by 1';
|
|
lastdisassembledata.opcode:='inc';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=rd16(memory[0]-$40) else
|
|
lastdisassembledata.parameters:=rd(memory[0]-$40);
|
|
end;
|
|
|
|
$48..$4f :
|
|
begin
|
|
description:='decrement by 1';
|
|
lastdisassembledata.opcode:='dec';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=rd16(memory[0]-$48) else
|
|
lastdisassembledata.parameters:=rd(memory[0]-$48);
|
|
end;
|
|
|
|
$50..$57 :
|
|
begin
|
|
description:='push word or doubleword onto the stack';
|
|
|
|
if is64bit then opcodeflags.w:=true;
|
|
|
|
lastdisassembledata.opcode:='push';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=rd16(memory[0]-$50) else
|
|
lastdisassembledata.parameters:=rd(memory[0]-$50);
|
|
end;
|
|
|
|
$58..$5f :
|
|
begin
|
|
description:='pop a value from the stack';
|
|
if is64bit then opcodeflags.w:=true; //so rd will pick the 64-bit version
|
|
lastdisassembledata.opcode:='pop';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=rd16(memory[0]-$58) else
|
|
lastdisassembledata.parameters:=rd(memory[0]-$58);
|
|
end;
|
|
|
|
$60 : begin
|
|
description:='push all general-purpose registers';
|
|
if is64bit then description:=description+' (invalid)';
|
|
if $66 in prefix2 then lastdisassembledata.opcode:='pusha' else
|
|
lastdisassembledata.opcode:='pushad';
|
|
|
|
if is64bit then
|
|
begin
|
|
description:=description+' (invalid)';
|
|
lastdisassembledata.opcode:='pushad (invalid)';
|
|
end;
|
|
end;
|
|
|
|
$61 : begin
|
|
description:='pop all general-purpose registers';
|
|
if $66 in prefix2 then lastdisassembledata.opcode:='popa' else
|
|
lastdisassembledata.opcode:='popad';
|
|
|
|
if is64bit then
|
|
begin
|
|
description:=description+' (invalid)';
|
|
lastdisassembledata.opcode:='popad (invalid)';
|
|
end;
|
|
|
|
end;
|
|
|
|
$62 : begin
|
|
//bound
|
|
description:='check array index against bounds';
|
|
lastdisassembledata.opcode:='bound';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[1])+modrm(memory,prefix2,1,1,last,mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[1])+modrm(memory,prefix2,1,0,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
|
|
end;
|
|
|
|
$63 : begin
|
|
//arpl or movsxd
|
|
if is64bit then
|
|
begin
|
|
lastdisassembledata.opcode:='movsxd';
|
|
opcodeflags.w:=false;
|
|
|
|
lastdisassembledata.parameters:=' '+r64(memory[1])+modrm(memory,prefix2,1,0,last,32,0,mRight);
|
|
inc(offset,last-1);
|
|
description:='Move doubleword to quadword with signextension';
|
|
|
|
LastDisassembleData.datasize:=4;
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='arpl';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last)+r16(memory[1]);
|
|
inc(offset,last-1);
|
|
description:='adjust rpl field of segment selector';
|
|
end;
|
|
end;
|
|
|
|
$68 : begin
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
if $66 in prefix2 then
|
|
begin
|
|
wordptr:=@memory[1];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
|
|
lastdisassembledata.opcode:='push';
|
|
lastdisassembledata.parameters:=inttohexs(wordptr^,4);
|
|
inc(offset,2);
|
|
end
|
|
else
|
|
begin
|
|
dwordptr:=@memory[1];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
|
|
lastdisassembledata.opcode:='push';
|
|
if processhandler.is64Bit then
|
|
lastdisassembledata.parameters:=inttohexs(longint(dwordptr^),8)
|
|
else
|
|
lastdisassembledata.parameters:=inttohexs(dwordptr^,8);
|
|
inc(offset,4);
|
|
end;
|
|
description:='push word or doubleword onto the stack (sign extended)';
|
|
end;
|
|
|
|
$69 : begin
|
|
description:='signed multiply';
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='imul';
|
|
lastdisassembledata.parameters:=r16(memory[1])+modrm(memory,prefix2,1,1,last,mRight);
|
|
wordptr:=@memory[last];
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
|
|
inc(offset,last-1+2);
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='imul';
|
|
lastdisassembledata.parameters:=r32(memory[1])+modrm(memory,prefix2,1,0,last,mRight);
|
|
dwordptr:=@memory[last];
|
|
if rex_w then
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+','+inttohexs(longint(dwordptr^),8)
|
|
else
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+','+inttohexs(dwordptr^,8);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
|
|
inc(offset,last-1+4);
|
|
end;
|
|
end;
|
|
|
|
$6a : begin
|
|
lastdisassembledata.opcode:='push';
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[1];
|
|
|
|
lastdisassembledata.parameters:=inttohexs(memory[1],2,true,1);
|
|
inc(offset);
|
|
description:='push byte onto the stack';
|
|
end;
|
|
|
|
$6b : begin
|
|
|
|
description:='signed multiply';
|
|
lastdisassembledata.opcode:='imul';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[1])+modrm(memory,prefix2,1,1,last,mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[1])+modrm(memory,prefix2,1,0,last,mRight);
|
|
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+','+inttohexs(memory[last],2);
|
|
inc(offset,last-1+1);
|
|
end;
|
|
|
|
$6c : begin
|
|
//m8, dx
|
|
description:='input from port to string';
|
|
lastdisassembledata.opcode:='insb';
|
|
end;
|
|
|
|
$6d : begin
|
|
//m8, dx
|
|
description:='input from port to string';
|
|
if $66 in prefix2 then lastdisassembledata.opcode:='insw' else
|
|
lastdisassembledata.opcode:='insd';
|
|
end;
|
|
|
|
$6e : begin
|
|
//m8, dx
|
|
description:='output string to port';
|
|
lastdisassembledata.opcode:='outsb';
|
|
end;
|
|
|
|
$6f : begin
|
|
//m8, dx
|
|
description:='output string to port';
|
|
if $66 in prefix2 then lastdisassembledata.opcode:='outsw' else
|
|
lastdisassembledata.opcode:='outsd';
|
|
end;
|
|
|
|
|
|
$70 : begin
|
|
description:='jump short if overflow (OF=1)';
|
|
lastdisassembledata.opcode:='jo';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_OF)<>0;
|
|
|
|
inc(offset);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtAddress;
|
|
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(shortint(memory[1])))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(shortint(memory[1])));
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
|
|
|
|
end;
|
|
|
|
$71 : begin
|
|
description:='jump short if not overflow (OF=0)';
|
|
lastdisassembledata.opcode:='jno';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_OF)=0;
|
|
|
|
inc(offset);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtAddress;
|
|
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(shortint(memory[1])))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(shortint(memory[1])));
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
end;
|
|
|
|
$72 : begin
|
|
description:='jump short if below/carry (CF=1)';
|
|
lastdisassembledata.opcode:='jb';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_CF)<>0;
|
|
inc(offset);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtAddress;
|
|
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(shortint(memory[1])))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(shortint(memory[1])));
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
end;
|
|
|
|
$73 : begin
|
|
description:='jump short if above or equal (CF=0)';
|
|
lastdisassembledata.opcode:='jae';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_CF)=0;
|
|
|
|
inc(offset);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtAddress;
|
|
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(shortint(memory[1])))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(shortint(memory[1])));
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
end;
|
|
|
|
$74 : begin
|
|
description:='jump short if equal (ZF=1)';
|
|
lastdisassembledata.opcode:='je';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_ZF)<>0;
|
|
|
|
inc(offset);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtAddress;
|
|
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(shortint(memory[1])))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(shortint(memory[1])));
|
|
|
|
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
end;
|
|
|
|
$75 : begin
|
|
description:='jump short if not equal (ZF=0)';
|
|
lastdisassembledata.opcode:='jne';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_ZF)=0;
|
|
inc(offset);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtAddress;
|
|
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(shortint(memory[1])))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(shortint(memory[1])));
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
end;
|
|
|
|
$76 : begin
|
|
description:='jump short if not above (ZF=1 or CF=1)';
|
|
lastdisassembledata.opcode:='jna';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
Lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and (EFLAGS_CF or EFLAGS_ZF))<>0;
|
|
|
|
|
|
inc(offset);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtAddress;
|
|
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(shortint(memory[1])))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(shortint(memory[1])));
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
end;
|
|
|
|
$77 : begin
|
|
description:='jump short if above (ZF=0 and CF=0)';
|
|
lastdisassembledata.opcode:='ja';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
Lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and (EFLAGS_CF or EFLAGS_ZF))=0;
|
|
|
|
|
|
inc(offset);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtAddress;
|
|
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(shortint(memory[1])))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(shortint(memory[1])));
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
end;
|
|
|
|
$78 : begin
|
|
description:='jump short if sign (SF=1)';
|
|
lastdisassembledata.opcode:='js';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_SF)<>0;
|
|
|
|
inc(offset);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtAddress;
|
|
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(shortint(memory[1])))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(shortint(memory[1])));
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
end;
|
|
|
|
$79 : begin
|
|
description:='jump short if not sign (SF=0)';
|
|
lastdisassembledata.opcode:='jns';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_SF)=0;
|
|
|
|
inc(offset);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtAddress;
|
|
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(shortint(memory[1])))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(shortint(memory[1])));
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
end;
|
|
|
|
$7a : begin
|
|
description:='jump short if parity (PF=1)';
|
|
lastdisassembledata.opcode:='jp';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_PF)<>0;
|
|
|
|
inc(offset);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtAddress;
|
|
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(shortint(memory[1])))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(shortint(memory[1])));
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
end;
|
|
|
|
$7b : begin
|
|
description:='jump short if not parity (PF=0)';
|
|
lastdisassembledata.opcode:='jnp';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_PF)=0;
|
|
|
|
inc(offset);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtAddress;
|
|
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(shortint(memory[1])))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(shortint(memory[1])));
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
end;
|
|
|
|
$7c : begin
|
|
description:='jump short if not greater or equal (SF~=OF)';
|
|
lastdisassembledata.opcode:='jl'; //jnge
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_SF)<>(context^.EFlags and EFLAGS_OF);
|
|
|
|
|
|
inc(offset);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtAddress;
|
|
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(shortint(memory[1])))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(shortint(memory[1])));
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
end;
|
|
|
|
$7d : begin
|
|
description:='jump short if not less (greater or equal) (SF=OF)';
|
|
lastdisassembledata.opcode:='jnl';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_SF)=(context^.EFlags and EFLAGS_OF);
|
|
|
|
|
|
inc(offset);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtAddress;
|
|
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(shortint(memory[1])))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(shortint(memory[1])));
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
end;
|
|
|
|
$7e : begin
|
|
description:='jump short if less or equal (ZF=1 or SF~=OF)';
|
|
lastdisassembledata.opcode:='jle';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=((context^.EFlags and EFLAGS_SF)<>(context^.EFlags and EFLAGS_OF)) or ((context^.EFlags and EFLAGS_ZF)<>0);
|
|
|
|
|
|
inc(offset);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(shortint(memory[1])))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(shortint(memory[1])));
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
lastdisassembledata.parameterValueType:=dvtAddress;
|
|
end;
|
|
|
|
$7f : begin
|
|
description:='jump short if greater (ZF=0 or SF=OF)';
|
|
lastdisassembledata.opcode:='jg';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=((context^.EFlags and EFLAGS_SF)=(context^.EFlags and EFLAGS_OF)) and ((context^.EFlags and EFLAGS_ZF)=0);
|
|
|
|
|
|
inc(offset);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(shortint(memory[1])))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(shortint(memory[1])));
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
lastdisassembledata.parameterValueType:=dvtAddress;
|
|
end;
|
|
|
|
$80,$82 : begin
|
|
case getreg(memory[1]) of
|
|
0: begin
|
|
//add
|
|
lastdisassembledata.opcode:='add';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
offset:=offset+last;
|
|
description:='add x to y';
|
|
end;
|
|
|
|
1: begin
|
|
//adc
|
|
lastdisassembledata.opcode:='or';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
offset:=offset+last;
|
|
description:='logical inclusive or';
|
|
end;
|
|
|
|
|
|
2: begin
|
|
//adc
|
|
lastdisassembledata.opcode:='adc';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
offset:=offset+last;
|
|
description:='add with carry';
|
|
end;
|
|
|
|
3: begin
|
|
//sbb
|
|
lastdisassembledata.opcode:='sbb';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
offset:=offset+last;
|
|
description:='integer subtraction with borrow';
|
|
end;
|
|
|
|
4: begin
|
|
//and
|
|
lastdisassembledata.opcode:='and';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
offset:=offset+last;
|
|
description:='logical and';
|
|
end;
|
|
|
|
5: begin
|
|
lastdisassembledata.opcode:='sub';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
offset:=offset+last;
|
|
description:='subtract';
|
|
end;
|
|
|
|
6: begin
|
|
lastdisassembledata.opcode:='xor';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
offset:=offset+last;
|
|
description:='logical exclusive or';
|
|
end;
|
|
|
|
7: begin
|
|
lastdisassembledata.opcode:='cmp';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
offset:=offset+last;
|
|
description:='compare two operands';
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
|
|
$81 : begin
|
|
case getreg(memory[1]) of
|
|
0: begin
|
|
//add
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='add';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
wordptr:=@memory[last];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(wordptr^,4);
|
|
inc(offset,last-1+2);
|
|
end else
|
|
begin
|
|
lastdisassembledata.opcode:='add';
|
|
if rex_w then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64)
|
|
else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
dwordptr:=@memory[last];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
|
|
if Rex_W then
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(longint(dwordptr^),8)
|
|
else
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(dwordptr^,8);
|
|
inc(offset,last-1+4);
|
|
end;
|
|
|
|
// offset:=offset+last;
|
|
description:='add x to y';
|
|
end;
|
|
|
|
1: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='or';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
wordptr:=@memory[last];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(wordptr^,4);
|
|
inc(offset,last-1+2);
|
|
end else
|
|
begin
|
|
lastdisassembledata.opcode:='or';
|
|
if rex_w then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64)
|
|
else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
dwordptr:=@memory[last];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
|
|
if Rex_W then
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(longint(dwordptr^),8)
|
|
else
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(dwordptr^,8);
|
|
inc(offset,last-1+4);
|
|
end;
|
|
|
|
|
|
description:='logical inclusive or';
|
|
end;
|
|
|
|
2: begin
|
|
//adc
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='adc';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
wordptr:=@memory[last];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(wordptr^,4);
|
|
inc(offset,last-1+2);
|
|
end else
|
|
begin
|
|
lastdisassembledata.opcode:='adc';
|
|
if rex_w then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64)
|
|
else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
dwordptr:=@memory[last];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
|
|
if Rex_W then
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(longint(dwordptr^),8)
|
|
else
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(dwordptr^,8);
|
|
inc(offset,last-1+4);
|
|
end;
|
|
|
|
|
|
description:='add with carry';
|
|
end;
|
|
|
|
3: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='sbb';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
wordptr:=@memory[last];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(wordptr^,4);
|
|
inc(offset,last-1+2);
|
|
end else
|
|
begin
|
|
lastdisassembledata.opcode:='sbb';
|
|
if rex_w then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64)
|
|
else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
dwordptr:=@memory[last];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
|
|
if Rex_W then
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(longint(dwordptr^),8)
|
|
else
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(dwordptr^,8);
|
|
inc(offset,last-1+4);
|
|
end;
|
|
|
|
|
|
description:='integer subtraction with borrow';
|
|
end;
|
|
|
|
|
|
4: begin
|
|
//and
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='and';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
wordptr:=@memory[last];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(wordptr^,4);
|
|
inc(offset,last-1+2);
|
|
end else
|
|
begin
|
|
lastdisassembledata.opcode:='and';
|
|
if rex_w then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64)
|
|
else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
dwordptr:=@memory[last];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
|
|
if Rex_W then
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(longint(dwordptr^),8)
|
|
else
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(dwordptr^,8);
|
|
inc(offset,last-1+4);
|
|
end;
|
|
|
|
|
|
description:='logical and';
|
|
end;
|
|
|
|
5: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='sub';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last);
|
|
wordptr:=@memory[last];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(wordptr^,4);
|
|
inc(offset,last-1+2);
|
|
end else
|
|
begin
|
|
lastdisassembledata.opcode:='sub';
|
|
if rex_w then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64)
|
|
else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
dwordptr:=@memory[last];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
|
|
if Rex_W then
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(longint(dwordptr^),8)
|
|
else
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(dwordptr^,8);
|
|
inc(offset,last-1+4);
|
|
end;
|
|
|
|
|
|
description:='subtract';
|
|
end;
|
|
|
|
6: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='xor';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
wordptr:=@memory[last];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(wordptr^,4);
|
|
inc(offset,last-1+2);
|
|
end else
|
|
begin
|
|
lastdisassembledata.opcode:='xor';
|
|
if rex_w then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64)
|
|
else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
dwordptr:=@memory[last];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
|
|
if Rex_W then
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(longint(dwordptr^),8)
|
|
else
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(dwordptr^,8);
|
|
inc(offset,last-1+4);
|
|
end;
|
|
description:='logical exclusive or';
|
|
end;
|
|
|
|
7: begin
|
|
//cmp
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='cmp';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
wordptr:=@memory[last];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(wordptr^,4);
|
|
inc(offset,last-1+2);
|
|
end else
|
|
begin
|
|
lastdisassembledata.opcode:='cmp';
|
|
if rex_w then
|
|
begin
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
lastdisassembledata.datasize:=8;;
|
|
end
|
|
else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
dwordptr:=@memory[last];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
|
|
if Rex_W then
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(longint(dwordptr^),8)
|
|
else
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(dwordptr^,8);
|
|
inc(offset,last-1+4);
|
|
end;
|
|
|
|
description:='compare two operands';
|
|
end;
|
|
|
|
|
|
end;
|
|
end;
|
|
|
|
$83 : begin
|
|
case getreg(memory[1]) of
|
|
0: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='add';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2, true);
|
|
end else
|
|
begin
|
|
lastdisassembledata.opcode:='add';
|
|
|
|
if rex_w then
|
|
begin
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2, true)
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2, true);
|
|
end;
|
|
|
|
end;
|
|
|
|
inc(offset,last);
|
|
description:='add (sign extended)';
|
|
end;
|
|
|
|
1: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='or';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
end else
|
|
begin
|
|
lastdisassembledata.opcode:='or';
|
|
if rex_w then
|
|
begin
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2)
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
end;
|
|
end;
|
|
|
|
inc(offset,last);
|
|
description:='add (sign extended)';
|
|
end;
|
|
|
|
|
|
2: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='adc';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
end else
|
|
begin
|
|
lastdisassembledata.opcode:='adc';
|
|
if rex_w then
|
|
begin
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2)
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
end;
|
|
|
|
end;
|
|
|
|
inc(offset,last);
|
|
description:='add with carry (sign extended)';
|
|
end;
|
|
|
|
3: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='sbb';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
end else
|
|
begin
|
|
lastdisassembledata.opcode:='sbb';
|
|
if rex_w then
|
|
begin
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2)
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
end;
|
|
end;
|
|
|
|
inc(offset,last);
|
|
description:='integer subtraction with borrow (sign extended)';
|
|
end;
|
|
|
|
4: begin
|
|
//and
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='and';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
end else
|
|
begin
|
|
lastdisassembledata.opcode:='and';
|
|
if rex_w then
|
|
begin
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2)
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
end;
|
|
|
|
end;
|
|
|
|
offset:=offset+last;
|
|
description:='logical and (sign extended)';
|
|
end;
|
|
|
|
5: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='sub';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
end else
|
|
begin
|
|
lastdisassembledata.opcode:='sub';
|
|
if rex_w then
|
|
begin
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2)
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
end;
|
|
end;
|
|
|
|
offset:=offset+last;
|
|
description:='subtract';
|
|
end;
|
|
|
|
6: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='xor';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
end else
|
|
begin
|
|
lastdisassembledata.opcode:='xor';
|
|
if rex_w then
|
|
begin
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2)
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
end;
|
|
end;
|
|
|
|
offset:=offset+last;
|
|
description:='logical exclusive or';
|
|
end;
|
|
|
|
7: begin
|
|
//cmp
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='cmp';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
end else
|
|
begin
|
|
lastdisassembledata.opcode:='cmp';
|
|
if rex_w then
|
|
begin
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2)
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
end;
|
|
end;
|
|
|
|
offset:=offset+last;
|
|
description:='compare two operands';
|
|
end;
|
|
|
|
|
|
end;
|
|
end;
|
|
|
|
$84 : begin
|
|
description:='logical compare';
|
|
lastdisassembledata.opcode:='test';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last)+r8(memory[1]);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$85 : begin
|
|
description:='logical compare';
|
|
lastdisassembledata.opcode:='test';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last)+r16(memory[1]) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last)+r32(memory[1]);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$86 : begin
|
|
description:='exchange memory with register';
|
|
lastdisassembledata.opcode:='xchg';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last)+r8(memory[1]);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$87 : begin
|
|
description:='exchange memory with register';
|
|
lastdisassembledata.opcode:='xchg';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last)+r16(memory[1]) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last)+r32(memory[1]);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$88 : begin
|
|
description:='copy memory';
|
|
lastdisassembledata.opcode:='mov';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last)+r8(memory[1]);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$89 : begin
|
|
description:='copy memory';
|
|
lastdisassembledata.opcode:='mov';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last)+r16(memory[1]) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last)+r32(memory[1]);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$8a : begin
|
|
description:='copy memory';
|
|
lastdisassembledata.opcode:='mov';
|
|
lastdisassembledata.parameters:=r8(memory[1])+modrm(memory,prefix2,1,2,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$8b : begin
|
|
description:='copy memory';
|
|
lastdisassembledata.opcode:='mov';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[1])+modrm(memory,prefix2,1,1,last,mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[1])+modrm(memory,prefix2,1,0,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$8c : begin
|
|
description:='copy memory';
|
|
lastdisassembledata.opcode:='mov';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last)+sreg(memory[1]);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$8d : begin
|
|
description:='load effective address';
|
|
lastdisassembledata.opcode:='lea';
|
|
if $66 in prefix2 then
|
|
begin
|
|
if processhandler.is64Bit and ($67 in prefix2) then
|
|
lastdisassembledata.parameters:=r16(memory[1])+modrm(memory,prefix2,1,1,last,0,32,mRight)
|
|
else
|
|
lastdisassembledata.parameters:=r16(memory[1])+modrm(memory,prefix2,1,1,last,0,0,mRight);
|
|
end
|
|
else
|
|
begin
|
|
if processhandler.is64Bit and ($67 in prefix2) then
|
|
lastdisassembledata.parameters:=r32(memory[1])+modrm(memory,prefix2,1,0,last,0,32,mRight)
|
|
else
|
|
lastdisassembledata.parameters:=r32(memory[1])+modrm(memory,prefix2,1,0,last,0,0,mRight)
|
|
end;
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$8e : begin
|
|
description:='copy memory';
|
|
lastdisassembledata.opcode:='mov';
|
|
lastdisassembledata.parameters:=sreg(memory[1])+modrm(memory,prefix2,1,1,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
$8f : begin
|
|
case getreg(memory[1]) of
|
|
0: begin
|
|
description:='pop a value from the stack';
|
|
lastdisassembledata.opcode:='pop';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='db';
|
|
lastdisassembledata.parameters:=colorhex+'8f'+endcolor;
|
|
description:='undefined by the intel specification';
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
$90 : begin
|
|
description:='no operation';
|
|
lastdisassembledata.opcode:='nop';
|
|
if prefixsize>0 then
|
|
begin
|
|
if RexPrefix<>0 then
|
|
begin
|
|
|
|
description:='Exchange '+ifthen(processhandler.is64bit,'R','E')+'AX with register';
|
|
lastdisassembledata.opcode:='xchg';
|
|
if rex_w then
|
|
lastdisassembledata.parameters:=colorreg+'rax'+endcolor+','+rd(memory[0]-$90)
|
|
else
|
|
lastdisassembledata.parameters:=colorreg+'eax'+endcolor+','+rd(memory[0]-$90);
|
|
end
|
|
else
|
|
lastdisassembledata.parameters:=inttohexs(prefixsize+1,1);
|
|
end;
|
|
end;
|
|
|
|
$91..$97:
|
|
begin
|
|
description:='exchange register with register';
|
|
lastdisassembledata.opcode:='xchg';
|
|
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=colorreg+'ax'+endcolor+','+rd16(memory[0]-$90)
|
|
else
|
|
begin
|
|
if rex_w then
|
|
lastdisassembledata.parameters:=colorreg+'rax'+endcolor+','+rd(memory[0]-$90)
|
|
else
|
|
lastdisassembledata.parameters:=colorreg+'eax'+endcolor+','+rd(memory[0]-$90);
|
|
end;
|
|
end;
|
|
|
|
|
|
$98 : begin
|
|
//cbw/cwde
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='cbw';
|
|
description:='convert byte to word';
|
|
end else
|
|
begin
|
|
if rex_w then
|
|
begin
|
|
lastdisassembledata.opcode:='cdqe';
|
|
description:='convert doubleword to quadword';
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='cwde';
|
|
description:='convert word to doubleword';
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$99 : begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='convert word to doubleword';
|
|
lastdisassembledata.opcode:='cwd';
|
|
end
|
|
else
|
|
begin
|
|
|
|
if rex_w then
|
|
begin
|
|
lastdisassembledata.opcode:='cqo';
|
|
description:='convert quadword to octword';
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='cdq';
|
|
description:='convert doubleword to quadword';
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$9a : begin
|
|
description:='call procedure';
|
|
wordptr:=@memory[5];
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=5;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
|
|
if is64bit then
|
|
lastdisassembledata.opcode:='call (invalid)'
|
|
else
|
|
lastdisassembledata.opcode:='call';
|
|
|
|
|
|
lastdisassembledata.parameters:=inttohexs(wordptr^,4)+':';
|
|
dwordptr:=@memory[1];
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
|
|
inc(offset,6);
|
|
end;
|
|
|
|
$9b : begin
|
|
case memory[1] of
|
|
|
|
$d9 : begin
|
|
case getreg(memory[2]) of
|
|
6: begin
|
|
description:='store fpu environment';
|
|
lastdisassembledata.opcode:='wait:fstenv';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
|
|
7: begin
|
|
description:='store control word';
|
|
lastdisassembledata.opcode:='wait:fstcw';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
else
|
|
begin
|
|
description:='wait';
|
|
lastdisassembledata.opcode:='wait';
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
|
|
$db : begin
|
|
case memory[2] of
|
|
$e2 : begin
|
|
description:='clear exceptions';
|
|
lastdisassembledata.opcode:='wait:fclex';
|
|
inc(offset,2);
|
|
end;
|
|
|
|
$e3 : begin
|
|
description:='initialize floaring-point unit';
|
|
lastdisassembledata.opcode:='wait:finit';
|
|
inc(offset,2);
|
|
end;
|
|
else
|
|
begin
|
|
description:='wait';
|
|
lastdisassembledata.opcode:='wait';
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$dd : begin
|
|
case getreg(memory[2]) of
|
|
6: begin
|
|
description:='store fpu state';
|
|
lastdisassembledata.opcode:='wait:fsave';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
7: begin
|
|
description:='store status word';
|
|
lastdisassembledata.opcode:='wait:fstsw';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,2,0,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
else
|
|
begin
|
|
description:='wait';
|
|
lastdisassembledata.opcode:='wait';
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$df : begin
|
|
case memory[2] of
|
|
$e0 : begin
|
|
description:='store status word';
|
|
lastdisassembledata.opcode:='wait:fstsw ax';
|
|
inc(offset,2);
|
|
end;
|
|
|
|
else
|
|
begin
|
|
description:='wait';
|
|
lastdisassembledata.opcode:='wait';
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
else begin
|
|
description:='wait';
|
|
lastdisassembledata.opcode:='wait';
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
$9c : begin
|
|
description:='push eflags register onto the stack';
|
|
if $66 in prefix2 then lastdisassembledata.opcode:='pushf' else
|
|
begin
|
|
if is64bit then
|
|
lastdisassembledata.opcode:='pushfq'
|
|
else
|
|
lastdisassembledata.opcode:='pushfd';
|
|
end;
|
|
end;
|
|
|
|
$9d : begin
|
|
description:='pop stack into eflags register';
|
|
if $66 in prefix2 then lastdisassembledata.opcode:='popf' else
|
|
begin
|
|
if is64bit then
|
|
lastdisassembledata.opcode:='popfq'
|
|
else
|
|
lastdisassembledata.opcode:='popfd';
|
|
end;
|
|
end;
|
|
|
|
$9e : begin
|
|
description:='store ah into flags';
|
|
lastdisassembledata.opcode:='sahf';
|
|
end;
|
|
|
|
$9f : begin
|
|
description:='load status flag into ah register';
|
|
lastdisassembledata.opcode:='lahf';
|
|
end;
|
|
|
|
$a0 : begin
|
|
description:='copy memory';
|
|
dwordptr:=@memory[1];
|
|
lastdisassembledata.opcode:='mov';
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
if processhandler.is64bit then
|
|
begin
|
|
lastdisassembledata.parameters:=colorreg+'al'+endcolor+','+getsegmentoverride(prefix2)+'['+inttohexs(pqword(dwordptr)^,8)+']';
|
|
inc(offset,8);
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.parameters:=colorreg+'al'+endcolor+','+getsegmentoverride(prefix2)+'['+inttohexs(dwordptr^,8)+']';
|
|
inc(offset,4);
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
$a1 : begin
|
|
description:='copy memory';
|
|
lastdisassembledata.opcode:='mov';
|
|
dwordptr:=@memory[1];
|
|
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.parameters:=colorreg+'ax'+endcolor+','+getsegmentoverride(prefix2)+'['+inttohexs(dwordptr^,8)+']';
|
|
end
|
|
else
|
|
begin
|
|
if rex_w then
|
|
lastdisassembledata.parameters:=colorreg+'rax'+endcolor+','
|
|
else
|
|
lastdisassembledata.parameters:=colorreg+'eax'+endcolor+',';
|
|
|
|
|
|
if processhandler.is64bit then
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+getsegmentoverride(prefix2)+'['+inttohexs(pqword(dwordptr)^,8)+']'
|
|
else
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+getsegmentoverride(prefix2)+'['+inttohexs(dwordptr^,8)+']';
|
|
|
|
end;
|
|
|
|
if processhandler.is64bit then
|
|
inc(offset, 8)
|
|
else
|
|
inc(offset, 4);
|
|
|
|
end;
|
|
|
|
$a2 : begin
|
|
description:='copy memory';
|
|
dwordptr:=@memory[1];
|
|
lastdisassembledata.opcode:='mov';
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
if processhandler.is64bit then
|
|
lastdisassembledata.parameters:=getsegmentoverride(prefix2)+'['+inttohexs(pqword(dwordptr)^,8)+'],'+colorreg+'al'+endcolor
|
|
else
|
|
lastdisassembledata.parameters:=getsegmentoverride(prefix2)+'['+inttohexs(dwordptr^,8)+'],'+colorreg+'al'+endcolor;
|
|
|
|
if processhandler.is64bit then
|
|
inc(offset, 8)
|
|
else
|
|
inc(offset, 4);
|
|
end;
|
|
|
|
$a3 : begin
|
|
description:='copy memory';
|
|
lastdisassembledata.opcode:='mov';
|
|
dwordptr:=@memory[1];
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
if processhandler.is64bit then
|
|
lastdisassembledata.parameters:=getsegmentoverride(prefix2)+'['+inttohexs(pqword(dwordptr)^,8)+'],'
|
|
else
|
|
lastdisassembledata.parameters:=getsegmentoverride(prefix2)+'['+inttohexs(dwordptr^,8)+'],';
|
|
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+colorreg+'ax'+endcolor
|
|
else
|
|
begin
|
|
if rex_w then
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+colorreg+'rax'+endcolor
|
|
else
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+colorreg+'eax'+endcolor;
|
|
end;
|
|
|
|
if processhandler.is64bit then
|
|
inc(offset, 8)
|
|
else
|
|
inc(offset, 4);
|
|
end;
|
|
|
|
$a4 : begin
|
|
description:='move data from string to string';
|
|
lastdisassembledata.opcode:='movsb';
|
|
end;
|
|
|
|
$a5 : begin
|
|
description:='move data from string to string';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.opcode:='movsw'
|
|
else
|
|
begin
|
|
if rex_w then
|
|
lastdisassembledata.opcode:='movsq'
|
|
else
|
|
lastdisassembledata.opcode:='movsd';
|
|
end;
|
|
end;
|
|
|
|
$a6 : begin
|
|
description:='compare string operands';
|
|
lastdisassembledata.opcode:='cmpsb';
|
|
end;
|
|
|
|
$a7 : begin
|
|
description:='compare string operands';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.opcode:='cmpsw'
|
|
else
|
|
begin
|
|
if rex_w then
|
|
lastdisassembledata.opcode:='cmpsq'
|
|
else
|
|
lastdisassembledata.opcode:='cmpsd';
|
|
end;
|
|
end;
|
|
|
|
$a8 : begin
|
|
description:='logical compare';
|
|
lastdisassembledata.opcode:='test';
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[1];
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.parameters:=colorreg+'al'+endcolor+','+inttohexs(memory[1],2);
|
|
inc(offset);
|
|
end;
|
|
|
|
$a9 : begin
|
|
description:='logical compare';
|
|
lastdisassembledata.opcode:='test';
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
if $66 in prefix2 then
|
|
begin
|
|
wordptr:=@memory[1];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
|
|
lastdisassembledata.parameters:=colorreg+'ax'+endcolor+','+inttohexs(wordptr^,4);
|
|
inc(offset,2);
|
|
end
|
|
else
|
|
begin
|
|
dwordptr:=@memory[1];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
|
|
if rex_w then
|
|
lastdisassembledata.parameters:=colorreg+'rax'+endcolor+','+inttohexs(longint(dwordptr^),8)
|
|
else
|
|
lastdisassembledata.parameters:=colorreg+'eax'+endcolor+','+inttohexs(dwordptr^,8);
|
|
inc(offset,4);
|
|
end;
|
|
end;
|
|
|
|
$aa : begin
|
|
description:='store string';
|
|
lastdisassembledata.opcode:='stosb';
|
|
end;
|
|
|
|
$ab : begin
|
|
description:='store string';
|
|
if $66 in prefix2 then lastdisassembledata.opcode:='stosw' else
|
|
begin
|
|
if rex_w then
|
|
lastdisassembledata.opcode:='stosq'
|
|
else
|
|
lastdisassembledata.opcode:='stosd';
|
|
end;
|
|
end;
|
|
|
|
$ac : begin
|
|
description:='load string';
|
|
lastdisassembledata.opcode:='lodsb';
|
|
end;
|
|
|
|
$ad : begin
|
|
description:='load string';
|
|
if $66 in prefix2 then lastdisassembledata.opcode:='lodsw' else
|
|
begin
|
|
if rex_w then
|
|
lastdisassembledata.opcode:='lodsq'
|
|
else
|
|
lastdisassembledata.opcode:='lodsd';
|
|
end;
|
|
end;
|
|
|
|
$ae : begin
|
|
description:='compare al with byte at es:edi and set status flag';
|
|
lastdisassembledata.opcode:='scasb';
|
|
end;
|
|
|
|
$af : begin
|
|
description:='scan string';
|
|
if $66 in prefix2 then lastdisassembledata.opcode:='scasw' else
|
|
begin
|
|
if rex_w then
|
|
lastdisassembledata.opcode:='scasq'
|
|
else
|
|
lastdisassembledata.opcode:='scasd';
|
|
end;
|
|
end;
|
|
|
|
$b0..$b7:
|
|
begin
|
|
description:='copy memory';
|
|
lastdisassembledata.opcode:='mov';
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[1];
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
// if Rex_B
|
|
|
|
lastdisassembledata.parameters:=rd8(memory[0]-$b0)+','+inttohexs(memory[1],2);
|
|
inc(offset);
|
|
end;
|
|
|
|
$b8..$bf:
|
|
begin
|
|
description:='copy memory';
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
if $66 in prefix2 then
|
|
begin
|
|
wordptr:=@memory[1];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
|
|
lastdisassembledata.opcode:='mov';
|
|
lastdisassembledata.parameters:=rd16(memory[0]-$b8)+','+inttohexs(wordptr^,4);
|
|
inc(offset,2);
|
|
end
|
|
else
|
|
begin
|
|
dwordptr:=@memory[1];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
|
|
|
|
if rex_w then
|
|
begin
|
|
lastdisassembledata.opcode:='mov';
|
|
lastdisassembledata.parametervalue:=pqword(dwordptr)^;
|
|
lastdisassembledata.parameters:=rd(memory[0]-$b8)+','+inttohexs(pqword(dwordptr)^,16);
|
|
inc(offset,8);
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='mov';
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
|
|
lastdisassembledata.parameters:=rd(memory[0]-$b8)+','+inttohexs(dwordptr^,8);
|
|
inc(offset,4);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$c0 : begin
|
|
case getreg(memory[1]) of
|
|
0: begin
|
|
lastdisassembledata.opcode:='rol';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
description:='rotate eight bits left '+inttostr(memory[last])+' times';
|
|
inc(offset,last);
|
|
end;
|
|
|
|
1: begin
|
|
lastdisassembledata.opcode:='ror';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
description:='rotate eight bits right '+inttostr(memory[last])+' times';
|
|
inc(offset,last);
|
|
end;
|
|
|
|
2: begin
|
|
lastdisassembledata.opcode:='rcl';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
description:='rotate nine bits left '+inttostr(memory[last])+' times';
|
|
inc(offset,last);
|
|
end;
|
|
|
|
3: begin
|
|
lastdisassembledata.opcode:='rcr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
description:='rotate nine bits right '+inttostr(memory[last])+' times';
|
|
inc(offset,last);
|
|
end;
|
|
|
|
4: begin
|
|
lastdisassembledata.opcode:='shl';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
description:='multiply by 2, '+inttostr(memory[last])+' times';
|
|
inc(offset,last);
|
|
end;
|
|
|
|
5: begin
|
|
lastdisassembledata.opcode:='shr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
description:='unsigned divide by 2, '+inttostr(memory[last])+' times';
|
|
inc(offset,last);
|
|
end;
|
|
|
|
{not in intel spec}
|
|
6: begin
|
|
lastdisassembledata.opcode:='rol';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
description:='rotate eight bits left '+inttostr(memory[last])+' times';
|
|
inc(offset,last);
|
|
end;
|
|
{^^^^^^^^^^^^^^^^^^}
|
|
|
|
7: begin
|
|
lastdisassembledata.opcode:='sar';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
description:='signed divide by 2, '+inttostr(memory[last])+' times';
|
|
inc(offset,last);
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
|
|
$c1 : begin
|
|
case getreg(memory[1]) of
|
|
0: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='rol';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
description:='rotate 16 bits left '+inttostr(memory[last])+' times';
|
|
inc(offset,last);
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='rol';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
description:='rotate 32 bits left '+inttostr(memory[last])+' times';
|
|
inc(offset,last);
|
|
end;
|
|
end;
|
|
|
|
1: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='ror';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
description:='rotate 16 bits right '+inttostr(memory[last])+' times';
|
|
inc(offset,last);
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='ror';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
description:='rotate 32 bits right '+inttostr(memory[last])+' times';
|
|
inc(offset,last);
|
|
end;
|
|
end;
|
|
|
|
2: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='rcl';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
description:='rotate 17 bits left '+inttostr(memory[last])+' times';
|
|
inc(offset,last);
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='rcl';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
description:='rotate 33 bits left '+inttostr(memory[last])+' times';
|
|
inc(offset,last);
|
|
end;
|
|
end;
|
|
|
|
3: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='rcr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
description:='rotate 17 bits right '+inttostr(memory[last])+' times';
|
|
inc(offset,last);
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='rcr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
description:='rotate 33 bits right '+inttostr(memory[last])+' times';
|
|
inc(offset,last);
|
|
end;
|
|
end;
|
|
|
|
4: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='shl';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
description:='multiply by 2 '+inttostr(memory[last])+' times';
|
|
inc(offset,last);
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='shl';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
description:='multiply by 2 '+inttostr(memory[last])+' times';
|
|
inc(offset,last);
|
|
end;
|
|
end;
|
|
|
|
5: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='shr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
description:='unsigned divide by 2 '+inttostr(memory[last])+' times';
|
|
inc(offset,last);
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='shr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
description:='unsigned divide by 2 '+inttostr(memory[last])+' times';
|
|
inc(offset,last);
|
|
end;
|
|
end;
|
|
|
|
{not in intel spec}
|
|
6: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='sal';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
description:='signed multiply by 2 '+inttostr(memory[last])+' times';
|
|
inc(offset,last);
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='sal';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
description:='signed multiply by 2 '+inttostr(memory[last])+' times';
|
|
inc(offset,last);
|
|
end;
|
|
end;
|
|
{^^^^^^^^^^^^^^^^^^}
|
|
7: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='sar';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
description:='signed divide by 2 '+inttostr(memory[last])+' times';
|
|
inc(offset,last);
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='sar';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
description:='signed divide by 2 '+inttostr(memory[last])+' times';
|
|
inc(offset,last);
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
|
|
$c2 : begin
|
|
|
|
wordptr:=@memory[1];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.opcode:='ret';
|
|
LastDisassembleData.isret:=true;
|
|
lastdisassembledata.parameters:=inttohexs(wordptr^,4);
|
|
inc(offset,2);
|
|
|
|
description:='near return to calling procedure and pop '+inttostr(lastdisassembledata.parametervalue)+' bytes from stack';
|
|
|
|
|
|
end;
|
|
|
|
$c3 : begin
|
|
description:='near return to calling procedure';
|
|
lastdisassembledata.opcode:='ret';
|
|
LastDisassembleData.isret:=true;
|
|
end;
|
|
|
|
$c4 : begin
|
|
if processhandler.is64Bit=false then
|
|
begin
|
|
description:='load far pointer';
|
|
lastdisassembledata.opcode:='les';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[1])+modrm(memory,prefix2,1,1,last,mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[1])+modrm(memory,prefix2,1,0,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$c5 : begin
|
|
if processhandler.is64Bit=false then
|
|
begin
|
|
description:='load far pointer';
|
|
lastdisassembledata.opcode:='lds';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=r16(memory[1])+modrm(memory,prefix2,1,1,last,mRight) else
|
|
lastdisassembledata.parameters:=r32(memory[1])+modrm(memory,prefix2,1,0,last,mRight);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
$c6 : begin
|
|
if memory[1]=$f8 then
|
|
begin
|
|
inc(offset);
|
|
lastdisassembledata.opcode:='xabort';
|
|
description:='transactional abort';
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[2];
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
lastdisassembledata.parameters:=inttohexs(memory[2],2);
|
|
|
|
end
|
|
else
|
|
case getreg(memory[1]) of
|
|
0 : begin
|
|
description:='copy memory';
|
|
lastdisassembledata.opcode:='mov';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
inc(offset,last);
|
|
end;
|
|
|
|
else begin
|
|
description:='not defined by the intel documentation';
|
|
lastdisassembledata.opcode:='db';
|
|
lastdisassembledata.parameters:=inttohexs(memory[0],2);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$c7 : begin
|
|
if memory[1]=$f8 then
|
|
begin
|
|
description:='Transactional Begin';
|
|
lastdisassembledata.opcode:='xbegin';
|
|
|
|
if MarkIPRelativeInstructions then
|
|
begin
|
|
LastDisassembleData.riprelative:=1;
|
|
riprelative:=true;
|
|
end;
|
|
inc(offset,4);
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
|
|
|
|
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+pinteger(@memory[2])^)
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+pinteger(@memory[2])^);
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
end
|
|
else
|
|
case getreg(memory[1]) of
|
|
0 : begin
|
|
description:='copy memory';
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='mov';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
|
|
wordptr:=@memory[last];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(wordptr^,4);
|
|
inc(offset,last+1);
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='mov';
|
|
|
|
if Rex_W then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64)
|
|
else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
dwordptr:=@memory[last];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
|
|
|
|
if rex_w then
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+IntToHexs(longint(dwordptr^),8)
|
|
else
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+IntToHexs(dwordptr^,8);
|
|
|
|
inc(offset,last+3);
|
|
end;
|
|
end;
|
|
|
|
else begin
|
|
description:='not defined by the intel documentation';
|
|
lastdisassembledata.opcode:='db';
|
|
lastdisassembledata.parameters:=inttohexs(memory[0],2);
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
|
|
$c8 : begin
|
|
description:='make stack frame for procedure parameters';
|
|
wordptr:=@memory[1];
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=3;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
lastdisassembledata.opcode:='enter';
|
|
lastdisassembledata.parameters:=inttohexs(wordptr^,4)+','+inttohexs(memory[3],2);
|
|
inc(offset,3);
|
|
end;
|
|
|
|
$c9 : begin
|
|
description:='high level procedure exit';
|
|
lastdisassembledata.opcode:='leave';
|
|
end;
|
|
|
|
$ca : begin
|
|
description:='far return to calling procedure and pop 2 bytes from stack';
|
|
wordptr:=@memory[1];
|
|
lastdisassembledata.opcode:='ret';
|
|
LastDisassembleData.isret:=true;
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.parameters:=inttohexs(wordptr^,4);
|
|
inc(offset,2);
|
|
end;
|
|
|
|
$cb : begin
|
|
description:='far return to calling procedure';
|
|
lastdisassembledata.opcode:='ret';
|
|
LastDisassembleData.isret:=true;
|
|
end;
|
|
|
|
$cc : begin
|
|
//should not be shown if its being debugged using int 3'
|
|
description:='call to interrupt procedure-3:trap to debugger';
|
|
lastdisassembledata.opcode:='int 3';
|
|
|
|
{$ifdef onebytejumps}
|
|
if AutoAssemblerExceptionHandlerHasEntries then
|
|
begin
|
|
if IsAutoAssemblerExceptionRIPChanger(LastDisassembleData.address, tempaddress) then
|
|
begin
|
|
lastdisassembledata.opcode:='jmp1';
|
|
LastDisassembleData.parameters:=inttohexs(tempaddress,8);
|
|
end;
|
|
end;
|
|
{$endif}
|
|
|
|
|
|
end;
|
|
|
|
$cd : begin
|
|
description:='call to interrupt procedure';
|
|
lastdisassembledata.opcode:='int';
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[1];
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.parameters:=inttohexs(memory[1],2);
|
|
inc(offset);
|
|
end;
|
|
|
|
$ce : begin
|
|
description:='call to interrupt procedure-4:if overflow flag=1';
|
|
lastdisassembledata.opcode:='into';
|
|
end;
|
|
|
|
$cf : begin
|
|
description:='interrupt return';
|
|
if $66 in prefix2 then lastdisassembledata.opcode:='iret' else
|
|
begin
|
|
if rex_w then
|
|
lastdisassembledata.opcode:='iretq'
|
|
else
|
|
lastdisassembledata.opcode:='iretd';
|
|
end;
|
|
end;
|
|
|
|
$d0 : begin
|
|
case getreg(memory[1]) of
|
|
0: begin
|
|
description:='rotate eight bits left once';
|
|
lastdisassembledata.opcode:='rol';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8)+'1';
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
1: begin
|
|
description:='rotate eight bits right once';
|
|
lastdisassembledata.opcode:='ror';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8)+'1';
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
|
|
2: begin
|
|
description:='rotate nine bits left once';
|
|
lastdisassembledata.opcode:='rcl';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8)+'1';
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
3: begin
|
|
description:='rotate nine bits right once';
|
|
lastdisassembledata.opcode:='rcr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8)+'1';
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
4: begin
|
|
description:='multiply by 2, once';
|
|
lastdisassembledata.opcode:='shl';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8)+'1';
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
5: begin
|
|
description:='unsigned divide by 2, once';
|
|
lastdisassembledata.opcode:='shr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8)+'1';
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
6: begin
|
|
{undefined by intel}
|
|
description:='signed multiply by 2, once';
|
|
lastdisassembledata.opcode:='sal';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8)+'1';
|
|
inc(offset,last-1);
|
|
{^^^^^^^^^^^^^^^^^}
|
|
end;
|
|
|
|
7: begin
|
|
description:='signed divide by 2, once';
|
|
lastdisassembledata.opcode:='sar';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8)+'1';
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
|
|
$d1 : begin
|
|
case getreg(memory[1]) of
|
|
0: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='rotate 16 bits left once';
|
|
lastdisassembledata.opcode:='rol';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16)+'1';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='rotate 32 bits left once';
|
|
lastdisassembledata.opcode:='rol';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last, ifthen(rex_w,64,0) )+'1';
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
1: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='rotate 16 bits right once';
|
|
lastdisassembledata.opcode:='ror';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16)+'1';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='rotate 32 bits right once';
|
|
lastdisassembledata.opcode:='ror';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last, ifthen(rex_w,64,0))+'1';
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
2: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='rotate 17 bits left once';
|
|
lastdisassembledata.opcode:='rcl';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16)+'1';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='rotate 33 bits left once';
|
|
lastdisassembledata.opcode:='rcl';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last, ifthen(rex_w,64,0))+'1';
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
3: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='rotate 17 bits right once';
|
|
lastdisassembledata.opcode:='rcr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16)+'1';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='rotate 33 bits right once';
|
|
lastdisassembledata.opcode:='rcr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last, ifthen(rex_w,64,0))+'1';
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
4: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='multiply by 2, once';
|
|
lastdisassembledata.opcode:='shl';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16)+'1';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='multiply by 2, once';
|
|
lastdisassembledata.opcode:='shl';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last, ifthen(rex_w,64,0))+'1';
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
5: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='unsigned divide by 2, once';
|
|
lastdisassembledata.opcode:='shr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16)+'1';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='unsigned divide by 2, once';
|
|
lastdisassembledata.opcode:='shr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last, ifthen(rex_w,64,0))+'1';
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
6: begin
|
|
{undefined by intel}
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='signed multiply by 2, once';
|
|
lastdisassembledata.opcode:='sal';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16)+'1';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='signed multiply by 2, once';
|
|
lastdisassembledata.opcode:='sal';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last, ifthen(rex_w,64,0))+'1';
|
|
inc(offset,last-1);
|
|
end;
|
|
{^^^^^^^^^^^^^^^^^}
|
|
end;
|
|
|
|
7: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='signed divide by 2, once';
|
|
lastdisassembledata.opcode:='sar';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16)+'1';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='signed divide by 2, once';
|
|
lastdisassembledata.opcode:='sar';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last, ifthen(rex_w,64,0))+'1';
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
|
|
|
|
$d2 : begin
|
|
case getreg(memory[1]) of
|
|
0: begin
|
|
description:='rotate eight bits left cl times';
|
|
lastdisassembledata.opcode:='rol';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8)+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
1: begin
|
|
description:='rotate eight bits right cl times';
|
|
lastdisassembledata.opcode:='ror';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8)+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
2: begin
|
|
description:='rotate nine bits left cl times';
|
|
lastdisassembledata.opcode:='rcl';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8)+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
3: begin
|
|
description:='rotate nine bits right cl times';
|
|
lastdisassembledata.opcode:='rcr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8)+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
4: begin
|
|
description:='multiply by 2, cl times';
|
|
lastdisassembledata.opcode:='shl';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8)+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
5: begin
|
|
description:='unsigned divide by 2, cl times';
|
|
lastdisassembledata.opcode:='shr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8)+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
6: begin
|
|
description:='multiply by 2, cl times';
|
|
lastdisassembledata.opcode:='shl';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8)+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
7: begin
|
|
description:='signed divide by 2, cl times';
|
|
lastdisassembledata.opcode:='sar';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8)+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
|
|
end;
|
|
end;
|
|
|
|
$d3 : begin
|
|
case getreg(memory[1]) of
|
|
0: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='rotate 16 bits left cl times';
|
|
lastdisassembledata.opcode:='rol';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16)+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='rotate 32 bits left cl times';
|
|
lastdisassembledata.opcode:='rol';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last)+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
1: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='rotate 16 bits right cl times';
|
|
lastdisassembledata.opcode:='ror';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16)+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='rotate 32 bits right cl times';
|
|
lastdisassembledata.opcode:='ror';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last)+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
2: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='rotate 17 bits left cl times';
|
|
lastdisassembledata.opcode:='rcl';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16)+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='rotate 33 bits left cl times';
|
|
lastdisassembledata.opcode:='rcl';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last)+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
3: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='rotate 17 bits right cl times';
|
|
lastdisassembledata.opcode:='rcr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16)+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='rotate 33 bits right cl times';
|
|
lastdisassembledata.opcode:='rcr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last)+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
4: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='multiply by 2, cl times';
|
|
lastdisassembledata.opcode:='shl';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16)+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='multiply by 2, cl times';
|
|
lastdisassembledata.opcode:='shl';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last)+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
5: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='unsigned divide by 2, cl times';
|
|
lastdisassembledata.opcode:='shr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16)+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='unsigned divide by 2, cl times';
|
|
lastdisassembledata.opcode:='shr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last)+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
6: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='signed multiply by 2, cl times';
|
|
lastdisassembledata.opcode:='sal';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16)+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='signed multiply by 2, cl times';
|
|
lastdisassembledata.opcode:='sal';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last)+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
7: begin
|
|
if $66 in prefix2 then
|
|
begin
|
|
description:='signed divide by 2, cl times';
|
|
lastdisassembledata.opcode:='sar';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16)+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='signed divide by 2, cl times';
|
|
lastdisassembledata.opcode:='sar';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last)+colorreg+'cl'+endcolor;
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
|
|
|
|
$d4 : begin // aam
|
|
inc(offset);
|
|
lastdisassembledata.opcode:='aam';
|
|
description:='ascii adjust ax after multiply';
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[1];
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
if memory[1]<>$0a then
|
|
lastdisassembledata.parameters:=inttohexs(memory[1],2);
|
|
end;
|
|
|
|
$d5 : begin // aad
|
|
inc(offset);
|
|
lastdisassembledata.opcode:='aad';
|
|
description:='ascii adjust ax before division';
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[1];
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
if memory[1]<>$0a then lastdisassembledata.parameters:=inttohexs(memory[1],2);
|
|
end;
|
|
|
|
$d7 : begin
|
|
description:='table look-up translation';
|
|
lastdisassembledata.opcode:='xlatb';
|
|
end;
|
|
|
|
$d8 : begin
|
|
case getreg(memory[1]) of
|
|
0: begin
|
|
//fadd
|
|
description:='add';
|
|
lastdisassembledata.opcode:='fadd';
|
|
last:=2;
|
|
if memory[1]>=$c0 then
|
|
lastdisassembledata.parameters:='st(0),st('+inttostr(memory[1]-$c0)+')' else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
1: begin
|
|
description:='multiply';
|
|
last:=2;
|
|
if memory[1]>=$c8 then
|
|
begin
|
|
lastdisassembledata.opcode:='fmul';
|
|
lastdisassembledata.parameters:='st(0),st('+inttostr(memory[1]-$c8)+')';
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='fmul';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
|
|
end;
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
|
|
2: begin
|
|
description:='compare real';
|
|
last:=2;
|
|
if memory[1]>=$d0 then
|
|
begin
|
|
lastdisassembledata.opcode:='fcom';
|
|
lastdisassembledata.parameters:='st(0),st('+inttostr(memory[1]-$d0)+')'
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='fcom';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
|
|
end;
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
3: begin
|
|
description:='compare real and pop register stack';
|
|
last:=2;
|
|
if memory[1]>=$d8 then
|
|
begin
|
|
lastdisassembledata.opcode:='fcomp';
|
|
lastdisassembledata.parameters:='st(0),st('+inttostr(memory[1]-$d8)+')'
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='fcomp';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
|
|
end;
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
4: begin
|
|
description:='substract';
|
|
last:=2;
|
|
if memory[1]>=$e0 then
|
|
begin
|
|
lastdisassembledata.opcode:='fsub';
|
|
lastdisassembledata.parameters:='st(0),st('+inttostr(memory[1]-$e0)+')';
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='fsub';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
|
|
end;
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
5: begin
|
|
description:='reverse substract';
|
|
last:=2;
|
|
if (memory[1]>=$e8) then
|
|
begin
|
|
lastdisassembledata.opcode:='fsubr';
|
|
lastdisassembledata.parameters:='st(0),st('+inttostr(memory[1]-$e8)+')';
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='fsubr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
|
|
end;
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
6: begin
|
|
description:='divide';
|
|
last:=2;
|
|
if memory[1]>=$f0 then
|
|
begin
|
|
lastdisassembledata.opcode:='fdiv';
|
|
lastdisassembledata.parameters:='st(0),st('+inttostr(memory[1]-$f0)+')';
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='fdiv';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
|
|
end;
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
7: begin
|
|
description:='reverse divide';
|
|
last:=2;
|
|
if memory[1]>=$f8 then
|
|
begin
|
|
lastdisassembledata.opcode:='fdivr';
|
|
lastdisassembledata.parameters:='st(0),st('+inttostr(memory[1]-$f8)+')';
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='fdivr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
|
|
end;
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
|
|
$d9 : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
case memory[1] of
|
|
$00..$bf : begin
|
|
|
|
case getreg(memory[1]) of
|
|
0: begin
|
|
description:='load floating point value';
|
|
lastdisassembledata.opcode:='fld';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
2: begin
|
|
description:='store single';
|
|
lastdisassembledata.opcode:='fst';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
3: begin
|
|
description:='store single';
|
|
lastdisassembledata.opcode:='fstp';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
4: begin
|
|
description:='load fpu environment';
|
|
lastdisassembledata.opcode:='fldenv';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
5: begin
|
|
description:='load control word';
|
|
lastdisassembledata.opcode:='fldcw';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
6: begin
|
|
description:='store fpu environment';
|
|
lastdisassembledata.opcode:='fnstenv';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
7: begin
|
|
description:='store control word';
|
|
lastdisassembledata.opcode:='fnstcw';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
|
|
end;
|
|
end;
|
|
|
|
$c0..$c7 : begin
|
|
description:='push st(i) onto the fpu register stack';
|
|
lastdisassembledata.opcode:='fld';
|
|
lastdisassembledata.parameters:='st('+inttostr(memory[1]-$c0)+')';
|
|
inc(offset);
|
|
end;
|
|
|
|
$c8..$cf : begin
|
|
description:='exchange register contents';
|
|
lastdisassembledata.opcode:='fxch';
|
|
lastdisassembledata.parameters:='st('+inttostr(memory[1]-$c8)+')';
|
|
inc(offset);
|
|
end;
|
|
|
|
|
|
$d9..$df : begin
|
|
description:='exchange register contents';
|
|
lastdisassembledata.opcode:='fxch';
|
|
lastdisassembledata.parameters:='st('+inttostr(memory[1]-$d9)+')';
|
|
inc(offset);
|
|
end;
|
|
|
|
|
|
$d0 : begin
|
|
description:='no operation';
|
|
lastdisassembledata.opcode:='fnop';
|
|
inc(offset);
|
|
end;
|
|
|
|
$e0 : begin
|
|
description:='change sign';
|
|
lastdisassembledata.opcode:='fchs';
|
|
inc(offset);
|
|
end;
|
|
|
|
$e1 : begin
|
|
description:='absolute value';
|
|
lastdisassembledata.opcode:='fabs';
|
|
inc(offset);
|
|
end;
|
|
|
|
$e4 : begin
|
|
description:='test';
|
|
lastdisassembledata.opcode:='ftst';
|
|
inc(offset);
|
|
end;
|
|
|
|
$e5 : begin
|
|
description:='examine';
|
|
lastdisassembledata.opcode:='fxam';
|
|
inc(offset);
|
|
end;
|
|
|
|
|
|
|
|
$e8 : begin
|
|
description:='Push +1.0 onto the FPU register stack';
|
|
lastdisassembledata.opcode:='fld1';
|
|
inc(offset);
|
|
end;
|
|
|
|
$e9 : begin
|
|
description:='Push log2(10) onto the FPU register stack';
|
|
lastdisassembledata.opcode:='fldl2t';
|
|
inc(offset);
|
|
end;
|
|
|
|
$ea : begin
|
|
description:='Push log2(e) onto the FPU register stack';
|
|
lastdisassembledata.opcode:='fldl2e';
|
|
inc(offset);
|
|
end;
|
|
|
|
$eb : begin
|
|
description:='Push "pi" onto the FPU register stackload constant';
|
|
lastdisassembledata.opcode:='fldpi';
|
|
inc(offset);
|
|
end;
|
|
|
|
$ec : begin
|
|
description:='Push log10(2) onto the FPU register stack';
|
|
lastdisassembledata.opcode:='fldlg2';
|
|
inc(offset);
|
|
end;
|
|
|
|
$ed : begin
|
|
description:='Push log e(2) onto the FPU register stack';
|
|
lastdisassembledata.opcode:='fldln2';
|
|
inc(offset);
|
|
end;
|
|
|
|
$ee : begin
|
|
description:='Push +0.0 onto the FPU register stack';
|
|
lastdisassembledata.opcode:='fldz';
|
|
inc(offset);
|
|
end;
|
|
|
|
|
|
$f0 : begin
|
|
description:='compute 2^x-1';
|
|
lastdisassembledata.opcode:='f2xm1';
|
|
inc(offset);
|
|
end;
|
|
|
|
$f1 : begin
|
|
description:='compute y*log(2)x';
|
|
lastdisassembledata.opcode:='fyl2x';
|
|
inc(offset);
|
|
end;
|
|
|
|
$f2 : begin
|
|
description:='partial tangent';
|
|
lastdisassembledata.opcode:='fptan';
|
|
inc(offset);
|
|
end;
|
|
|
|
$f3 : begin
|
|
description:='partial arctangent';
|
|
lastdisassembledata.opcode:='fpatan';
|
|
inc(offset);
|
|
end;
|
|
|
|
$f4 : begin
|
|
description:='extract exponent and significand';
|
|
lastdisassembledata.opcode:='fxtract';
|
|
inc(offset);
|
|
end;
|
|
|
|
$f5 : begin
|
|
description:='partial remainder';
|
|
lastdisassembledata.opcode:='fprem1';
|
|
inc(offset);
|
|
end;
|
|
|
|
$f6 : begin
|
|
description:='decrement stack-top pointer';
|
|
lastdisassembledata.opcode:='fdecstp';
|
|
inc(offset);
|
|
end;
|
|
|
|
$f7 : begin
|
|
description:='increment stack-top pointer';
|
|
lastdisassembledata.opcode:='fincstp';
|
|
inc(offset);
|
|
end;
|
|
|
|
$f8 : begin
|
|
description:='partial remainder';
|
|
lastdisassembledata.opcode:='fprem';
|
|
inc(offset);
|
|
end;
|
|
|
|
$f9 : begin
|
|
description:='compute y*log(2)(x+1)';
|
|
lastdisassembledata.opcode:='fyl2xp1';
|
|
inc(offset);
|
|
end;
|
|
|
|
$fa : begin
|
|
description:='square root';
|
|
lastdisassembledata.opcode:='fsqrt';
|
|
inc(offset);
|
|
end;
|
|
|
|
$fb : begin
|
|
description:='sine and cosine';
|
|
lastdisassembledata.opcode:='fsincos';
|
|
inc(offset);
|
|
end;
|
|
|
|
|
|
$fc : begin
|
|
description:='round to integer';
|
|
lastdisassembledata.opcode:='frndint';
|
|
inc(offset);
|
|
end;
|
|
|
|
$fd : begin
|
|
description:='scale';
|
|
lastdisassembledata.opcode:='fscale';
|
|
inc(offset);
|
|
end;
|
|
|
|
$fe : begin
|
|
description:='sine';
|
|
lastdisassembledata.opcode:='fsin';
|
|
inc(offset);
|
|
end;
|
|
|
|
$ff : begin
|
|
description:='cosine';
|
|
lastdisassembledata.opcode:='fcos';
|
|
inc(offset);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$da : begin
|
|
if memory[1]<$bf then
|
|
begin
|
|
case getreg(memory[1]) of
|
|
0: begin
|
|
description:='add';
|
|
lastdisassembledata.opcode:='fiadd';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
1: begin
|
|
description:='multiply';
|
|
lastdisassembledata.opcode:='fimul';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
2: begin
|
|
description:='compare integer';
|
|
lastdisassembledata.opcode:='ficom';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
3: begin
|
|
description:='compare integer';
|
|
lastdisassembledata.opcode:='ficomp';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
4: begin
|
|
description:='subtract';
|
|
lastdisassembledata.opcode:='fisub';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
5: begin
|
|
description:='reverse subtract';
|
|
lastdisassembledata.opcode:='fisubr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
|
|
6: begin
|
|
description:='divide';
|
|
lastdisassembledata.opcode:='fidiv';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
7: begin
|
|
description:='reverse divide';
|
|
lastdisassembledata.opcode:='fidivr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
case getreg(memory[1]) of
|
|
0: begin
|
|
description:='floating-point: move if below';
|
|
lastdisassembledata.opcode:='fcmovb';
|
|
lastdisassembledata.parameters:='st(0),st('+inttostr(memory[1]-$c0)+')';
|
|
inc(offset);
|
|
end;
|
|
|
|
1: begin
|
|
description:='floating-point: move if equal';
|
|
lastdisassembledata.opcode:='fcmove';
|
|
lastdisassembledata.parameters:='st(0),st('+inttostr(memory[1]-$c8)+')';
|
|
inc(offset);
|
|
end;
|
|
|
|
2: begin
|
|
description:='floating-point: move if below or equal';
|
|
lastdisassembledata.opcode:='fcmovbe';
|
|
lastdisassembledata.parameters:='st(0),st('+inttostr(memory[1]-$d0)+')';
|
|
inc(offset);
|
|
end;
|
|
|
|
3: begin
|
|
description:='floating-point: move if unordered';
|
|
lastdisassembledata.opcode:='fcmovu';
|
|
lastdisassembledata.parameters:='st(0),st('+inttostr(memory[1]-$d8)+')';
|
|
inc(offset);
|
|
end;
|
|
|
|
5: begin
|
|
case memory[1] of
|
|
$e9 : begin
|
|
description:='unordered compare real';
|
|
lastdisassembledata.opcode:='fucompp';
|
|
inc(offset);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$db : begin
|
|
case memory[1] of
|
|
$0..$bf : begin
|
|
case getreg(memory[1]) of
|
|
0: begin
|
|
description:='load integer';
|
|
lastdisassembledata.opcode:='fild';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
1: begin
|
|
description:='store integer with truncation';
|
|
lastdisassembledata.opcode:='fisttp';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
2: begin
|
|
description:='store integer';
|
|
lastdisassembledata.opcode:='fist';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
3: begin
|
|
description:='store integer';
|
|
lastdisassembledata.opcode:='fistp';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
5: begin
|
|
lastdisassembledata.isfloat:=true;
|
|
description:='load floating point value';
|
|
lastdisassembledata.opcode:='fld';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,80);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
7: begin
|
|
lastdisassembledata.isfloat:=true;
|
|
description:='store extended';
|
|
lastdisassembledata.opcode:='fstp';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,80);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
|
|
$c0..$c7 : begin
|
|
description:='floating-point: move if not below';
|
|
lastdisassembledata.opcode:='fcmovnb';
|
|
lastdisassembledata.parameters:='st(0),st('+inttostr(memory[1]-$c0)+')';
|
|
inc(offset);
|
|
end;
|
|
|
|
$c8..$cf : begin
|
|
description:='floating-point: move if not equal';
|
|
lastdisassembledata.opcode:='fcmovne';
|
|
lastdisassembledata.parameters:='st(0),st('+inttostr(memory[1]-$c8)+')';
|
|
inc(offset);
|
|
end;
|
|
|
|
$d0..$d7 : begin
|
|
description:='floating-point: move if not below or equal';
|
|
lastdisassembledata.opcode:='fcmovnbe';
|
|
lastdisassembledata.parameters:='st(0),st('+inttostr(memory[1]-$d0)+')';
|
|
inc(offset);
|
|
end;
|
|
|
|
$d8..$df : begin
|
|
description:='floating-point: move if not unordered';
|
|
lastdisassembledata.opcode:='fcmovnu';
|
|
lastdisassembledata.parameters:='st(0),st('+inttostr(memory[1]-$d8)+')';
|
|
inc(offset);
|
|
end;
|
|
|
|
$e2 : begin
|
|
description:='clear exceptions';
|
|
lastdisassembledata.opcode:='fnclex';
|
|
inc(offset);
|
|
end;
|
|
|
|
$e3 : begin
|
|
description:='initialize floating-point unit';
|
|
lastdisassembledata.opcode:='fninit';
|
|
inc(offset);
|
|
end;
|
|
|
|
$e8..$ef : begin
|
|
description:='floating-point: compare real and set eflags';
|
|
lastdisassembledata.opcode:='fucomi';
|
|
lastdisassembledata.parameters:='st(0),st('+inttostr(memory[1]-$e8)+')';
|
|
inc(offset);
|
|
end;
|
|
|
|
$f0..$f7 : begin
|
|
description:='floating-point: compare real and set eflags';
|
|
lastdisassembledata.opcode:='fcomi';
|
|
lastdisassembledata.parameters:='st(0),st('+inttostr(memory[1]-$f0)+')';
|
|
inc(offset);
|
|
end;
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
$dc : begin
|
|
lastdisassembledata.isfloat:=true;
|
|
case getreg(memory[1]) of
|
|
0: begin
|
|
//fadd
|
|
description:='add';
|
|
last:=2;
|
|
if memory[1]>=$c0 then
|
|
begin
|
|
lastdisassembledata.opcode:='fadd';
|
|
lastdisassembledata.parameters:='st('+inttostr(memory[1]-$c0)+'),st(0)'
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='fadd';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
|
|
end;
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
1: begin
|
|
description:='multiply';
|
|
last:=2;
|
|
if memory[1]>=$c8 then
|
|
begin
|
|
lastdisassembledata.opcode:='fmul';
|
|
lastdisassembledata.parameters:='st('+inttostr(memory[1]-$c8)+'),st(0)';
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='fmul';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
|
|
end;
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
2: begin
|
|
description:='compare real';
|
|
last:=2;
|
|
lastdisassembledata.opcode:='fcom';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
3: begin
|
|
description:='compare real';
|
|
last:=2;
|
|
lastdisassembledata.opcode:='fcomp';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
4: begin
|
|
description:='subtract';
|
|
last:=2;
|
|
if memory[1]>=$e0 then
|
|
begin
|
|
lastdisassembledata.opcode:='fsubr';
|
|
lastdisassembledata.parameters:='st('+inttostr(memory[1]-$e0)+'),st(0)';
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='fsub';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
|
|
end;
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
5: begin
|
|
description:='reverse subtract';
|
|
last:=2;
|
|
if memory[1]>=$e8 then
|
|
begin
|
|
lastdisassembledata.opcode:='fsub';
|
|
lastdisassembledata.parameters:='st('+inttostr(memory[1]-$e8)+'),st(0)';
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='fsubr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
|
|
end;
|
|
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
|
|
6: begin
|
|
description:='divide';
|
|
last:=2;
|
|
if memory[1]>=$f0 then
|
|
begin
|
|
lastdisassembledata.opcode:='fdivr';
|
|
lastdisassembledata.parameters:='st('+inttostr(memory[1]-$f0)+'),st(0)';
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='fdiv';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
|
|
end;
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
7: begin
|
|
description:='reverse divide';
|
|
last:=2;
|
|
if memory[1]>=$f8 then
|
|
begin
|
|
lastdisassembledata.opcode:='fdiv';
|
|
lastdisassembledata.parameters:='st('+inttostr(memory[1]-$f8)+'),st(0)';
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='fdivr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
|
|
end;
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$dd : begin
|
|
case memory[1] of
|
|
$0..$bf : begin
|
|
case getreg(memory[1]) of
|
|
0: begin
|
|
lastdisassembledata.isfloat:=true;
|
|
description:='load floating point value';
|
|
lastdisassembledata.opcode:='fld';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
1: begin
|
|
description:='store integer with truncation';
|
|
lastdisassembledata.opcode:='fisttp';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
2: begin
|
|
lastdisassembledata.isfloat:=true;
|
|
description:='store double';
|
|
lastdisassembledata.opcode:='fst';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
3: begin
|
|
lastdisassembledata.isfloat:=true;
|
|
description:='store double';
|
|
lastdisassembledata.opcode:='fstp';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
4: begin
|
|
description:='restore fpu state';
|
|
lastdisassembledata.opcode:='frstor';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
6: begin
|
|
description:='store fpu state';
|
|
lastdisassembledata.opcode:='fnsave';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
7: begin
|
|
description:='store status word';
|
|
lastdisassembledata.opcode:='fnstsw';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
$c0..$c7 : begin
|
|
description:='free floating-point register';
|
|
lastdisassembledata.opcode:='ffree';
|
|
lastdisassembledata.parameters:='st('+inttostr(memory[1]-$c0)+')';
|
|
inc(offset);
|
|
end;
|
|
|
|
$d0..$d7 : begin
|
|
description:='store real';
|
|
lastdisassembledata.opcode:='fst';
|
|
lastdisassembledata.parameters:='st('+inttostr(memory[1]-$d0)+')';
|
|
inc(offset);
|
|
end;
|
|
|
|
$d8..$df : begin
|
|
description:='store real';
|
|
lastdisassembledata.opcode:='fstp';
|
|
lastdisassembledata.parameters:='st('+inttostr(memory[1]-$d8)+')';
|
|
inc(offset);
|
|
end;
|
|
|
|
$e0..$e7 : begin
|
|
description:='unordered compare real';
|
|
lastdisassembledata.opcode:='fucom';
|
|
lastdisassembledata.parameters:='st('+inttostr(memory[1]-$e0)+')';
|
|
inc(offset);
|
|
end;
|
|
|
|
$e8..$ef : begin
|
|
description:='unordered compare real';
|
|
lastdisassembledata.opcode:='fucomp';
|
|
lastdisassembledata.parameters:='st('+inttostr(memory[1]-$e8)+')';
|
|
inc(offset);
|
|
end;
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='db';
|
|
lastdisassembledata.parameters:=inttohexs(memory[0],2);
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
|
|
$de : begin
|
|
case getreg(memory[1]) of
|
|
0: begin
|
|
//faddp
|
|
description:='add and pop';
|
|
last:=2;
|
|
if (memory[1]=$c1) then lastdisassembledata.opcode:='faddp'
|
|
else
|
|
if memory[1]>=$c0 then
|
|
begin
|
|
lastdisassembledata.opcode:='faddp';
|
|
lastdisassembledata.parameters:='st('+inttostr(memory[1]-$c0)+'),st(0)';
|
|
end
|
|
else
|
|
begin
|
|
description:='add';
|
|
lastdisassembledata.opcode:='fiadd';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
end;
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
1: begin
|
|
description:='multiply';
|
|
last:=2;
|
|
if memory[1]>=$c8 then
|
|
begin
|
|
lastdisassembledata.opcode:='fmulp';
|
|
lastdisassembledata.parameters:='st('+inttostr(memory[1]-$c8)+'),st(0)';
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='fimul';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
end;
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
2: begin
|
|
description:='compare integer';
|
|
last:=2;
|
|
lastdisassembledata.opcode:='ficom';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
|
|
3: begin
|
|
if memory[1]<$c0 then
|
|
begin
|
|
description:='compare integer';
|
|
lastdisassembledata.opcode:='ficomp';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
if memory[1]=$d9 then
|
|
begin
|
|
description:='compare real and pop register stack twice';
|
|
lastdisassembledata.opcode:='fcompp';
|
|
inc(offset);
|
|
end;
|
|
end;
|
|
|
|
4: begin
|
|
description:='subtract';
|
|
last:=2;
|
|
if memory[1]>=$e0 then
|
|
begin
|
|
lastdisassembledata.opcode:='fsubrp';
|
|
lastdisassembledata.parameters:='st('+inttostr(memory[1]-$e0)+'),st(0)';
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='fisub';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
end;
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
|
|
5: begin
|
|
description:='reverse divide';
|
|
last:=2;
|
|
if memory[1]>=$e8 then
|
|
begin
|
|
description:='subtract and pop from stack';
|
|
lastdisassembledata.opcode:='fsubp';
|
|
lastdisassembledata.parameters:='st('+inttostr(memory[1]-$e8)+'),st(0)'
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='fisubr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
end;
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
|
|
6: begin
|
|
description:='reverse divide';
|
|
last:=2;
|
|
if memory[1]>=$f0 then
|
|
begin
|
|
lastdisassembledata.opcode:='fdivrp';
|
|
lastdisassembledata.parameters:='st('+inttostr(memory[1]-$f0)+'),st(0)';
|
|
inc(offset,last-1);
|
|
end
|
|
else
|
|
begin
|
|
description:='divide';
|
|
lastdisassembledata.opcode:='fidiv';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
7: begin
|
|
description:='divide';
|
|
last:=2;
|
|
if memory[1]>=$f8 then
|
|
begin
|
|
lastdisassembledata.opcode:='fdivp';
|
|
lastdisassembledata.parameters:='st('+inttostr(memory[1]-$f8)+'),st(0)';
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='fdivr';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
end;
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
|
|
$df : begin
|
|
if memory[1] in [$c0..$c7] then
|
|
begin
|
|
description:='free floating-point register and pop (might not work)';
|
|
lastdisassembledata.opcode:='ffreep';
|
|
lastdisassembledata.parameters:='st('+inttostr(memory[1]-$c0)+')';
|
|
inc(offset);
|
|
end
|
|
else
|
|
case getreg(memory[1]) of
|
|
0: begin
|
|
description:='load integer';
|
|
lastdisassembledata.opcode:='fild';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,16);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
1: begin
|
|
description:='store integer with truncation';
|
|
lastdisassembledata.opcode:='fisttp';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,16);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
2: begin
|
|
description:='store integer';
|
|
lastdisassembledata.opcode:='fist';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,16);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
3: begin
|
|
description:='store integer';
|
|
lastdisassembledata.opcode:='fistp';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,16);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
4: begin
|
|
description:='load binary coded decimal';
|
|
last:=2;
|
|
if memory[1]>=$e0 then
|
|
begin
|
|
lastdisassembledata.opcode:='fnstsw';
|
|
lastdisassembledata.parameters:=colorreg+'ax'+endcolor;
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='fbld';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,80);
|
|
|
|
end;
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
5: begin
|
|
if memory[1]<$c0 then
|
|
begin
|
|
description:='load integer';
|
|
lastdisassembledata.opcode:='fild';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
if memory[1]>=$e8 then
|
|
begin
|
|
description:='compare real and set eflags';
|
|
lastdisassembledata.opcode:='fucomip';
|
|
lastdisassembledata.parameters:='st(0),st('+inttostr(memory[1]-$e8)+')';
|
|
inc(offset);
|
|
end;
|
|
end;
|
|
|
|
6: begin
|
|
if memory[1]>=$f0 then
|
|
begin
|
|
description:='compare real and set eflags';
|
|
lastdisassembledata.opcode:='fcomip';
|
|
lastdisassembledata.parameters:='st(0),st('+inttostr(memory[1]-$f0)+')';
|
|
inc(offset)
|
|
end
|
|
else
|
|
begin
|
|
description:='store bcd integer and pop';
|
|
lastdisassembledata.opcode:='fbstp';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,80);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
end;
|
|
|
|
7: begin
|
|
description:='store integer';
|
|
lastdisassembledata.opcode:='fistp';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='db';
|
|
lastdisassembledata.parameters:=inttohexs(memory[0],2);
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
|
|
$e0 : begin
|
|
description:='loop according to ecx counter';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_ZF)=0;
|
|
|
|
lastdisassembledata.opcode:='loopne';
|
|
|
|
inc(offset);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(pshortint(@memory[1])^))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(pshortint(@memory[1])^));
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
end;
|
|
|
|
$e1 : begin
|
|
description:='loop according to ecx counter';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=(context^.EFlags and EFLAGS_ZF)<>0;
|
|
|
|
lastdisassembledata.opcode:='loope';
|
|
inc(offset);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(pshortint(@memory[1])^))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(pshortint(@memory[1])^));
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
end;
|
|
|
|
$e2 : begin
|
|
description:='loop according to ecx counting';
|
|
lastdisassembledata.opcode:='loop';
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=context^.{$ifdef CPU64}RCX{$else}ECX{$endif}<>0;
|
|
|
|
lastdisassembledata.isjump:=true;
|
|
inc(offset);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(pshortint(@memory[1])^))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(pshortint(@memory[1])^));
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
end;
|
|
|
|
$e3 : begin
|
|
description:='jump short if cx=0';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.isconditionaljump:=true;
|
|
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='jcxz';
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=((context^.{$ifdef CPU64}RCX{$else}ECX{$endif}) and $ffff)=0;
|
|
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='jecxz';
|
|
if context<>nil then
|
|
lastdisassembledata.willJumpAccordingToContext:=context^.{$ifdef CPU64}RCX{$else}ECX{$endif}=0;
|
|
|
|
end;
|
|
inc(offset);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
|
|
|
|
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(pshortint(@memory[1])^))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(pshortint(@memory[1])^));
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
end;
|
|
|
|
$e4 : begin
|
|
description:='input from port';
|
|
lastdisassembledata.opcode:='in';
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[1];
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
lastdisassembledata.parameters:=colorreg+'al'+endcolor+','+inttohexs(memory[1],2);
|
|
inc(offset);
|
|
|
|
end;
|
|
|
|
$e5 : begin
|
|
description:='input from port';
|
|
lastdisassembledata.opcode:='in';
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[1];
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
if $66 in prefix2 then lastdisassembledata.parameters:=colorreg+'ax'+endcolor+','+inttohexs(memory[1],2)
|
|
else lastdisassembledata.parameters:=colorreg+'eax'+endcolor+','+inttohexs(memory[1],2);
|
|
inc(offset);
|
|
|
|
end;
|
|
|
|
$e6 : begin
|
|
description:='output to port';
|
|
lastdisassembledata.opcode:='out';
|
|
lastdisassembledata.parameters:=inttohexs(memory[1],2)+','+colorreg+'al'+endcolor;
|
|
inc(offset);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[1];
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount)
|
|
end;
|
|
|
|
$e7 : begin
|
|
description:='output toport';
|
|
lastdisassembledata.opcode:='out';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=inttohexs(memory[1],2)+','+colorreg+'ax'+endcolor else
|
|
lastdisassembledata.parameters:=inttohexs(memory[1],2)+','+colorreg+'eax'+endcolor;
|
|
|
|
inc(offset);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtvalue;
|
|
lastdisassembledata.parametervalue:=memory[1];
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
end;
|
|
|
|
$e8 : begin
|
|
//call
|
|
//this time no $66 prefix because it will only run in win32
|
|
description:='call procedure';
|
|
lastdisassembledata.opcode:='call';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.iscall:=true;
|
|
|
|
if MarkIPRelativeInstructions then
|
|
begin
|
|
LastDisassembleData.riprelative:=1;
|
|
riprelative:=true;
|
|
end;
|
|
inc(offset,4);
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(pinteger(@memory[1])^))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(pinteger(@memory[1])^));
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
end;
|
|
|
|
$e9 : begin
|
|
description:='jump near';
|
|
lastdisassembledata.isjump:=true;
|
|
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='jmp';
|
|
|
|
inc(offset,2);
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(psmallint(@memory[1])^));
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='jmp';
|
|
|
|
if MarkIPRelativeInstructions then
|
|
begin
|
|
LastDisassembleData.riprelative:=1;
|
|
riprelative:=true;
|
|
end;
|
|
|
|
inc(offset,4);
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(pinteger(@memory[1])^))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(pinteger(@memory[1])^));
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8)
|
|
end;
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
end;
|
|
|
|
$ea : begin
|
|
description:='jump far';
|
|
lastdisassembledata.isjump:=true;
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=5;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
|
|
wordptr:=@memory[5];
|
|
lastdisassembledata.opcode:='jmp';
|
|
lastdisassembledata.parameters:=inttohexs(wordptr^,4)+':';
|
|
dwordptr:=@memory[1];
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
|
|
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(dwordptr^,8);
|
|
inc(offset,6);
|
|
end;
|
|
|
|
$eb : begin
|
|
description:='jump short';
|
|
lastdisassembledata.opcode:='jmp';
|
|
lastdisassembledata.isjump:=true;
|
|
|
|
inc(offset);
|
|
|
|
if is64bit then
|
|
lastdisassembledata.parametervalue:=qword(offset+qword(pshortint(@memory[1])^))
|
|
else
|
|
lastdisassembledata.parametervalue:=dword(offset+qword(pshortint(@memory[1])^));
|
|
|
|
lastdisassembledata.parameters:=inttohexs(lastdisassembledata.parametervalue,8);
|
|
|
|
lastdisassembledata.parametervaluetype:=dvtAddress;
|
|
|
|
lastdisassembledata.seperators[lastdisassembledata.seperatorcount]:=1;
|
|
inc(lastdisassembledata.seperatorcount);
|
|
|
|
end;
|
|
|
|
$ec : begin
|
|
description:='input from port';
|
|
lastdisassembledata.opcode:='in';
|
|
lastdisassembledata.parameters:=colorreg+'al'+endcolor+','+colorreg+'dx'+endcolor;
|
|
end;
|
|
|
|
$ed : begin
|
|
description:='input from port';
|
|
lastdisassembledata.opcode:='in';
|
|
if $66 in prefix2 then lastdisassembledata.parameters:=colorreg+'ax'+endcolor+','+colorreg+'dx'+endcolor else
|
|
lastdisassembledata.parameters:=colorreg+'eax'+endcolor+','+colorreg+'dx'+endcolor;
|
|
end;
|
|
|
|
$ee : begin
|
|
description:='input from port';
|
|
lastdisassembledata.opcode:='out';
|
|
lastdisassembledata.parameters:=colorreg+'dx'+endcolor+','+colorreg+'al'+endcolor
|
|
end;
|
|
|
|
$ef : begin
|
|
description:='input from port';
|
|
lastdisassembledata.opcode:='out';
|
|
if $66 in prefix2 then lastdisassembledata.parameters:=colorreg+'dx'+endcolor+','+colorreg+'ax'+endcolor else
|
|
lastdisassembledata.parameters:=colorreg+'dx'+endcolor+','+colorreg+'eax'+endcolor ;
|
|
end;
|
|
|
|
$f3 : begin
|
|
|
|
end;
|
|
|
|
$f4 : begin
|
|
description:='halt';
|
|
lastdisassembledata.opcode:='hlt';
|
|
end;
|
|
|
|
$f5 : begin
|
|
description:='complement carry flag';
|
|
lastdisassembledata.opcode:='cmc';
|
|
end;
|
|
|
|
$f6 : begin
|
|
case getreg(memory[1]) of
|
|
0: begin
|
|
description:='logical compare';
|
|
lastdisassembledata.opcode:='test';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(memory[last],2);
|
|
lastdisassembledata.parametervaluetype:=dvtValue;
|
|
lastdisassembledata.parametervalue:=memory[last];
|
|
|
|
|
|
inc(offset,last);
|
|
end;
|
|
|
|
2: begin
|
|
description:='one''s complement negation';
|
|
lastdisassembledata.opcode:='not';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
3: begin
|
|
description:='two''s complement negation';
|
|
lastdisassembledata.opcode:='neg';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
4: begin
|
|
description:='unsigned multiply';
|
|
lastdisassembledata.opcode:='mul';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
5: begin
|
|
description:='signed multiply';
|
|
lastdisassembledata.opcode:='imul';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
6: begin
|
|
description:='unsigned divide';
|
|
lastdisassembledata.opcode:='div';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
7: begin
|
|
description:='signed divide';
|
|
lastdisassembledata.opcode:='idiv';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='db';
|
|
lastdisassembledata.parameters:=inttohexs(memory[0],2);
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
|
|
$f7 : begin
|
|
case getreg(memory[1]) of
|
|
0: begin
|
|
description:='logical compare';
|
|
if $66 in prefix2 then
|
|
begin
|
|
lastdisassembledata.opcode:='test';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16);
|
|
wordptr:=@memory[last];
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
lastdisassembledata.parametervalue:=wordptr^;
|
|
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(wordptr^,4);
|
|
inc(offset,last+1);
|
|
end
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='test';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
dwordptr:=@memory[last];
|
|
lastdisassembledata.parametervaluetype:=dvtaddress;
|
|
lastdisassembledata.parametervalue:=dwordptr^;
|
|
if rex_w then
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(longint(dwordptr^),8)
|
|
else
|
|
lastdisassembledata.parameters:=lastdisassembledata.parameters+inttohexs(dwordptr^,8);
|
|
inc(offset,last+3);
|
|
end;
|
|
end;
|
|
|
|
2: begin
|
|
description:='one''s complement negation';
|
|
lastdisassembledata.opcode:='not';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
3: begin
|
|
description:='two''s complement negation';
|
|
lastdisassembledata.opcode:='neg';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16)
|
|
else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
4: begin
|
|
description:='unsigned multiply';
|
|
lastdisassembledata.opcode:='mul';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16)
|
|
else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
5: begin
|
|
description:='signed multiply';
|
|
lastdisassembledata.opcode:='imul';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16)
|
|
else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
6: begin
|
|
description:='unsigned divide';
|
|
lastdisassembledata.opcode:='div';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16)
|
|
else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
7: begin
|
|
description:='signed divide';
|
|
lastdisassembledata.opcode:='idiv';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16)
|
|
else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='db';
|
|
lastdisassembledata.parameters:=inttohexs(memory[0],2);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$f8 : begin
|
|
description:='clear carry flag';
|
|
lastdisassembledata.opcode:='clc';
|
|
end;
|
|
|
|
$f9 : begin
|
|
description:='set carry flag';
|
|
lastdisassembledata.opcode:='stc';
|
|
end;
|
|
|
|
$fa : begin
|
|
description:='clear interrupt flag';
|
|
lastdisassembledata.opcode:='cli';
|
|
end;
|
|
|
|
$fb : begin
|
|
description:='set interrupt flag';
|
|
lastdisassembledata.opcode:='sti';
|
|
end;
|
|
|
|
$fc : begin
|
|
description:='clear direction flag';
|
|
lastdisassembledata.opcode:='cld';
|
|
end;
|
|
|
|
$fd : begin
|
|
description:='set direction flag';
|
|
lastdisassembledata.opcode:='std';
|
|
end;
|
|
|
|
$fe : begin
|
|
case getreg(memory[1]) of
|
|
0: begin
|
|
description:='increment by 1';
|
|
lastdisassembledata.opcode:='inc';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,8);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
1: begin
|
|
description:='decrement by 1';
|
|
lastdisassembledata.opcode:='dec';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,2,last,7);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='db';
|
|
lastdisassembledata.parameters:=inttohexs(memory[0],2);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
$ff : begin
|
|
case getreg(memory[1]) of
|
|
0: begin
|
|
description:='increment by 1';
|
|
lastdisassembledata.opcode:='inc';
|
|
|
|
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16)
|
|
else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,ifthen(Rex_W,64,0));
|
|
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
1: begin
|
|
description:='decrement by 1';
|
|
lastdisassembledata.opcode:='dec';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last,16)
|
|
else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,ifthen(Rex_W,64,0));
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
2: begin
|
|
//call
|
|
description:='call procedure';
|
|
lastdisassembledata.opcode:='call';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.iscall:=true;
|
|
|
|
if memory[1]>=$c0 then
|
|
begin
|
|
if is64bit then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64) else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
|
|
end
|
|
else
|
|
begin
|
|
if is64bit then
|
|
begin
|
|
|
|
if (memory[1]=$15) and (pdword(@memory[2])^=2) and (pword(@memory[6])^=$8eb) then //special 16 byte call
|
|
begin
|
|
lastdisassembledata.parameters:=inttohexs(pqword(@memory[8])^,8);
|
|
LastDisassembleData.parameterValue:=pqword(@memory[8])^;
|
|
LastDisassembleData.parameterValueType:=dvtAddress;
|
|
|
|
inc(last,8+4+2+2);
|
|
|
|
LastDisassembleData.Seperators[0]:=2;
|
|
LastDisassembleData.Seperators[1]:=2+4;
|
|
LastDisassembleData.Seperators[2]:=2+4+2;
|
|
LastDisassembleData.SeperatorCount:=3;
|
|
|
|
end
|
|
else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
end
|
|
else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
end;
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
3: begin
|
|
//call
|
|
description:='call procedure';
|
|
lastdisassembledata.opcode:='call';
|
|
lastdisassembledata.isjump:=true;
|
|
lastdisassembledata.iscall:=true;
|
|
|
|
if is64bit then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64)
|
|
else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
4: begin
|
|
//jmp
|
|
description:='jump near';
|
|
lastdisassembledata.opcode:='jmp';
|
|
lastdisassembledata.isjump:=true;
|
|
|
|
|
|
if is64bit then
|
|
begin
|
|
if (memory[1]=$25) and (pdword(@memory[2])^=0) then //special 14 byte jmp
|
|
begin
|
|
LastDisassembleData.parameterValue:=pqword(@memory[6])^;
|
|
LastDisassembleData.parameterValueType:=dvtAddress;
|
|
|
|
lastdisassembledata.parameters:=inttohexs(pqword(@memory[6])^,8);
|
|
inc(last,8+4+2);
|
|
|
|
LastDisassembleData.Seperators[0]:=2;
|
|
LastDisassembleData.Seperators[1]:=2+4;
|
|
LastDisassembleData.SeperatorCount:=2;
|
|
|
|
end
|
|
else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,64);
|
|
end
|
|
else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last,32);
|
|
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
5: begin
|
|
//jmp
|
|
description:='jump far';
|
|
lastdisassembledata.opcode:='jmp far';
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
lastdisassembledata.isjump:=true;
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
|
|
6: begin
|
|
description:='push word or doubleword onto the stack';
|
|
lastdisassembledata.opcode:='push';
|
|
if $66 in prefix2 then
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,1,last)
|
|
else
|
|
lastdisassembledata.parameters:=modrm(memory,prefix2,1,0,last);
|
|
|
|
|
|
inc(offset,last-1);
|
|
end;
|
|
else
|
|
begin
|
|
lastdisassembledata.opcode:='db';
|
|
lastdisassembledata.parameters:=inttohexs(memory[0],2);
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
else begin
|
|
lastdisassembledata.opcode:='db';
|
|
lastdisassembledata.parameters:=inttohex(memory[0],2);
|
|
end;
|
|
end;
|
|
|
|
|
|
debugpart:=12;
|
|
// if dataonly then exit; //no need to handle the other stuff, dataonly means I'm only interested in the addresses, not bytes or extra parameters
|
|
|
|
if (lastdisassembledata.parameters<>'') and (lastdisassembledata.parameters[length(lastdisassembledata.parameters)]=',') then
|
|
setlength(lastdisassembledata.parameters, length(lastdisassembledata.parameters)-1);
|
|
|
|
|
|
// tempresult:=tempresult+LastDisassembleData.opcode+' '+LastDisassembleData.parameters;
|
|
|
|
LastDisassembleData.description:=description;
|
|
|
|
//copy the remaining bytes
|
|
k:=length(LastDisassembleData.Bytes);
|
|
|
|
if int64(offset-initialoffset)<k then
|
|
offset:=initialoffset+k;
|
|
|
|
setlength(LastDisassembleData.Bytes,offset-initialoffset);
|
|
debugpart:=13;
|
|
|
|
if (k>=32) or (k<0) then
|
|
begin
|
|
MessageBox(0,pchar(inttohex(startoffset,8)+'disassembler error 1'),'debug here',MB_OK);
|
|
end;
|
|
|
|
td:=dword(offset-initialoffset-qword(k));
|
|
i:=k+td;
|
|
if (td>=32) or (i>=32) or (i<0) then
|
|
begin
|
|
MessageBox(0,pchar(inttohex(startoffset,8)+'disassembler error 2'),'debug here',MB_OK);
|
|
end;
|
|
|
|
debugpart:=14;
|
|
|
|
if td>0 then
|
|
begin
|
|
breaknow:=false;
|
|
try
|
|
|
|
copymemory(@LastDisassembleData.Bytes[k], @_memory[k], td);
|
|
except
|
|
breaknow:=true;
|
|
end;
|
|
|
|
if breaknow then
|
|
begin
|
|
asm
|
|
nop
|
|
end;
|
|
MessageBox(0,pchar(inttohex(startoffset,8)+'disassembler error 3'),'debug here',MB_OK);
|
|
|
|
end;
|
|
end;
|
|
|
|
debugpart:=15;
|
|
|
|
|
|
//adjust for the prefix.
|
|
if k<>0 then
|
|
begin
|
|
for i:=0 to LastDisassembleData.SeperatorCount-1 do
|
|
inc(LastDisassembleData.Seperators[i],prefixsize);
|
|
|
|
if LastDisassembleData.riprelative<>0 then
|
|
inc(LastDisassembleData.riprelative, prefixsize);
|
|
end;
|
|
|
|
|
|
|
|
|
|
//todo: Next time the disassembler is getting an averhaul, do something about the prefix counting and the unnecessary readprocessmemorys associated with it
|
|
|
|
|
|
// result:=result+'- '+tempresult;
|
|
|
|
debugpart:=16;
|
|
|
|
if riprelative then
|
|
begin
|
|
debugpart:=17;
|
|
//add the current offset to the code between []
|
|
LastDisassembleData.modrmValue:=offset+ptrint(integer(LastDisassembleData.modrmValue)); //sign extended increase
|
|
|
|
i:=pos('[',LastDisassembleData.parameters);
|
|
j:=PosEx(']',LastDisassembleData.parameters,i);
|
|
// tempresult:=copy(LastDisassembleData.parameters,i+1,j-i-1);
|
|
|
|
|
|
tempaddress:=LastDisassembleData.modrmValue;
|
|
|
|
tempresult:=copy(LastDisassembleData.parameters,1,i);
|
|
tempresult:=tempresult+inttohexs(tempaddress,8);
|
|
LastDisassembleData.parameters:=tempresult+copy(LastDisassembleData.parameters,j,length(LastDisassembleData.parameters));
|
|
end;
|
|
|
|
debugpart:=18;
|
|
|
|
|
|
|
|
|
|
|
|
end
|
|
else
|
|
begin
|
|
LastDisassembleData.opcode:='??';
|
|
inc(offset);
|
|
end;
|
|
{$ifdef windows}
|
|
LastDisassembleData.iscloaked:=hasCloakedRegionInRange(LastDisassembleData.address, length(LastDisassembleData.Bytes), VA, PA);
|
|
{$else}
|
|
LastDisassembleData.iscloaked:=false;
|
|
{$endif}
|
|
debugpart:=19;
|
|
|
|
if not dataonly then
|
|
begin
|
|
result:=inttohex(LastDisassembleData.address,8)+' - '+getLastBytestring;
|
|
result:=result+' - ';
|
|
result:=result+LastDisassembleData.prefix+LastDisassembleData.opcode;
|
|
result:=result+' ';
|
|
result:=result+LastDisassembleData.parameters;
|
|
end;
|
|
|
|
debugpart:=20;
|
|
|
|
if assigned(OnPostDisassemble) then
|
|
begin
|
|
debugpart:=21;
|
|
tempresult:=result;
|
|
tempdescription:=description;
|
|
|
|
if OnPostDisassemble(self, initialoffset, LastDisassembleData, tempresult, tempdescription) then
|
|
begin
|
|
result:=tempresult;
|
|
description:=tempdescription;
|
|
|
|
if length(LastDisassembleData.Bytes)>0 then
|
|
offset:=initialoffset+length(LastDisassembleData.Bytes);
|
|
end;
|
|
end;
|
|
|
|
debugpart:=22;
|
|
//finally
|
|
// cs.Leave;
|
|
//end
|
|
{ for i:=32 to 63 do
|
|
if _memory[i]<>$ce then
|
|
raise exception.create('Memory corruption in the disassembler'); }
|
|
except
|
|
on e:exception do
|
|
begin
|
|
outputdebugstring(inttohex(startoffset,8)+':disassembler exception:'+e.message);
|
|
MessageBox(0,pchar('disassembler exception at '+inttohex(startoffset,8)+#13#10+'Debugpart='+inttostr(debugpart)+#13#10+e.message+#13#10+#13#10+'Please provide dark byte the bytes that are at this address so he can fix it'#13#10'(Open another CE instance and in the hexadecimal view go to this address)'),'debug here',MB_OK);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TDisassembler.getLastBytestring: string;
|
|
var
|
|
i,j: integer;
|
|
cloaked:boolean=false;
|
|
changed:boolean=false;
|
|
VA,PA: qword;
|
|
begin
|
|
result:='';
|
|
if processhandler.SystemArchitecture=archArm then
|
|
begin
|
|
if length(LastDisassembleData.Bytes)=2 then
|
|
result:=pword(@LastDisassembleData.Bytes[0])^.ToHexString(4);
|
|
|
|
if length(LastDisassembleData.Bytes)=4 then
|
|
result:=pdword(@LastDisassembleData.Bytes[0])^.ToHexString(8);
|
|
|
|
exit;
|
|
end;
|
|
|
|
for i:=0 to length(LastDisassembleData.Bytes)-1 do
|
|
begin
|
|
if syntaxhighlighting then
|
|
begin
|
|
if LastDisassembleData.iscloaked then
|
|
begin
|
|
//check if this byte is cloaked (due to pageboundaries)
|
|
{$ifdef windows}
|
|
cloaked:=hasCloakedRegionInRange(LastDisassembleData.address+i, 1, VA, PA);
|
|
if (cloaked) then result:=result+'{C00FF00}'; //green
|
|
{$endif}
|
|
end;
|
|
|
|
changed:=hasAddressBeenChanged(LastDisassembleData.address+i);
|
|
if (changed) then result:=result+'{C0000FF}'; //red
|
|
end;
|
|
|
|
result:=result+inttohex(LastDisassembleData.Bytes[i],2);
|
|
|
|
if i<LastDisassembleData.prefixsize then
|
|
result:=result+' '
|
|
else
|
|
for j:=0 to LastDisassembleData.SeperatorCount-1 do
|
|
if (LastDisassembleData.Seperators[j]=i+1) then //followed by a seperator
|
|
result:=result+' ';
|
|
|
|
if syntaxhighlighting and ((LastDisassembleData.iscloaked and cloaked) or changed ) then
|
|
begin
|
|
result:=result+'{N}'; //back to default
|
|
cloaked:=false;
|
|
changed:=false;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
function disassemble(var offset: ptrUint): string; overload;
|
|
var ignore: string;
|
|
begin
|
|
result:=disassemble(offset,ignore);
|
|
end;
|
|
|
|
|
|
function previousOpcodeHelp(d: Tdisassembler; address: ptruint; distance:integer; var result2: ptruint): ptruint;
|
|
var x,y: ptruint;
|
|
s: string;
|
|
i: integer;
|
|
begin
|
|
x:=address-distance;
|
|
while x<address do
|
|
begin
|
|
y:=x;
|
|
d.disassemble(x,s);
|
|
end;
|
|
result:=x;
|
|
result2:=y;
|
|
end;
|
|
|
|
|
|
function previousopcode(address: ptrUint; d: Tdisassembler=nil):ptrUint;
|
|
var
|
|
x,y: ptrUint;
|
|
s: string;
|
|
found: boolean;
|
|
i: ptrUint;
|
|
|
|
aggressive: boolean;
|
|
begin
|
|
if d=nil then
|
|
d:=defaultDisassembler;
|
|
|
|
aggressive:=d.aggressivealignment;
|
|
d.aggressivealignment:=true;
|
|
|
|
x:=previousOpcodeHelp(d, address,80, result);
|
|
if x<>address then
|
|
begin
|
|
//no match found 80 bytes from the start
|
|
//try 40
|
|
x:=previousOpcodeHelp(d, address,40, result);
|
|
|
|
if x<>address then
|
|
begin
|
|
//nothing with 40, try 20
|
|
x:=previousOpcodeHelp(d, address,20,result);
|
|
if x<>address then
|
|
begin
|
|
//no 20, try 10
|
|
x:=previousOpcodeHelp(d, address,10,result);
|
|
if x<>address then
|
|
begin
|
|
//and if all else fails try to find the closest one
|
|
result:=address-1;
|
|
for i:=1 to 20 do
|
|
begin
|
|
x:=address-i;
|
|
d.disassemble(x,s);
|
|
if x=address then
|
|
begin
|
|
result:=address-i;
|
|
exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
d.aggressivealignment:=aggressive;
|
|
end;
|
|
|
|
|
|
|
|
|
|
function has4ByteHexString(d: string; var hexstring: string): boolean;
|
|
var
|
|
hexcount: integer;
|
|
i: integer;
|
|
|
|
lastmatch: integer;
|
|
lasthexcount: integer;
|
|
begin
|
|
result:=false;
|
|
hexcount:=0;
|
|
lasthexcount:=0;
|
|
lastmatch:=0;
|
|
|
|
for i:=length(d) downto 1 do
|
|
begin
|
|
if d[i] in ['a'..'f','A'..'F','0'..'9'] then
|
|
begin
|
|
inc(hexcount);
|
|
|
|
if hexcount>lasthexcount then
|
|
begin
|
|
lastmatch:=i;
|
|
lasthexcount:=hexcount;
|
|
end;
|
|
end
|
|
else
|
|
hexcount:=0;
|
|
end;
|
|
|
|
if lasthexcount>=8 then
|
|
begin
|
|
//it has at least a 4 byte hexadecimal value, so an address specifier
|
|
hexstring:='$'+copy(d,lastmatch,lasthexcount);
|
|
result:=true;
|
|
end;
|
|
end;
|
|
|
|
function hasAddress(d: string; var address: ptrUint; context: PContext=nil):boolean;
|
|
{
|
|
returns if the opcode has an accessible address specifier or not, and the address
|
|
}
|
|
var
|
|
s: string;
|
|
i,j: integer;
|
|
br: ptruint;
|
|
|
|
haserror: boolean;
|
|
begin
|
|
result:=false;
|
|
|
|
if d='' then exit;
|
|
if pos(' ',d)=0 then exit;
|
|
|
|
//if the opcode has a , then get the last part
|
|
i:=pos(',',d);
|
|
if i>0 then
|
|
begin
|
|
d:=copy(d,i+1,length(d));
|
|
end;
|
|
|
|
if (context=nil) then
|
|
begin
|
|
if pos('+',d)>0 then exit; //it has an offset, so also a register. without a context, this is impossible
|
|
|
|
//check O for a hexadecimal value of 8 bytes and longer.
|
|
if has4ByteHexString(d,s) then
|
|
begin
|
|
address:=StrToQWordEx(s); //s already has the $ in front
|
|
|
|
result:=isAddress(address);
|
|
|
|
end;
|
|
end else
|
|
begin
|
|
//a slower but more effective address detector
|
|
//strip of everything before the space, and if there's a [ ] get what's inbetween
|
|
//then use the symbolhandler to find out what it is
|
|
i:=pos(' ',d);
|
|
if i>0 then //it has a space , so a instruction is still present, strip it
|
|
d:=copy(d,i+1,length(d));
|
|
|
|
i:=pos('[',d);
|
|
if i>0 then
|
|
begin
|
|
d:=copy(d,i+1,pos(']',d)-i-1);
|
|
|
|
end;
|
|
|
|
address:=symhandler.getAddressFromName(d,false,haserror, context);
|
|
result:=not haserror;
|
|
end;
|
|
|
|
|
|
|
|
end;
|
|
|
|
function TDisassembler.opcode4FST(opcode: string): integer;
|
|
begin
|
|
result:=3; //float
|
|
if length(opcode)>=4 then
|
|
begin
|
|
case opcode[4] of
|
|
'c','e','s': result:=2;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TDisassembler.opcode3FN(opcode: string): integer;
|
|
begin
|
|
result:=3; //float
|
|
if length(opcode)>=3 then
|
|
begin
|
|
case opcode[3] of
|
|
's' : result:=2; //fnst
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TDisassembler.opcode3FS(opcode: string): integer;
|
|
begin
|
|
result:=3; //float
|
|
if length(opcode)>=3 then
|
|
begin
|
|
case opcode[3] of
|
|
't' : result:=opcode4FST(opcode); //fstxxx (fst, fstp, fstcw, fstenv, fstsw)
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TDisassembler.opcode2F(opcode: string): integer;
|
|
begin
|
|
result:=3;
|
|
if length(opcode)>=2 then
|
|
begin
|
|
case opcode[2] of
|
|
'i' : result:=2; //fixxxxx
|
|
'n' : result:=opcode3FN(opcode);
|
|
's' : result:=opcode3FS(opcode);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function tdisassembler.opcodeToValueType(opcode: string): integer;
|
|
{
|
|
figures out what type of memory access this opcode does
|
|
returns 2 if unsure
|
|
}
|
|
begin
|
|
result:=2;
|
|
if length(opcode)>=1 then
|
|
begin
|
|
case opcode[1] of
|
|
'f' : result:=opcode2F(opcode);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure splitDisassembledString(disassembled: string; showvalues: boolean; var address: string; var bytes: string; var opcode: string; var special:string; context: PContext=nil);
|
|
begin
|
|
defaultDisassembler.splitDisassembledString(disassembled, showvalues, address,bytes, opcode, special, context);
|
|
end;
|
|
|
|
function tdisassembler.DecodeLastParametersToString: string;
|
|
{
|
|
use the last disassembled data to show some detailed data
|
|
}
|
|
var
|
|
jumpAddress: ptrUint;
|
|
buffer: array [0..63] of byte;
|
|
x: PtrUInt;
|
|
|
|
values: array [0..1] of record
|
|
value: ptruint;
|
|
vtype: TVariableType;
|
|
isAddress: boolean;
|
|
s: string;
|
|
end;
|
|
//value: ptrUint;
|
|
//vtype: TVariableType;
|
|
a: boolean;
|
|
s: string;
|
|
|
|
|
|
parametercount: integer;
|
|
sv1,sv2: string;
|
|
|
|
i: integer;
|
|
begin
|
|
if LastDisassembleData.commentsoverride<>'' then
|
|
exit(LastDisassembleData.commentsoverride);
|
|
|
|
result:='';
|
|
|
|
if LastDisassembleData.isjump then
|
|
begin
|
|
if LastDisassembleData.modrmValueType=dvtAddress then
|
|
begin
|
|
jumpAddress:=LastDisassembleData.modrmValue;
|
|
|
|
if not ReadProcessMemory(processhandle, pointer(jumpAddress), @jumpAddress, processhandler.pointersize,x) then exit;
|
|
end
|
|
else
|
|
begin
|
|
if LastDisassembleData.parameterValueType=dvtNone then
|
|
exit; //jump with no address (e.g reg)
|
|
|
|
jumpAddress:=LastDisassembleData.parameterValue;
|
|
end;
|
|
|
|
//check if the bytes at jumpAddress is ff 25 (jmp [xxxxxxxx])
|
|
if ReadProcessMemory(processhandle, pointer(jumpAddress), @buffer[0], 6,x) then
|
|
begin
|
|
|
|
if (buffer[0]=$ff) and (buffer[1]=$25) then
|
|
begin
|
|
result:=result+'->'; //double, so ->->
|
|
|
|
|
|
if is64bit then
|
|
jumpAddress:=jumpaddress+6+pinteger(@buffer[2])^ //jumpaddress+6 because of relative addressing
|
|
else
|
|
jumpAddress:=pdword(@buffer[2])^;
|
|
|
|
//jumpaddress now contains the address of the address to jump to
|
|
//so, get the address it actually jumps to
|
|
if not ReadProcessMemory(processhandle, pointer(jumpAddress), @jumpAddress, processhandler.pointersize,x) then exit;
|
|
end;
|
|
|
|
|
|
s:=symhandler.getNameFromAddress(jumpAddress, symhandler.showsymbols, symhandler.showmodules, symhandler.showsections, nil,nil,8,false);
|
|
if pos(s, LastDisassembleData.parameters)=0 then //no need to show a comment if it's exactly the same
|
|
result:=result+'->'+s;
|
|
end;
|
|
|
|
|
|
end
|
|
else
|
|
begin
|
|
if (LastDisassembleData.modrmValueType=dvtAddress) or (LastDisassembleData.parameterValueType<>dvtNone) then
|
|
begin
|
|
a:=false;
|
|
|
|
parametercount:=0;
|
|
|
|
if LastDisassembleData.parameterValueType<>dvtNone then inc(parametercount);
|
|
if LastDisassembleData.modrmValueType=dvtAddress then inc(parametercount);
|
|
|
|
if (LastDisassembleData.modrmValueType=dvtAddress) then
|
|
begin
|
|
if (parametercount>1) and (modrmposition=mRight) then values[1].value:=LastDisassembleData.modrmValue else values[0].value:=LastDisassembleData.modrmValue;
|
|
end;
|
|
|
|
if LastDisassembleData.parameterValueType<>dvtNone then
|
|
begin
|
|
if (parametercount>1) and (modrmposition<>mRight) then values[1].value:=LastDisassembleData.parameterValue else values[0].value:=LastDisassembleData.parameterValue;
|
|
end;
|
|
|
|
for i:=0 to parametercount-1 do
|
|
begin
|
|
values[i].s:='';
|
|
|
|
if isAddress(values[i].value) then
|
|
begin
|
|
values[i].isAddress:=true;
|
|
x:=0;
|
|
|
|
values[i].vtype:=vtDword;
|
|
readprocessmemory(processhandle, pointer(values[i].value), @buffer[0], 63,x);
|
|
if x>0 then
|
|
begin
|
|
if LastDisassembleData.isfloat then
|
|
begin
|
|
case LastDisassembleData.datasize of
|
|
4: values[i].vtype:=vtSingle;
|
|
8: values[i].vtype:=vtDouble;
|
|
10: values[i].vtype:=vtQword; //('ext>'); //exit(format('%.2f',[pextended(@buffer[0])^]);
|
|
end;
|
|
end
|
|
else
|
|
values[i].vtype:=FindTypeOfData(values[i].value, @buffer[0], x)
|
|
end
|
|
else
|
|
begin
|
|
values[i].s:='';
|
|
continue;
|
|
end;
|
|
|
|
|
|
end
|
|
else
|
|
begin
|
|
x:=sizeof(values[i].value);
|
|
pptruint(@buffer[0])^:=values[i].value; //assign it so I don't have to make two compare routines
|
|
values[i].vtype:=FindTypeOfData(0, @buffer[0], x);
|
|
values[i].IsAddress:=false;
|
|
end;
|
|
|
|
|
|
|
|
case values[i].vtype of
|
|
vtByte: values[i].s:=inttostr(buffer[0]);
|
|
vtWord: values[i].s:=inttostr(PSmallInt(@buffer[0])^);
|
|
vtDword: if a then values[i].s:=inttohex(pdword(@buffer[0])^,8) else values[i].s:=inttostr(pinteger(@buffer[0])^);
|
|
vtQword: values[i].s:=inttostr(pInt64(@buffer[0])^);
|
|
vtSingle: values[i].s:=format('%.2f',[psingle(@buffer[0])^]);
|
|
vtDouble: values[i].s:=format('%.2f',[pdouble(@buffer[0])^]);
|
|
vtString:
|
|
begin
|
|
buffer[x]:=0;
|
|
values[i].s:='"'+pchar(@buffer[0])+'"';
|
|
end;
|
|
|
|
|
|
vtUnicodeString:
|
|
begin
|
|
buffer[x]:=0;
|
|
if x>0 then
|
|
buffer[x-1]:=0;
|
|
|
|
values[i].s:='"'+pwidechar(@buffer[0])+'"';
|
|
end;
|
|
|
|
vtPointer:
|
|
begin
|
|
if processhandler.is64Bit then
|
|
values[i].s:=inttohex(PQWord(@buffer[0])^,8)
|
|
else
|
|
values[i].s:=inttohex(PDWord(@buffer[0])^,8);
|
|
|
|
end;
|
|
end;
|
|
// result:=VariableTypeToString(vtype);
|
|
|
|
if values[i].isAddress and (values[i].s<>'') then
|
|
values[i].s:='('+values[i].s+')';
|
|
|
|
if i=0 then
|
|
result:=result+values[i].s
|
|
else
|
|
result:=result+','+values[i].s;
|
|
end;
|
|
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure tdisassembler.splitDisassembledString(disassembled: string; showvalues: boolean; var address: string; var bytes: string; var opcode: string; var special:string; context: PContext=nil);
|
|
//obsolete
|
|
var offset,value:ptrUint;
|
|
e: integer;
|
|
i,j,j2,k,l: integer;
|
|
ts,ts2,ts3: string;
|
|
actualread: PtrUInt;
|
|
valuetype: integer;
|
|
|
|
// tokens: ttokens;
|
|
fvalue: single;
|
|
fvalue2: double;
|
|
tempbuf: array [0..127] of byte;
|
|
|
|
pc: pchar;
|
|
pwc: pwidechar;
|
|
|
|
variableType: TVariableType;
|
|
tempaddress: ptrUint;
|
|
err: boolean;
|
|
isjumper: boolean;
|
|
hexstring: string;
|
|
begin
|
|
i:=pos(' - ',disassembled);
|
|
address:=uppercase(copy(disassembled,1,i-1));
|
|
|
|
inc(i,3);
|
|
j:=PosEx(' - ',disassembled,i);
|
|
if j=0 then j:=length(disassembled)+1;
|
|
bytes:=copy(disassembled,i,(j-i));
|
|
|
|
inc(j,3);
|
|
k:=PosEx(' : ',disassembled,j);
|
|
l:=k;
|
|
if k=0 then
|
|
k:=length(disassembled)+1;
|
|
|
|
opcode:=copy(disassembled,j,(k-j));
|
|
|
|
if showvalues then
|
|
begin
|
|
ts:='';
|
|
special:='';
|
|
|
|
try //could cause a parser exception if a weird symbol is used
|
|
if (hasAddress(opcode, tempaddress, context)) or ((length(opcode)>3) and (opcode[1]='l') and (opcode[2]='e') and (opcode[3]='a')) then
|
|
begin
|
|
if isaddress(tempaddress) then
|
|
begin
|
|
try
|
|
if (opcode[1]='l') and (opcode[2]='e') and (opcode[3]='a') then //lea
|
|
begin
|
|
j:=pos('[',opcode);
|
|
j2:=pos(']',opcode);
|
|
ts2:=copy(opcode,j+1,j2-j-1);
|
|
|
|
|
|
tempaddress:=symhandler.getAddressFromName(ts2,false,err);
|
|
if err then exit; //error
|
|
|
|
end;
|
|
except
|
|
tempaddress:=0;
|
|
end;
|
|
|
|
isjumper:=false;
|
|
if opcode[1]='j' then isjumper:=true; //jmp, jx
|
|
if (opcode[1]='l') and (opcode[2]='o') and (opcode[3]='o') then isjumper:=true; //loop
|
|
if (opcode[1]='c') and (opcode[2]='a') then isjumper:=true; //call
|
|
|
|
|
|
valuetype:=opcodeToValueType(opcode);
|
|
{
|
|
//tip: Replace with a function that checks for each opcode what value type it handles
|
|
if (opcode[1]='f') then //fxxx
|
|
begin
|
|
valuetype:=3;
|
|
if length(opcode)>3 then
|
|
begin
|
|
if opcode[2]='i' then valuetype:=2; //fixxxx
|
|
if (opcode[2]='n') and (opcode[3]='s') then valuetype:=2; //fns
|
|
end;
|
|
end else valuetype:=2;
|
|
}
|
|
|
|
i:=pos('[',disassembled);
|
|
if i>0 then
|
|
begin
|
|
//it might have an override
|
|
if pos('qword ptr',opcode)>0 then valuetype:=4 else //usually a double
|
|
if pos('dword ptr',opcode)>0 then valuetype:=2 else
|
|
if pos('word ptr',opcode)>0 then valuetype:=1 else
|
|
if pos('byte ptr',opcode)>0 then valuetype:=0 else
|
|
begin
|
|
//check the register used
|
|
j2:=pos(',[',opcode);
|
|
k:=pos('],',opcode);
|
|
if j2>0 then //register in front
|
|
begin
|
|
l:=pos(' ',opcode);
|
|
ts3:=copy(opcode,l+1,j2-l-1);
|
|
|
|
case TokenToRegisterbit(uppercase(ts3)) of
|
|
ttRegister8Bit: ValueType:=0;
|
|
ttRegister16Bit: valuetype:=1;
|
|
ttRegister32Bit: valuetype:=2;
|
|
else valuetype:=2;
|
|
end;
|
|
end
|
|
else
|
|
if k>0 then //register after ],
|
|
begin
|
|
l:=pos('],',opcode);
|
|
ts3:=copy(opcode,l+2,length(opcode)-l-1);
|
|
|
|
case TokenToRegisterbit(uppercase(ts3)) of
|
|
ttRegister8Bit: valuetype:=0;
|
|
ttRegister16Bit: valuetype:=1;
|
|
ttRegister32Bit: valuetype:=2;
|
|
else valuetype:=2;
|
|
end;
|
|
end; //else no idea, check var
|
|
end;
|
|
end; //not an address specifier
|
|
|
|
if valuetype=2 then
|
|
begin
|
|
if ReadProcessMemory(processhandle, pointer(tempaddress), @tempbuf[0], 16, actualread) then
|
|
begin
|
|
variableType:=FindTypeOfData(tempaddress, @tempbuf[0],16);
|
|
|
|
case variableType of
|
|
vtSingle: ValueType:=3;
|
|
vtDouble: ValueType:=4;
|
|
vtString: ValueType:=5;
|
|
vtUnicodeString: ValueType:=6;
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
if isjumper then
|
|
valuetype:=2; //handle it as a dword
|
|
|
|
value:=0;
|
|
fvalue:=0;
|
|
fvalue2:=0;
|
|
case valuetype of
|
|
0: if readprocessmemory(processhandle,pointer(tempaddress),@value,1,actualread) then ts:=inttohex(value,2);
|
|
1: if readprocessmemory(processhandle,pointer(tempaddress),@value,2,actualread) then ts:=inttohex(value,4);
|
|
2: if readprocessmemory(processhandle,pointer(tempaddress),@value,4,actualread) then
|
|
begin
|
|
|
|
if isjumper and ((value and $ffff)=$25ff) then //it's a jmp [xxxxxxxx] / call [xxxxxx] ...
|
|
begin
|
|
value:=0;
|
|
if readprocessmemory(processhandle,pointer(tempaddress+2),@value,4,actualread) then
|
|
begin
|
|
if is64bit then
|
|
value:=tempaddress+6+value;
|
|
|
|
if readprocessmemory(processhandle,pointer(value),@value,processhandler.Pointersize,actualread) then
|
|
begin
|
|
ts:='->'+symhandler.getNameFromAddress(value,symhandler.showsymbols, symhandler.showmodules,symhandler.showsections, nil,nil,8,false);
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
ts:=symhandler.getNameFromAddress(value,symhandler.showsymbols, symhandler.showmodules,symhandler.showsections,nil,nil,8,false);
|
|
end;
|
|
|
|
|
|
if isjumper then
|
|
begin
|
|
//check if ts is a name or a hexadecimal value
|
|
//if hex, don't use it
|
|
val('$'+ts,j, i);
|
|
if i=0 then
|
|
ts:=''; //zero the string, it's a hexadecimal string
|
|
end;
|
|
|
|
end;
|
|
3: if readprocessmemory(processhandle,pointer(tempaddress),@fvalue,4,actualread) then ts:=format('(float)%.4f',[fvalue]);
|
|
4: if readprocessmemory(processhandle,pointer(tempaddress),@fvalue2,8,actualread) then ts:=format('(double)%.4f',[fvalue2]);
|
|
5:
|
|
begin
|
|
actualread:=0;
|
|
ReadProcessMemory(processhandle, pointer(tempaddress), @tempbuf[0], 128, actualread);
|
|
|
|
tempbuf[127]:=0;
|
|
tempbuf[126]:=ord('.');
|
|
tempbuf[125]:=ord('.');
|
|
tempbuf[124]:=ord('.');
|
|
|
|
if actualread>0 then
|
|
tempbuf[actualread-1]:=0;
|
|
|
|
pc:=@tempbuf[0];
|
|
ts:='"'+ pc+'"';
|
|
end;
|
|
|
|
6:
|
|
begin
|
|
actualread:=0;
|
|
ReadProcessMemory(processhandle, pointer(tempaddress), @tempbuf[0], 128, actualread);
|
|
|
|
tempbuf[127]:=0;
|
|
tempbuf[126]:=0;
|
|
|
|
tempbuf[125]:=0;
|
|
tempbuf[124]:=ord('.');
|
|
tempbuf[123]:=0;
|
|
tempbuf[122]:=ord('.');
|
|
tempbuf[121]:=0;
|
|
tempbuf[120]:=ord('.');
|
|
|
|
if actualread>1 then
|
|
begin
|
|
tempbuf[actualread-1]:=0;
|
|
tempbuf[actualread-2]:=0;
|
|
end;
|
|
|
|
pwc:=@tempbuf[0];
|
|
ts:='""'+ pwc+'""';
|
|
end;
|
|
end;
|
|
|
|
if ts<>'' then
|
|
ts:='['+ts+']';
|
|
end
|
|
else
|
|
begin
|
|
//tempaddress doesn't seem to be an address
|
|
variableType:=FindTypeOfData(0, @tempaddress,processhandler.pointersize);
|
|
if variableType=vtsingle then
|
|
ts:=format('(float)%.4f',[psingle(@tempaddress)^]);
|
|
end;
|
|
|
|
end;
|
|
except
|
|
end;
|
|
special:=ts;
|
|
|
|
end else special:='';
|
|
end;
|
|
|
|
function TDisAssembler.inttohexs_withoutsymbols(value:ptrUint;chars: integer; signed: boolean=false; signedsize: integer=0):string;
|
|
begin
|
|
if chars=2 then
|
|
begin
|
|
signed:=true;
|
|
signedsize:=2;
|
|
end;
|
|
|
|
if signed then
|
|
begin
|
|
case signedsize of
|
|
2:
|
|
begin
|
|
if Shortint(value)<0 then
|
|
result:=colorhex+'-'+sysutils.IntToHex(-Shortint(value),chars)+endcolor
|
|
else
|
|
result:=colorhex+sysutils.IntToHex(Shortint(value),chars)+endcolor;
|
|
end;
|
|
|
|
4:
|
|
begin
|
|
if Smallint(value)<0 then
|
|
result:=colorhex+'-'+sysutils.IntToHex(-Smallint(value),chars)+endcolor
|
|
else
|
|
result:=colorhex+sysutils.IntToHex(Smallint(value),chars)+endcolor;
|
|
end;
|
|
|
|
8:
|
|
begin
|
|
if Longint(value)<0 then
|
|
result:=colorhex+'-'+sysutils.IntToHex(-Longint(value),chars)+endcolor
|
|
else
|
|
result:=colorhex+sysutils.IntToHex(Longint(value),chars)+endcolor;
|
|
end;
|
|
|
|
else result:=colorhex+sysutils.IntToHex(value,chars)+endcolor;
|
|
end;
|
|
end
|
|
else
|
|
result:=colorhex+sysutils.IntToHex(value,chars)+endcolor;
|
|
end;
|
|
|
|
function TDisAssembler.inttohexs_withsymbols(value:ptrUint;chars: integer; signed: boolean=false; signedsize: integer=0):string;
|
|
var found: boolean;
|
|
b: byte;
|
|
w: word;
|
|
d: dword;
|
|
i: integer;
|
|
begin
|
|
if (showsymbols or showmodules or showsections) and (chars>=8) then
|
|
begin
|
|
found:=false;
|
|
result:=symhandler.getNameFromAddress(value,showsymbols, showmodules, showsections, nil, @found,chars, false);
|
|
|
|
//when found, and the symbol contains a space or comma, put the symbolname in quotes
|
|
|
|
if found and ((pos(' ', result)>0) or (pos(',', result)>0)) then
|
|
begin
|
|
for i:=length(result) downto 1 do
|
|
begin
|
|
if (result[i] in ['-','+']) or (i=1) then
|
|
begin
|
|
if i>1 then
|
|
result:='"'+copy(result, 1, i-1)+'"'+copy(result, i, length(result))
|
|
else
|
|
result:='"'+result+'"';
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if syntaxhighlighting then
|
|
begin
|
|
if not found then
|
|
result:=colorhex+result+endcolor
|
|
else
|
|
result:=colorsymbol+result+endcolor;
|
|
end;
|
|
end
|
|
else
|
|
result:=inttohexs_withoutsymbols(value, chars, signed, signedsize);
|
|
|
|
end;
|
|
|
|
|
|
procedure TDisAssembler.setSyntaxHighlighting(state: boolean);
|
|
begin
|
|
fsyntaxhighlighting:=state;
|
|
if state then
|
|
begin
|
|
endcolor:='{N}';
|
|
colorhex:='{H}';
|
|
colorreg:='{R}';
|
|
colorsymbol:='{S}';
|
|
end
|
|
else
|
|
begin
|
|
//no color codes
|
|
endcolor:='';
|
|
colorhex:='';
|
|
colorreg:='';
|
|
colorsymbol:='';
|
|
end;
|
|
end;
|
|
|
|
|
|
constructor TDisassembler.create;
|
|
begin
|
|
// cs:=TCriticalSection.Create;
|
|
end;
|
|
|
|
destructor TDisassembler.destroy;
|
|
begin
|
|
// freeandnil(cs);
|
|
if self=visibleDisassembler then
|
|
visibleDisassembler:=nil;
|
|
|
|
if self=defaultDisassembler then
|
|
defaultDisassembler:=nil;
|
|
|
|
inherited destroy;
|
|
end;
|
|
|
|
|
|
initialization
|
|
defaultDisassembler:=TDisassembler.create;
|
|
defaultDisassembler.isdefault:=true;
|
|
defaultDisassembler.syntaxhighlighting:=false;
|
|
|
|
visibleDisassembler:=TDisassembler.Create;
|
|
visibleDisassembler.syntaxhighlighting:=true;
|
|
|
|
finalization
|
|
|
|
if visibleDisassembler<>nil then
|
|
freeandnil(visibleDisassembler);
|
|
|
|
if defaultDisassembler<>nil then
|
|
freeandnil(defaultDisassembler);
|
|
|
|
end.
|
|
|
|
|
|
|