unit disassembler;

interface

uses
  windows, imagehlp, sysutils;

//translation: There is no fucking way I change the descriptions to resource strings
//if you're bored, go do this
type
  qword = UInt64;

  Pqword = ^qword;

type
  Tprefix = set of byte;

type
  TMemory = array[0..23] of byte;

type
  TIntToHexS = function(address: UINT_PTR; chars: integer; signed: boolean = false; signedsize: integer = 0): string of object;

const
  BIT_REX_W = 8; //1000

const
  BIT_REX_R = 4;

const
  BIT_REX_X = 2;

const
  BIT_REX_B = 1;

type
  TDisAssemblerValueType = (dvtNone = 0, dvtAddress = 1, dvtValue = 2);

  TLastDisassembleData = record
    address: UINT_PTR;
    prefix: string;
    prefixsize: integer;
    opcode: string; //and sadly undone because I want to allow the user to change the string... pchar; //replaced string with pchar so it now only contains a pointer. Faster. string; //the result without bytes
    parameters: string;
    description: string;
    Bytes: array of byte;
    SeperatorCount: integer;
    Seperators: array[0..5] of integer; //an index in the byte array describing the seperators (prefix/instruction/modrm/sib/extra)
    modrmValueType: TDisAssemblerValueType;
    modrmValue: UINT_PTR;
    parameterValueType: TDisAssemblerValueType;
    parameterValue: UINT_PTR;
  //  ValueType: TValueType; //if it's not unknown the value type will say what type of value it is (e.g for the FP types)

    datasize: integer;
//    datatype:
    hasSib: boolean;
    sibIndex: integer;
    sibScaler: integer;
    isjump: boolean; //set for anything that can change eip/rip
    iscall: boolean; //set if it's a call
    isret: boolean; //set if it's a ret
    isconditionaljump: boolean; //set if it's only effective when an conditon is met
  end;

  TDisassembleEvent = function(sender: TObject; address: UINT_PTR; var ldd: TLastDisassembleData; var output: string; var description: string): boolean of object;

  TDisassembler = class
  private
    pointersize: Integer;
    inttohexs: TIntToHexS;
    RexPrefix: byte;
    riprelative: boolean;
    colorhex: string;
    colorreg: string;
    colorsymbol: string;
    endcolor: string;
    fsyntaxhighlighting: boolean;
    fOnDisassembleOverride: TDisassembleEvent;
    function SIB(memory: TMemory; sibbyte: integer; var last: dword): string;
    function MODRM(memory: TMemory; prefix: TPrefix; modrmbyte: integer; inst: integer; out last: dword): string; overload;
    function MODRM(memory: TMemory; prefix: TPrefix; modrmbyte: integer; inst: integer; out last: dword; opperandsize: integer): string; overload;
    function MODRM2(memory: TMemory; prefix: TPrefix; modrmbyte: integer; inst: integer; out last: dword; opperandsize: integer = 0): 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 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 mm(bt: byte): string;
    function sreg(bt: byte): string;
    function cr(bt: byte): string;
    function dr(bt: byte): string;
    function getsegmentoverride(prefix: TPrefix): string;
    function inttohexs_withoutsymbols(value: UINT_PTR; chars: integer; signed: boolean = false; signedsize: integer = 0): string;
    procedure setSyntaxHighlighting(state: boolean);
  public
    isdefault: boolean;
    showmodules: boolean;
    dataOnly: boolean;
    is64bit: boolean;
    LastDisassembleData: TLastDisassembleData;
    function disassemble(var offset: UINT_PTR; var description: string): string;
    function getLastBytestring: string;
    constructor Create(isX64: Boolean = False);
    property syntaxhighlighting: boolean read fsyntaxhighlighting write setSyntaxHighlighting;
    property OnDisassembleOverride: TDisassembleEvent read fOnDisassembleOverride write fOnDisassembleOverride;
  end;

function getbit(bitnr: integer; bt: qword): integer; inline;

function StrToQWordEx(s: string): qword;

function isAddress(address: UInt_Ptr): boolean;

var
  processhandle: THandle = Thandle(-1);

implementation

uses
  StrUtils;

function getbit(bitnr: integer; bt: qword): integer;
begin
  result := (bt shr bitnr) and 1;
end;

function StrToQWordEx(s: string): qword;
begin
  s := trim(s);
  if s[1] = '-' then
    result := StrToInt64(s)
  else
    result := StrToUInt64(s);
end;

function isAddress(address: UInt_Ptr): boolean;
var
  mbi: TMemoryBasicInformation;
begin
  result := false;
  if VirtualQueryEx(processhandle, pointer(address), mbi, sizeof(mbi)) > 0 then
    result := (mbi.State = MEM_COMMIT); // and (mbi.AllocationProtect<>PAGE_NOACCESS);
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';
  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
  case bt of
    0:
      if rexprefix = $41 then
        result := 'r8b'
      else
        result := 'al';
    1:
      if rexprefix = $41 then
        result := 'r9b'
      else
        result := 'cl';
    2:
      if rexprefix = $41 then
        result := 'r10b'
      else
        result := 'dl';
    3:
      if rexprefix = $41 then
        result := 'r11b'
      else
        result := 'bl';
    4:
      if rexprefix = $41 then
        result := 'r12b'
      else if rexprefix = 0 then
        result := 'ah'
      else
        result := 'spl';
    5:
      if rexprefix = $41 then
        result := 'r13b'
      else if rexprefix = 0 then
        result := 'ch'
      else
        result := 'bpl';
    6:
      if rexprefix = $41 then
        result := 'r14b'
      else if rexprefix = 0 then
        result := 'dh'
      else
        result := 'sil';
    7:
      if rexprefix = $41 then
        result := 'r15b'
      else if rexprefix = 0 then
        result := 'bh'
      else
        result := 'dil';
    8:
      result := 'r8l';
    9:
      result := 'r9l';
    10:
      result := 'r10l';
    11:
      result := 'r11l';
    12:
      result := 'r12l';
    13:
      result := 'r13l';
    14:
      result := 'r14l';
    15:
      result := 'r15l';
  end;

  result := colorreg + result + endcolor;
end;

function TDisassembler.rd16(bt: byte): string;
begin
  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';
  end;
  result := colorreg + result + endcolor;
end;

function TDisassembler.r8(bt: byte): string;
begin

  case getreg(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 := 'r8l';
    9:
      result := 'r9l';
    10:
      result := 'r10l';
    11:
      result := 'r11l';
    12:
      result := 'r12l';
    13:
      result := 'r13l';
    14:
      result := 'r14l';
    15:
      result := 'r15l';
  end;
  result := colorreg + result + endcolor;
end;

function TDisassembler.r16(bt: byte): string;
begin
  case getreg(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';
  end;
  result := colorreg + result + endcolor;
end;

function TDisassembler.r32(bt: byte): string;
begin
  case getreg(bt) of
    0:
      if rex_w then
        result := 'rax'
      else
        result := 'eax';
    1:
      if rex_w then
        result := 'rcx'
      else
        result := 'ecx';
    2:
      if rex_w then
        result := 'rdx'
      else
        result := 'edx';
    3:
      if rex_w then
        result := 'rbx'
      else
        result := 'ebx';
    4:
      if rex_w then
        result := 'rsp'
      else
        result := 'esp';
    5:
      if rex_w then
        result := 'rbp'
      else
        result := 'ebp';
    6:
      if rex_w then
        result := 'rsi'
      else
        result := 'esi';
    7:
      if rex_w then
        result := 'rdi'
      else
        result := 'edi';
    8:
      if rex_w then
        result := 'r8'
      else
        result := 'r8d';
    9:
      if rex_w then
        result := 'r9'
      else
        result := 'r9d';
    10:
      if rex_w then
        result := 'r10'
      else
        result := 'r10d';
    11:
      if rex_w then
        result := 'r11'
      else
        result := 'r11d';
    12:
      if rex_w then
        result := 'r12'
      else
        result := 'r12d';
    13:
      if rex_w then
        result := 'r13'
      else
        result := 'r13d';
    14:
      if rex_w then
        result := 'r14'
      else
        result := 'r14d';
    15:
      if rex_w then
        result := 'r15'
      else
        result := 'r15d';
  end;
  result := colorreg + result + endcolor;
end;

function TDisassembler.r64(bt: byte): string;
begin
  case getreg(bt) 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;
  result := colorreg + result + endcolor;
end;

function TDisassembler.xmm(bt: byte): string;
begin
  case getreg(bt) 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;
  result := colorreg + result + endcolor;
end;

function TDisassembler.mm(bt: byte): string;
begin
  case getreg(bt) 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;
  result := colorreg + result + endcolor;
end;

function TDisassembler.sreg(bt: byte): string;
begin
  case getreg(bt) 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;
  result := colorreg + result + endcolor;
end;

function TDisassembler.CR(bt: byte): string;
begin
  case getreg(bt) 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;
  result := colorreg + result + endcolor;
end;

function TDisassembler.DR(bt: byte): string;
begin
  case getreg(bt) 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 excist, 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;
  result := colorreg + result + endcolor;
end;

function TDisassembler.getsegmentoverride(prefix: TPrefix): string;
begin
  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 rex_b and (not ((((bt shl 6) and 3) <> 3) and ((bt and 7) = 4))) then //if this instruction does NOT have a SIB byte, only then apply the rex_B bit
    result := result or 8; //extend the RM field
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;
begin
  result := (RexPrefix and BIT_REX_B) = BIT_REX_B;
end;

function TDisassembler.Rex_X: boolean;
begin
  result := (RexPrefix and BIT_REX_X) = BIT_REX_X;
end;

function TDisassembler.Rex_R: boolean;
begin
  result := (RexPrefix and BIT_REX_R) = BIT_REX_R;
end;

function TDisassembler.Rex_W: boolean;
begin
  result := (RexPrefix and BIT_REX_W) = BIT_REX_W;
end;

function TDisassembler.MODRM2(memory: TMemory; prefix: TPrefix; modrmbyte: integer; inst: integer; out last: dword; opperandsize: integer = 0): string;
var
  dwordptr: ^dword;
  regprefix: char;
begin
  if is64bit then
    regprefix := 'r'
  else
    regprefix := 'e';

  LastDisassembleData.Seperators[LastDisassembleData.SeperatorCount] := modrmbyte;
  inc(LastDisassembleData.SeperatorCount);

  dwordptr := @memory[modrmbyte + 1];
  last := modrmbyte + 1;

  LastDisassembleData.Seperators[LastDisassembleData.SeperatorCount] := last;
  inc(LastDisassembleData.SeperatorCount);

  if $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
          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) + '],';
              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^;

                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;

        end;
      1:
        begin
          if getrm(memory[modrmbyte]) <> 4 then
          begin
            LastDisassembleData.modrmValueType := dvtValue;
            LastDisassembleData.modrmValue := 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(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(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(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(shortint(memory[modrmbyte + 1]), 2) + '],';

            4:
              begin
                result := getsegmentoverride(prefix) + '[' + sib(memory, modrmbyte + 1, last) + '],';
                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(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(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(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(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(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(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(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(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(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(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(shortint(memory[modrmbyte + 1]), 2, true, 2) + '],';

          end;

          inc(last);
        end;

      2:
        begin
          if getrm(memory[modrmbyte]) <> 4 then
          begin
            LastDisassembleData.modrmValueType := dvtValue;
            LastDisassembleData.modrmValue := 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) + '],';
                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);

        end;

      3:
        begin
          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:
                  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:
                  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:
                  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:
                  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:
                  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:
                  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:
                  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:
                  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 := 'r8l';
                3:
                  result := 'mm8';
                4:
                  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 := 'r9l';
                3:
                  result := 'mm9';
                4:
                  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 := 'r10l';
                3:
                  result := 'mm10';
                4:
                  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 := 'r11l';
                3:
                  result := 'mm11';
                4:
                  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 := 'r12l';
                3:
                  result := 'mm12';
                4:
                  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 := 'r13l';
                3:
                  result := 'mm13';
                4:
                  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 := 'r14l';
                3:
                  result := 'mm14';
                4:
                  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 := 'r15l';
                3:
                  result := 'mm15';
                4:
                  result := 'xmm15';
              end;
          end;

          result := colorreg + result + endcolor + ',';
        end;
    end;

  end;

  if last <> (Dword(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;

  if last > 15 then
    messagebox(0, pchar(result), nil, 0);
end;

function TDisassembler.MODRM(memory: TMemory; prefix: TPrefix; modrmbyte: integer; inst: integer; out last: dword): string;
begin
  case inst of
    0:
      LastDisassembleData.datasize := 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);
end;

function TDisassembler.MODRM(memory: TMemory; prefix: TPrefix; modrmbyte: integer; inst: integer; out last: dword; opperandsize: integer): string;
begin
  result := modrm2(memory, prefix, modrmbyte, inst, last, opperandsize);
  if (length(result) > 0) and (result[1] = '[') then
  begin
    LastDisassembleData.datasize := pointersize;
    case opperandsize of
      8:
        begin
          result := 'byte ptr ' + result;
          LastDisassembleData.datasize := 1;
        end;

      16:
        begin
          result := 'word ptr ' + result;
          LastDisassembleData.datasize := 2;
        end;

      32:
        begin
          result := 'dword ptr ' + result;
          LastDisassembleData.datasize := 4;
        end;

      64:
        begin
          result := 'qword ptr ' + result;
          LastDisassembleData.datasize := 8;
        end;

      80:
        begin
          result := 'tword ptr ' + result;
          LastDisassembleData.datasize := 10;
        end;

      128:
        begin
          result := 'dqword ptr ' + result;
          LastDisassembleData.datasize := 16;
        end;
    end;
  end;
end;

function TDisassembler.SIB(memory: TMemory; sibbyte: integer; var last: dword): 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;

  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';
  end;

  if is64bit then
  begin
    if indexstring <> '' then
      indexstring[1] := 'r'; //quick replace

  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 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 := 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 := 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 := 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;

function TDisassembler.disassemble(var offset: UINT_PTR; var description: string): string;
var
  memory: TMemory;
  actualread: UINT_PTR;
  startoffset: UINT_PTR;
  tempresult: string;
  wordptr: ^word;
  dwordptr: ^dword;
  i, j: integer;
  prefix: TPrefix;
  prefix2: TPrefix;
  isprefix: boolean;
  last: dword;
  tempaddress: UINT_PTR;
  prefixsize: integer;
begin

  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.isconditionaljump := false;
  lastdisassembledata.modrmValueType := dvtNone;
  lastdisassembledata.parameterValueType := dvtNone;
  LastDisassembleData.hasSib := false;
  LastDisassembleData.datasize := 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;

  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;
  actualread := 0;
  readprocessmemory(processhandle, pointer(offset), @memory, 24, actualread);

  if actualread > 0 then
  begin
    //I HATE THESE...   (I propably will not add them all, but I'll see how far I get)

    while isprefix do
    begin
      inc(offset);
      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]];
        readprocessmemory(processhandle, pointer(offset), addr(memory), 24, actualread);
      end
      else
        isprefix := false;
    end;

    if $F0 in prefix2 then
      tempresult := 'lock ';
    if $F2 in prefix2 then
      tempresult := tempresult + 'repne ';
    if $f3 in prefix2 then
      tempresult := tempresult + 'repe ';

    LastDisassembleData.prefix := tempresult;

    RexPrefix := 0;
    if is64bit then
    begin
      if memory[0] in [$40..$4f] then //does it start with a rex prefix ?
      begin
        setlength(LastDisassembleData.bytes, length(LastDisassembleData.bytes) + 1);
        LastDisassembleData.bytes[length(LastDisassembleData.bytes) - 1] := memory[0];

        RexPrefix := memory[0];
        if not dataonly then
          result := result + inttohexs(RexPrefix, 2) + ' ';

        inc(offset);
        inc(startoffset);
        prefix2 := prefix2 + [RexPrefix];
        MoveMemory(@memory[0], @memory[1], 23);
      end;
    end;

    prefixsize := length(LastDisassembleData.bytes);
    LastDisassembleData.prefixsize := prefixsize;

    case memory[0] of  //opcode
      $00:
        begin
          description := 'Add';

          lastdisassembledata.opcode := 'add';
          lastdisassembledata.parameters := modrm(memory, prefix2, 1, 2, last) + r8(memory[1]);

          inc(offset, last - 1);
        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);

          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)
          else
            LastDisassembleData.parameters := r32(memory[1]) + ',' + MODRM(memory, prefix2, 1, 0, last);

          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(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);
          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)
          else
            lastdisassembledata.parameters := r32(memory[1]) + ',' + modrm(memory, prefix2, 1, 0, last);

          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(lastdisassembledata.parametervalue, 4);
              description := description + ' (sign-extended)';
            end
            else
              lastdisassembledata.parameters := colorreg + 'eax' + endcolor + ',' + inttohexs(lastdisassembledata.parametervalue, 4);

            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
          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;

//the following 2 were made up by me.
                else
                  begin
                    lastdisassembledata.opcode := 'db';
                    LastDisassembleData.parameters := inttohex(memory[0], 2);
                    description := 'not specified by the intel documentation';
                  end;

                end;

              end;

            $01:
              begin
                case getreg(memory[2]) of
                  0:
                    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;

                      else
                        begin
                          description := 'store global descriptor table register';
                          lastdisassembledata.opcode := 'sgdt';
                          lastdisassembledata.parameters := modrm(memory, prefix2, 2, 0, last);
                          inc(offset, last - 1);
                        end;

                      end;

                    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
                      if (getmod(memory[2]) = 3) and (getrm(memory[2]) = 0) then //swapgs
                      begin
                        description := 'swap GS';
                        lastdisassembledata.opcode := 'swapgs';
                        modrm(memory, prefix2, 2, 0, last);
                      end
                      else
                      begin
                        description := 'invalidate tlb entry';
                        lastdisassembledata.opcode := 'invplg';
                        lastdisassembledata.parameters := modrm(memory, prefix2, 2, 0, last);
                      end;
                      inc(offset, last - 1);

                    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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 2, last);

                inc(offset, last - 1);
              end;

            $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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 2, last);

                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 := 'incd';
                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

                  //    end;


            $10:
              begin
                if $f2 in prefix2 then
                begin
                  description := 'move scalar double-fp';
                  lastdisassembledata.opcode := 'movsd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  inc(offset, last - 1);
                end
                else if $f3 in prefix2 then
                begin
                  description := 'move scalar single-fp';
                  lastdisassembledata.opcode := 'movss';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  inc(offset, last - 1);
                end
                else if $66 in prefix2 then
                begin
                  description := 'move unaligned packed double-fp';
                  lastdisassembledata.opcode := 'movupd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  inc(offset, last - 1);
                end
                else
                begin
                  description := 'move unaligned four packed single-fp';
                  lastdisassembledata.opcode := 'movups';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  inc(offset, last - 1);
                end;
              end;

            $11:
              begin
                if $f2 in prefix2 then
                begin
                  description := 'move scalar double-fp';
                  lastdisassembledata.opcode := 'movsd';
                  lastdisassembledata.parameters := modrm(memory, prefix2, 2, 4, last) + xmm(memory[2]);
                  inc(offset, last - 1);
                end
                else if $f3 in prefix2 then
                begin
                  description := 'move scalar single-fp';
                  lastdisassembledata.opcode := 'movss';
                  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 unaligned packed double-fp';
                  lastdisassembledata.opcode := 'movupd';
                  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';
                  lastdisassembledata.opcode := 'movups';
                  lastdisassembledata.parameters := modrm(memory, prefix2, 2, 4, last) + xmm(memory[2]);
                  inc(offset, last - 1);
                end;

              end;

            $12:
              begin
                if $66 in prefix2 then
                begin
                  description := 'move low packed double-precision floating-point value';
                  lastdisassembledata.opcode := 'movlpd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  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';

                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  inc(offset, last - 1);
                end;
              end;

            $13:
              begin
                if $66 in prefix2 then
                begin
                  description := 'move low packed double-fp';
                  lastdisassembledata.opcode := 'movlpd';
                  lastdisassembledata.parameters := modrm(memory, prefix2, 2, 4, last) + xmm(memory[2]);
                  inc(offset, last - 1);
                end
                else
                begin
                  description := 'move low packed single-fp';
                  lastdisassembledata.opcode := 'movlps';
                  lastdisassembledata.parameters := modrm(memory, prefix2, 2, 4, last) + xmm(memory[2]);
                  inc(offset, last - 1);
                end;
              end;

            $14:
              begin
                if $66 in prefix2 then
                begin
                  description := 'unpack low packed single-fp';
                  lastdisassembledata.opcode := 'unpcklpd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  inc(offset, last - 1);
                end
                else
                begin
                  description := 'unpack low packed single-fp';
                  lastdisassembledata.opcode := 'unpcklps';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  inc(offset, last - 1);
                end;
              end;

            $15:
              begin
                if $66 in prefix2 then
                begin
                  description := 'unpack and interleave high packed double-fp';
                  lastdisassembledata.opcode := 'unpckhpd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  inc(offset, last - 1);
                end
                else
                begin
                  description := 'unpack high packed single-fp';
                  lastdisassembledata.opcode := 'unpckhps';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  inc(offset, last - 1);
                end;
              end;

            $16:
              begin
                if $66 in prefix2 then
                begin
                  description := 'move high packed double-precision floating-point value';
                  lastdisassembledata.opcode := 'movhpd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  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';

                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  inc(offset, last - 1);
                end;
              end;

            $17:
              begin
                if $66 in prefix2 then
                begin
                  description := 'move high packed double-precision floating-point value';
                  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';
                  lastdisassembledata.opcode := 'movhps';
                  lastdisassembledata.parameters := modrm(memory, prefix2, 2, 4, last) + xmm(memory[2]);
                  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';
                      lastdisassembledata.parameters := modrm(memory, prefix2, 2, 0, last);
                      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);
                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);
                inc(offset, last - 1);
              end;

            $28:
              begin
                if $66 in prefix2 then
                begin
                  description := 'move aligned packed fouble-fp values';
                  lastdisassembledata.opcode := 'movapd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  inc(offset, last - 1);
                end
                else
                begin
                  description := 'move aligned four packed single-fp';
                  lastdisassembledata.opcode := 'movaps';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  inc(offset, last - 1);
                end;
              end;

            $29:
              begin
                if $66 in prefix2 then
                begin
                  description := 'move aligned packed fouble-fp values';
                  lastdisassembledata.opcode := 'movapd';
                  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';
                  lastdisassembledata.opcode := 'movaps';
                  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';
                  lastdisassembledata.opcode := 'cvtsi2sd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);

                  inc(offset, last - 1);
                end
                else if $f3 in prefix2 then
                begin

                  description := 'scalar signed int32 to single-fp conversion';
                  lastdisassembledata.opcode := 'cvtsi2ss';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);

                  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);

                    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);

                    inc(offset, last - 1);
                  end;
                end;
              end;

            $2b:
              begin
                if $66 in prefix2 then
                begin
                  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
                  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';
                  lastdisassembledata.opcode := 'cvttsd2si';
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  inc(offset, last - 1);
                end
                else if $f3 in prefix2 then
                begin
                  description := 'scalar single-fp to signed int32 conversion (truncate)';
                  lastdisassembledata.opcode := 'cvttss2si';
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  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);
                    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);
                    inc(offset, last - 1);
                  end;
                end;
              end;

            $2d:
              begin
                if $f2 in prefix2 then
                begin
                  description := 'convert scalar double-precision floating-point value to doubleword integer';
                  lastdisassembledata.opcode := 'cvtsd2si';
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  inc(offset, last - 1);
                end
                else if $f3 in prefix2 then
                begin
                  description := 'scalar single-fp to signed int32 conversion';
                  lastdisassembledata.opcode := 'cvtss2si';
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  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);
                    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);
                    inc(offset, last - 1);
                  end;
                end;
              end;

            $2e:
              begin
                if $66 in prefix2 then
                begin
                  description := 'unordered scalar double-fp compare and set eflags';
                  lastdisassembledata.opcode := 'ucomisd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  inc(offset, last - 1);
                end
                else
                begin
                  description := 'unordered scalar single-fp compare and set eflags';
                  lastdisassembledata.opcode := 'ucomiss';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  inc(offset, last - 1);
                end;
              end;

            $2f:
              begin
                if $66 in prefix2 then
                begin
                  description := 'compare scalar ordered double-precision floating point values and set eflags';
                  lastdisassembledata.opcode := 'comisd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  inc(offset, last - 1);
                end
                else
                begin
                  description := 'scalar ordered single-fp compare and set eflags';
                  lastdisassembledata.opcode := 'comiss';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  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;

            $38:
              begin
                case memory[2] of
                  $40:
                    begin
                      if $66 in prefix2 then
                      begin
                        description := 'Multiply Packed Signed Dword Integers and Store Low Result';
                        LastDisassembleData.opcode := 'pmulld';
                        lastdisassembledata.parameters := xmm(memory[3]) + ',' + modrm(memory, prefix2, 3, 4, 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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);
                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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);

                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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);

                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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);

                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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);

                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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);

                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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);

                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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);

                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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);

                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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);

                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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);

                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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);

                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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);

                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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);

                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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);

                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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);

                inc(offset, last - 1);
              end;

            $50:
              begin
                if $66 in prefix2 then
                begin
                  lastdisassembledata.opcode := 'movmskpd';
                  lastdisassembledata.parameters := modrm(memory, prefix2, 2, 0, last) + xmm(memory[2]);
                  description := 'extract packed double-precision floating-point sign mask';
                  inc(offset, last - 1);
                end
                else
                begin
                  lastdisassembledata.opcode := 'movmskps';
                  lastdisassembledata.parameters := modrm(memory, prefix2, 2, 0, last) + xmm(memory[2]);
                  description := 'move mask to integer';
                  inc(offset, last - 1);
                end;
              end;

            $51:
              begin
                if $f2 in prefix2 then
                begin
                  lastdisassembledata.opcode := 'sqrtsd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  description := 'scalar double-fp square root';
                  inc(offset, last - 1);
                end
                else if $f3 in prefix2 then
                begin

                  lastdisassembledata.opcode := 'sqrtss';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  description := 'scalar single-fp square root';
                  inc(offset, last - 1);
                end
                else if $66 in prefix2 then
                begin
                  lastdisassembledata.opcode := 'sqrtpd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  description := 'packed double-fp square root';

                  inc(offset, last - 1);
                end
                else
                begin
                  lastdisassembledata.opcode := 'sqrtps';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  description := 'packed single-fp square root';

                  inc(offset, last - 1);
                end;
              end;

            $52:
              begin
                if $f3 in prefix2 then
                begin
                  lastdisassembledata.opcode := 'rsqrtss';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  description := 'packed single-fp square root reciprocal';
                  inc(offset, last - 1);
                end
                else
                begin
                  lastdisassembledata.opcode := 'rsqrtps';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  description := 'scalar single-fp square root reciprocal';
                  inc(offset, last - 1);
                end;
              end;

            $53:
              begin
                if $f3 in prefix2 then
                begin
                  lastdisassembledata.opcode := 'rcpss';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  description := 'scalar single-fp reciprocal';
                  inc(offset, last - 1);
                end
                else
                begin
                  lastdisassembledata.opcode := 'rcpps';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  description := 'packed single-fp reciprocal';
                  inc(offset, last - 1);
                end;
              end;

            $54:
              begin
                if $66 in prefix2 then
                begin
                  lastdisassembledata.opcode := 'andpd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  description := 'bit-wise logical and of xmm2/m128 and xmm1';
                  inc(offset, last - 1);
                end
                else
                begin
                  lastdisassembledata.opcode := 'andps';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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';
                  lastdisassembledata.opcode := 'andnpd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  inc(offset, last - 1);
                end
                else
                begin
                  description := 'bit-wise logical and not for single-fp';
                  lastdisassembledata.opcode := 'andnps';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  inc(offset, last - 1);
                end;
              end;

            $56:
              begin
                if $66 in prefix2 then
                begin
                  description := 'bit-wise logical or of double-fp';
                  lastdisassembledata.opcode := 'orpd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  inc(offset, last - 1);
                end
                else
                begin
                  description := 'bit-wise logical or for single-fp';
                  lastdisassembledata.opcode := 'orps';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  inc(offset, last - 1);
                end;
              end;

            $57:
              begin
                if $66 in prefix2 then
                begin
                  description := 'bit-wise logical xor for double-fp data';
                  lastdisassembledata.opcode := 'xorpd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  inc(offset, last - 1);
                end
                else
                begin
                  description := 'bit-wise logical xor for single-fp data';
                  lastdisassembledata.opcode := 'xorps';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  inc(offset, last - 1);
                end;
              end;

            $58:
              begin
                if $f2 in prefix2 then
                begin
                          //delete the repne from the tempresult


                  lastdisassembledata.opcode := 'addsd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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


                  lastdisassembledata.opcode := 'addss';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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
                    lastdisassembledata.opcode := 'addpd';
                    lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                    description := 'add packed double-precision floating-point values from xmm2/mem to xmm1';
                    inc(offset, last - 1);
                  end
                  else
                  begin
                    lastdisassembledata.opcode := 'addps';
                    lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                    description := 'add packed sp fp numbers from xmm2/mem to xmm1';
                    inc(offset, last - 1);
                  end;
                end;
              end;

            $59:
              begin
                if $f2 in prefix2 then
                begin

                  lastdisassembledata.opcode := 'mulsd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  description := 'scalar double-fp multiply';
                  inc(offset, last - 1);
                end
                else if $f3 in prefix2 then
                begin

                  lastdisassembledata.opcode := 'mulss';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  description := 'scalar single-fp multiply';
                  inc(offset, last - 1);
                end
                else if $66 in prefix2 then
                begin
                  lastdisassembledata.opcode := 'mulpd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  description := 'packed double-fp multiply';
                  inc(offset, last - 1);
                end
                else
                begin
                  lastdisassembledata.opcode := 'mulps';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  description := 'packed single-fp multiply';
                  inc(offset, last - 1);
                end;
              end;

            $5a:
              begin
                if $f2 in prefix2 then
                begin

                  lastdisassembledata.opcode := 'cvtsd2ss';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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

                  lastdisassembledata.opcode := 'cvtss2sd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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
                    lastdisassembledata.opcode := 'cvtpd2ps';
                    lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                    description := 'convert packed double precision fp values to packed single precision fp values';
                    inc(offset, last - 1);
                  end
                  else
                  begin
                    lastdisassembledata.opcode := 'cvtps2pd';
                    lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                    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.opcode := 'cvtps2dq';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  description := 'convert ps-precision fpoint values to packed dword''s ';
                  inc(offset, last - 1);
                end
                else
                begin
                  lastdisassembledata.opcode := 'cvtdq2ps';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  description := 'convert packed dword''s to ps-precision fpoint values';
                  inc(offset, last - 1);
                end;
              end;

            $5c:
              begin
                if $f2 in prefix2 then
                begin
                  lastdisassembledata.opcode := 'subsd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  description := 'scalar double-fp subtract';
                  inc(offset, last - 1);
                end
                else if $f3 in prefix2 then
                begin
                  lastdisassembledata.opcode := 'subss';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  description := 'scalar single-fp subtract';
                  inc(offset, last - 1);
                end
                else if $66 in prefix2 then
                begin
                  lastdisassembledata.opcode := 'subpd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  description := 'packed double-fp subtract';
                  inc(offset, last - 1);
                end
                else
                begin
                  lastdisassembledata.opcode := 'subps';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  description := 'packed single-fp subtract';
                  inc(offset, last - 1);
                end;
              end;

            $5d:
              begin
                if $f2 in prefix2 then
                begin

                  lastdisassembledata.opcode := 'minsd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  description := 'scalar single-fp minimum';
                  inc(offset, last - 1);
                end
                else if $f3 in prefix2 then
                begin

                  lastdisassembledata.opcode := 'minss';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  description := 'scalar single-fp minimum';
                  inc(offset, last - 1);
                end
                else
                begin
                  if $66 in prefix2 then
                  begin
                    lastdisassembledata.opcode := 'minpd';
                    lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                    description := 'packed double-fp minimum';
                    inc(offset, last - 1);
                  end
                  else
                  begin
                    lastdisassembledata.opcode := 'minps';
                    lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                    description := 'packed single-fp minimum';
                    inc(offset, last - 1);
                  end;
                end;
              end;

            $5e:
              begin
                if $f2 in prefix2 then
                begin

                  lastdisassembledata.opcode := 'divsd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  description := 'scalar double-precision-fp divide';
                  inc(offset, last - 1);
                end
                else if $f3 in prefix2 then
                begin

                  lastdisassembledata.opcode := 'divss';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  description := 'scalar single-fp divide';
                  inc(offset, last - 1);
                end
                else
                begin
                  if $66 in prefix2 then
                  begin
                    lastdisassembledata.opcode := 'divpd';
                    lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                    description := 'packed double-precision fp divide';
                    inc(offset, last - 1);
                  end
                  else
                  begin
                    lastdisassembledata.opcode := 'divps';
                    lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                    description := 'packed single-fp divide';
                    inc(offset, last - 1);
                  end;
                end;
              end;

            $5f:
              begin
                if $f2 in prefix2 then
                begin

                  description := 'scalar double-fp maximum';
                  lastdisassembledata.opcode := 'maxsd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  inc(offset, last - 1);
                end
                else if $f3 in prefix2 then
                begin

                  description := 'scalar single-fp maximum';
                  lastdisassembledata.opcode := 'maxss';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  inc(offset, last - 1);
                end
                else
                begin
                  if $66 in prefix2 then
                  begin
                    description := 'packed double-fp maximum';
                    lastdisassembledata.opcode := 'maxpd';
                    lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                    inc(offset, last - 1);
                  end
                  else
                  begin
                    description := 'packed single-fp maximum';
                    lastdisassembledata.opcode := 'maxps';
                    lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                    inc(offset, last - 1);
                  end;
                end;
              end;

            $60:
              begin
                if $66 in prefix2 then
                begin
                  description := 'unpack low packed data';
                  lastdisassembledata.opcode := 'punpcklbw';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $61:
              begin
                if $66 in prefix2 then
                begin
                  description := 'unpack low packed data';
                  lastdisassembledata.opcode := 'punpcklwd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $62:
              begin
                if $66 in prefix2 then
                begin
                  description := 'unpack low packed data';
                  lastdisassembledata.opcode := 'punpckldq';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $63:
              begin
                if $66 in prefix2 then
                begin
                  description := 'pack with signed saturation';
                  lastdisassembledata.opcode := 'packsswb';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $64:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed compare for greater than';
                  lastdisassembledata.opcode := 'pcmpgtb';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $65:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed compare for greater than';
                  lastdisassembledata.opcode := 'pcmpgtw';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $66:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed compare for greater than';
                  lastdisassembledata.opcode := 'pcmpgtd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $67:
              begin
                if $66 in prefix2 then
                begin
                  description := 'pack with unsigned saturation';
                  lastdisassembledata.opcode := 'packuswb';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $68:
              begin
                if $66 in prefix2 then
                begin
                  description := 'unpack high packed data';
                  lastdisassembledata.opcode := 'punpckhbw';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  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);
                  inc(offset, last - 1);
                end;
              end;

            $69:
              begin
                if $66 in prefix2 then
                begin
                  description := 'unpack high packed data';
                  lastdisassembledata.opcode := 'punpckhwd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  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);
                  inc(offset, last - 1);
                end;
              end;

            $6a:
              begin
                if $66 in prefix2 then
                begin
                  description := 'unpack high packed data';
                  lastdisassembledata.opcode := 'punpckhdq';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  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);
                  inc(offset, last - 1);
                end;
              end;

            $6b:
              begin
                if $66 in prefix2 then
                begin
                  description := 'pack with signed saturation';
                  lastdisassembledata.opcode := 'packssdw';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  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);
                  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);
                  inc(offset, last - 1);
                end
              end;

            $6e:
              begin
                if rex_w then
                begin
                  description := 'move quadword';
                  lastdisassembledata.opcode := 'movq';
                end
                else
                begin
                  description := 'move doubleword';
                  lastdisassembledata.opcode := 'movd';
                end;

                if $66 in prefix2 then
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last)
                else
                  lastdisassembledata.parameters := mm(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);

                inc(offset, last - 1);
              end;

            $6f:
              begin
                if $f3 in prefix2 then
                begin

                  description := 'move unaligned double quadword';
                  lastdisassembledata.opcode := 'movdqu';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  inc(offset, last - 1);
                end
                else if $66 in prefix2 then
                begin
                  description := 'move aligned double quadword';
                  lastdisassembledata.opcode := 'movdqa';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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';
                  lastdisassembledata.opcode := 'pshuflw';
                  lastdisassembledata.parameters := xmm(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, last);
                end
                else if $f3 in prefix2 then
                begin

                  description := 'shuffle packed high words';
                  lastdisassembledata.opcode := 'pshufhw';
                  lastdisassembledata.parameters := xmm(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, 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);
                  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';
                  lastdisassembledata.opcode := 'pshufw';
                  lastdisassembledata.parameters := mm(memory[2]) + ',' + modrm(memory, prefix2, 2, 3, last);
                  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';
                        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 := 'packed shift right arithmetic';
                        lastdisassembledata.opcode := 'psraw';
                        lastdisassembledata.parameters := xmm(memory[2]) + ',' + inttohexs(memory[3], 2);
                        inc(offset, 3);
                      end
                      else
                      begin
                        description := 'packed shift right arithmetic';
                        lastdisassembledata.opcode := 'psraw';
                        lastdisassembledata.parameters := mm(memory[2]) + ',' + inttohexs(memory[3], 2);
                        inc(offset, 3);
                      end;
                    end;

                  6:
                    begin
                      if $66 in prefix2 then
                      begin
                        description := 'packed shift left logical';
                        lastdisassembledata.opcode := 'psllw';
                        lastdisassembledata.parameters := xmm(memory[2]) + ',' + inttohexs(memory[3], 2);
                        inc(offset, 3);
                      end
                      else
                      begin
                        description := 'packed shift left logical';
                        lastdisassembledata.opcode := 'psllw';
                        lastdisassembledata.parameters := mm(memory[2]) + ',' + inttohexs(memory[3], 2);
                        inc(offset, 3);
                      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';
                        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';
                        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';
                        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';
                        lastdisassembledata.opcode := 'psrlq';
                        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 := 'psrlq';
                        lastdisassembledata.parameters := modrm(memory, prefix2, 2, 3, last);
                        lastdisassembledata.parameters := lastdisassembledata.parameters + inttohexs(memory[last], 2);
                        inc(offset, 3);
                      end;
                    end;

                  3:
                    begin
                      if $66 in prefix2 then
                      begin
                        description := 'shift double quadword right lopgical';
                        lastdisassembledata.opcode := 'psrldq';
                        lastdisassembledata.parameters := modrm(memory, prefix2, 2, 4, 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';
                        lastdisassembledata.opcode := 'psllq';
                        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 := 'psllq';
                        lastdisassembledata.parameters := modrm(memory, prefix2, 2, 3, last);
                        lastdisassembledata.parameters := lastdisassembledata.parameters + inttohexs(memory[last], 2);
                        inc(offset, 3);
                      end;
                    end;

                  7:
                    begin
                      if $66 in prefix2 then
                      begin
                        description := 'shift double quadword left logical';
                        lastdisassembledata.opcode := 'pslldq';
                        lastdisassembledata.parameters := modrm(memory, prefix2, 2, 4, last);
                        lastdisassembledata.parameters := lastdisassembledata.parameters + inttohexs(memory[last], 2);
                        inc(offset, 3);
                      end;
                    end;
                end;
              end;

            $74:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed compare for equal';
                  lastdisassembledata.opcode := 'pcmpeqb';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $75:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed compare for equal';
                  lastdisassembledata.opcode := 'pcmpeqw';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $76:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed compare for equal';
                  lastdisassembledata.opcode := 'pcmpeqd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $77:
              begin
                description := 'empty mmx?state';
                lastdisassembledata.opcode := 'emms';
                inc(offset);
              end;

            $78:
              begin
                description := 'reads a specified vmcs field (32 bits)';
                lastdisassembledata.opcode := 'vmread';
                lastdisassembledata.parameters := modrm(memory, prefix2, 2, 2, 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, 2, last);

                inc(offset, last - 1);
              end;

            $7e:
              begin
                if $f3 in prefix2 then
                begin

                  description := 'move quadword';
                  lastdisassembledata.opcode := 'movq';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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;

                  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';
                  lastdisassembledata.opcode := 'movdqu';
                  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';
                  lastdisassembledata.opcode := 'movdqa';
                  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';
                lastdisassembledata.opcode := 'jo';
                lastdisassembledata.isjump := true;
                lastdisassembledata.isconditionaljump := true;
                inc(offset, 1 + 4);

                lastdisassembledata.parametervaluetype := dvtaddress;
                if is64bit then
                  lastdisassembledata.parametervalue := qword(offset + pint(@memory[2])^)
                else
                  lastdisassembledata.parametervalue := dword(offset + 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';
                lastdisassembledata.opcode := 'jno';
                lastdisassembledata.isjump := true;
                lastdisassembledata.isconditionaljump := true;
                inc(offset, 1 + 4);

                lastdisassembledata.parametervaluetype := dvtaddress;
                if is64bit then
                  lastdisassembledata.parametervalue := qword(offset + pint(@memory[2])^)
                else
                  lastdisassembledata.parametervalue := dword(offset + 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';

                lastdisassembledata.opcode := 'jb';
                lastdisassembledata.isjump := true;
                lastdisassembledata.isconditionaljump := true;
                inc(offset, 1 + 4);

                lastdisassembledata.parametervaluetype := dvtaddress;
                if is64bit then
                  lastdisassembledata.parametervalue := qword(offset + pint(@memory[2])^)
                else
                  lastdisassembledata.parametervalue := dword(offset + 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';
                lastdisassembledata.opcode := 'jae';
                lastdisassembledata.isjump := true;
                lastdisassembledata.isconditionaljump := true;
                inc(offset, 1 + 4);

                lastdisassembledata.parametervaluetype := dvtaddress;
                if is64bit then
                  lastdisassembledata.parametervalue := qword(offset + pint(@memory[2])^)
                else
                  lastdisassembledata.parametervalue := dword(offset + 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';

                lastdisassembledata.opcode := 'je';
                lastdisassembledata.isjump := true;
                lastdisassembledata.isconditionaljump := true;
                inc(offset, 1 + 4);

                lastdisassembledata.parametervaluetype := dvtaddress;
                if is64bit then
                  lastdisassembledata.parametervalue := qword(offset + pint(@memory[2])^)
                else
                  lastdisassembledata.parametervalue := dword(offset + 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';
                lastdisassembledata.opcode := 'jne';
                lastdisassembledata.isjump := true;
                lastdisassembledata.isconditionaljump := true;
                inc(offset, 1 + 4);

                lastdisassembledata.parametervaluetype := dvtaddress;
                if is64bit then
                  lastdisassembledata.parametervalue := qword(offset + pint(@memory[2])^)
                else
                  lastdisassembledata.parametervalue := dword(offset + 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';
                lastdisassembledata.opcode := 'jbe';
                lastdisassembledata.isjump := true;
                lastdisassembledata.isconditionaljump := true;
                inc(offset, 1 + 4);

                lastdisassembledata.parametervaluetype := dvtaddress;
                if is64bit then
                  lastdisassembledata.parametervalue := qword(offset + pint(@memory[2])^)
                else
                  lastdisassembledata.parametervalue := dword(offset + 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';
                lastdisassembledata.opcode := 'ja';
                lastdisassembledata.isjump := true;
                lastdisassembledata.isconditionaljump := true;
                inc(offset, 1 + 4);

                lastdisassembledata.parametervaluetype := dvtaddress;
                if is64bit then
                  lastdisassembledata.parametervalue := qword(offset + pint(@memory[2])^)
                else
                  lastdisassembledata.parametervalue := dword(offset + 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';
                lastdisassembledata.opcode := 'js';
                lastdisassembledata.isjump := true;
                lastdisassembledata.isconditionaljump := true;
                inc(offset, 1 + 4);

                lastdisassembledata.parametervaluetype := dvtaddress;
                if is64bit then
                  lastdisassembledata.parametervalue := qword(offset + pint(@memory[2])^)
                else
                  lastdisassembledata.parametervalue := dword(offset + 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';
                lastdisassembledata.opcode := 'jns';
                lastdisassembledata.isjump := true;
                lastdisassembledata.isconditionaljump := true;
                inc(offset, 1 + 4);

                lastdisassembledata.parametervaluetype := dvtaddress;
                if is64bit then
                  lastdisassembledata.parametervalue := qword(offset + pint(@memory[2])^)
                else
                  lastdisassembledata.parametervalue := dword(offset + 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';
                lastdisassembledata.opcode := 'jp';
                lastdisassembledata.isjump := true;
                lastdisassembledata.isconditionaljump := true;
                inc(offset, 1 + 4);

                lastdisassembledata.parametervaluetype := dvtaddress;
                if is64bit then
                  lastdisassembledata.parametervalue := qword(offset + pint(@memory[2])^)
                else
                  lastdisassembledata.parametervalue := dword(offset + 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';
                lastdisassembledata.opcode := 'jnp';
                lastdisassembledata.isjump := true;
                lastdisassembledata.isconditionaljump := true;
                inc(offset, 1 + 4);

                lastdisassembledata.parametervaluetype := dvtaddress;
                if is64bit then
                  lastdisassembledata.parametervalue := qword(offset + pint(@memory[2])^)
                else
                  lastdisassembledata.parametervalue := dword(offset + 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';
                lastdisassembledata.opcode := 'jl';
                lastdisassembledata.isjump := true;
                lastdisassembledata.isconditionaljump := true;
                inc(offset, 1 + 4);

                lastdisassembledata.parametervaluetype := dvtaddress;
                if is64bit then
                  lastdisassembledata.parametervalue := qword(offset + pint(@memory[2])^)
                else
                  lastdisassembledata.parametervalue := dword(offset + 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';
                lastdisassembledata.opcode := 'jnl';
                lastdisassembledata.isjump := true;
                lastdisassembledata.isconditionaljump := true;
                inc(offset, 1 + 4);

                lastdisassembledata.parametervaluetype := dvtaddress;
                if is64bit then
                  lastdisassembledata.parametervalue := qword(offset + pint(@memory[2])^)
                else
                  lastdisassembledata.parametervalue := dword(offset + 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';
                lastdisassembledata.opcode := 'jng';
                lastdisassembledata.isjump := true;
                lastdisassembledata.isconditionaljump := true;
                inc(offset, 1 + 4);

                lastdisassembledata.parametervaluetype := dvtaddress;
                if is64bit then
                  lastdisassembledata.parametervalue := qword(offset + pint(@memory[2])^)
                else
                  lastdisassembledata.parametervalue := dword(offset + 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';
                lastdisassembledata.opcode := 'jg';
                lastdisassembledata.isjump := true;
                lastdisassembledata.isconditionaljump := true;
                inc(offset, 1 + 4);

                lastdisassembledata.parametervaluetype := dvtaddress;
                if is64bit then
                  lastdisassembledata.parametervalue := qword(offset + pint(@memory[2])^)
                else
                  lastdisassembledata.parametervalue := dword(offset + 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);

                inc(offset, last - 1);
              end;

            $91:
              begin
                description := 'set byte if not overfloww';
                lastdisassembledata.opcode := 'setno';
                lastdisassembledata.parameters := modrm(memory, prefix2, 2, 2, last);

                inc(offset, last - 1);
              end;

            $92:
              begin
                description := 'set byte if below/carry';
                lastdisassembledata.opcode := 'setb';
                lastdisassembledata.parameters := modrm(memory, prefix2, 2, 2, last);

                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);

                inc(offset, last - 1);
              end;

            $94:
              begin
                description := 'set byte if equal';
                lastdisassembledata.opcode := 'sete';
                lastdisassembledata.parameters := modrm(memory, prefix2, 2, 2, last);

                inc(offset, last - 1);
              end;

            $95:
              begin
                description := 'set byte if not equal';
                lastdisassembledata.opcode := 'setne';
                lastdisassembledata.parameters := modrm(memory, prefix2, 2, 2, last);

                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);

                inc(offset, last - 1);
              end;

            $97:
              begin
                description := 'set byte if above';
                lastdisassembledata.opcode := 'seta';
                lastdisassembledata.parameters := modrm(memory, prefix2, 2, 2, last);

                inc(offset, last - 1);
              end;

            $98:
              begin
                description := 'set byte if sign';
                lastdisassembledata.opcode := 'sets';
                lastdisassembledata.parameters := modrm(memory, prefix2, 2, 2, last);

                inc(offset, last - 1);
              end;

            $99:
              begin
                description := 'set byte if not sign';
                lastdisassembledata.opcode := 'setns';
                lastdisassembledata.parameters := modrm(memory, prefix2, 2, 2, last);

                inc(offset, last - 1);
              end;

            $9a:
              begin
                description := 'set byte if parity';
                lastdisassembledata.opcode := 'setp';
                lastdisassembledata.parameters := modrm(memory, prefix2, 2, 2, last);

                inc(offset, last - 1);
              end;

            $9b:
              begin
                description := 'set byte if not parity';
                lastdisassembledata.opcode := 'setnp';
                lastdisassembledata.parameters := modrm(memory, prefix2, 2, 2, last);

                inc(offset, last - 1);
              end;

            $9c:
              begin
                description := 'set byte if less';
                lastdisassembledata.opcode := 'setl';
                lastdisassembledata.parameters := modrm(memory, prefix2, 2, 2, last);

                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);
                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);
                inc(offset, last - 1);

              end;

            $9f:
              begin
                description := 'set byte if greater';
                lastdisassembledata.opcode := 'setg';
                lastdisassembledata.parameters := modrm(memory, prefix2, 2, 2, last);
                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 getreg(memory[2]) of
                  0:
                    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;

                  1:
                    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;

                  2:
                    begin
                      description := 'load streaming simd extension control/status';
                      lastdisassembledata.opcode := 'ldmxcsr';
                      lastdisassembledata.parameters := modrm(memory, prefix2, 2, 0, last);
                      inc(offset, last - 1);
                    end;

                  3:
                    begin
                      description := 'store streaming simd extension control/status';
                      lastdisassembledata.opcode := 'stmxcsr';
                      lastdisassembledata.parameters := modrm(memory, prefix2, 2, 0, last);
                      inc(offset, last - 1);
                    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, 1);
                      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 := 'memory fence';
                      lastdisassembledata.opcode := 'mfence';
                      inc(offset, 1);
                    end;

                  7:
                    begin
                      description := 'store fence';
                      lastdisassembledata.opcode := 'sfence';
                      inc(offset, 1);
                    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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);

                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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);

                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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);

                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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);

                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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 2, last, 8);

                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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 1, last, 16);

                inc(offset, last - 1);
              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
                        //bsf
                description := 'bit scan forward';
                lastdisassembledata.opcode := 'bsf';
                if $66 in prefix2 then
                  lastdisassembledata.parameters := r16(memory[2]) + ',' + modrm(memory, prefix2, 2, 1, last)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);

                inc(offset, last - 1);
              end;

            $bd:
              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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);

                inc(offset, last - 1);
              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)
                else
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 2, last, 8);

                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);

                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
                if $f2 in prefix2 then
                begin
                  description := 'compare scalar dpuble-precision floating-point values';
                  lastdisassembledata.opcode := 'cmpsd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last, 128);

                  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 := 'packed single-fp compare';
                  lastdisassembledata.opcode := 'cmpss';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last, 128);
                  lastdisassembledata.parametervaluetype := dvtvalue;
                  lastdisassembledata.parametervalue := memory[last];
                  lastdisassembledata.parameters := lastdisassembledata.parameters + inttohexs(lastdisassembledata.parametervalue, 2);
                  inc(offset, last);
                end
                else
                begin
                  if $66 in prefix2 then
                  begin
                    description := 'compare packed double-precision floating-point values';
                    lastdisassembledata.opcode := 'cmppd';
                    lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last, 128);
                    lastdisassembledata.parametervaluetype := dvtvalue;
                    lastdisassembledata.parametervalue := memory[last];
                    lastdisassembledata.parameters := lastdisassembledata.parameters + inttohexs(lastdisassembledata.parametervalue, 2);
                    inc(offset, last);
                  end
                  else
                  begin
                    description := 'packed single-fp compare';
                    lastdisassembledata.opcode := 'cmpps';
                    lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last, 128);
                    lastdisassembledata.parametervaluetype := dvtvalue;
                    lastdisassembledata.parametervalue := memory[last];
                    lastdisassembledata.parameters := lastdisassembledata.parameters + inttohexs(lastdisassembledata.parametervalue, 2);
                    inc(offset, last);
                  end;
                end;
              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';
                  lastdisassembledata.opcode := 'pinsrw';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 0, last);
                  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);
                  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);
                  lastdisassembledata.parametervaluetype := dvtvalue;
                  lastdisassembledata.parametervalue := memory[last];
                  lastdisassembledata.parameters := lastdisassembledata.parameters + inttohexs(lastdisassembledata.parametervalue, 2);
                  inc(offset, 3);
                end;
              end;

            $c6:
              begin
                if $66 in prefix2 then
                begin
                  description := 'shuffle double-fp';
                  lastdisassembledata.opcode := 'shufpd';
                  lastdisassembledata.parameters := xmm(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, last);
                end
                else
                begin
                  description := 'shuffle single-fp';
                  lastdisassembledata.opcode := 'shufps';
                  lastdisassembledata.parameters := xmm(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, 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;

                  6:
                    begin
                      if $66 in prefix2 then
                      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
                      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
                        description := 'loads ther current vmcs pointer from memory';
                        lastdisassembledata.opcode := 'vmptrld';
                        lastdisassembledata.parameters := modrm(memory, prefix2, 2, 0, last);

                        inc(offset, last - 1);
                      end;
                    end;

                  7:
                    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;

            $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;

            $d1:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed shift right logical';
                  lastdisassembledata.opcode := 'psrlw';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  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);
                  inc(offset, last - 1);
                end;
              end;

            $d2:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed shift right logical';
                  lastdisassembledata.opcode := 'psrld';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  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);
                  inc(offset, last - 1);
                end;
              end;

            $d3:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed shift right logical';
                  lastdisassembledata.opcode := 'psrlq';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  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);
                  inc(offset, last - 1);
                end;
              end;

            $d4:
              begin
                if $66 in prefix2 then
                begin
                  description := 'add packed quadwprd integers';
                  lastdisassembledata.opcode := 'paddq';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  inc(offset, last - 1);
                end
                else
                begin
                  description := 'add packed quadwprd integers';
                  lastdisassembledata.opcode := 'paddq';
                  lastdisassembledata.parameters := mm(memory[2]) + ',' + modrm(memory, prefix2, 2, 3, last);
                  inc(offset, last - 1);
                end;
              end;

            $d5:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed multiply low';
                  lastdisassembledata.opcode := 'pmullw';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  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);

                  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);

                  inc(offset, last - 1);
                end
                else if $66 in prefix2 then
                begin
                  description := 'move low quadword from xmm to mmx technology register';
                  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';
                  lastdisassembledata.opcode := 'pmovmskb';
                  lastdisassembledata.parameters := r32(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $d8:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed subtract unsigned with saturation';
                  lastdisassembledata.opcode := 'psubusb';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  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);
                  inc(offset, last - 1);
                end;
              end;

            $d9:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed subtract unsigned with saturation';
                  lastdisassembledata.opcode := 'psubusw';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  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);
                  inc(offset, last - 1);
                end;
              end;

            $da:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed unsigned integer byte minimum';
                  lastdisassembledata.opcode := 'pminub';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $db:
              begin
                if $66 in prefix2 then
                begin
                  description := 'logical and';
                  lastdisassembledata.opcode := 'pand';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  inc(offset, last - 1);
                end
                else
                begin
                  description := 'logical and';
                  lastdisassembledata.opcode := 'pand';
                  lastdisassembledata.parameters := mm(memory[2]) + ',' + modrm(memory, prefix2, 2, 3, last);

                  inc(offset, last - 1);
                end;
              end;

            $dc:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed add unsigned with saturation';
                  lastdisassembledata.opcode := 'paddusb';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $dd:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed add unsigned with saturation';
                  lastdisassembledata.opcode := 'paddusw';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $de:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed unsigned integer byte maximum';
                  lastdisassembledata.opcode := 'pmaxub';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $df:
              begin
                if $66 in prefix2 then
                begin
                  description := 'logical and not';
                  lastdisassembledata.opcode := 'pandn';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $e0:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed average';
                  lastdisassembledata.opcode := 'pavgb';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  inc(offset, last - 1);
                end
                else
                begin
                  description := 'packed average';
                  lastdisassembledata.opcode := 'pavgb';
                  lastdisassembledata.parameters := mm(memory[2]) + ',' + modrm(memory, prefix2, 2, 3, last);

                  inc(offset, last - 1);
                end;
              end;

            $e1:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed shift right arithmetic';
                  lastdisassembledata.opcode := 'psraw';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  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);
                  inc(offset, last - 1);
                end;
              end;

            $e2:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed shift left logical';
                  lastdisassembledata.opcode := 'psrad';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  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);
                  inc(offset, last - 1);
                end;
              end;

            $e3:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed average';
                  lastdisassembledata.opcode := 'pavgw';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  inc(offset, last - 1);
                end
                else
                begin
                  description := 'packed average';
                  lastdisassembledata.opcode := 'pavgw';
                  lastdisassembledata.parameters := mm(memory[2]) + ',' + modrm(memory, prefix2, 2, 3, last);

                  inc(offset, last - 1);
                end;
              end;

            $e4:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed multiply high unsigned';
                  lastdisassembledata.opcode := 'pmulhuw';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $e5:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed multiply high';
                  lastdisassembledata.opcode := 'pmulhw';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  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';
                  lastdisassembledata.opcode := 'cvtpd2dq';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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';
                  lastdisassembledata.opcode := 'cvtdq2pd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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';
                    lastdisassembledata.opcode := 'cvttpd2dq';
                    lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                    inc(offset, last - 1);
                  end;
                end;
              end;

            $e7:
              begin
                if $66 in prefix2 then
                begin
                  lastdisassembledata.opcode := 'movntdq';
                  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';
                  lastdisassembledata.opcode := 'psubsb';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  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);
                  inc(offset, last - 1);
                end;
              end;

            $e9:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed subtract with saturation';
                  lastdisassembledata.opcode := 'psubsw';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  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);
                  inc(offset, last - 1);
                end;
              end;

            $ea:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed signed integer word minimum';
                  lastdisassembledata.opcode := 'pminsw';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $eb:
              begin
                if $66 in prefix2 then
                begin
                  description := 'bitwise logical or';
                  lastdisassembledata.opcode := 'por';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $ec:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed add with saturation';
                  lastdisassembledata.opcode := 'paddsb';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $ed:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed add with saturation';
                  lastdisassembledata.opcode := 'paddsw';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $ee:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed signed integer word maximum';
                  lastdisassembledata.opcode := 'pmaxsw';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $ef:
              begin
                if $66 in prefix2 then
                begin
                  description := 'logical exclusive or';
                  lastdisassembledata.opcode := 'pxor';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $f0:
              begin
                if $f2 in prefix2 then
                begin
                  description := 'load unaligned integer 128 bits';
                  lastdisassembledata.opcode := 'lddqu';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  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);
                  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);
                  inc(offset, last - 1);
                end;
              end;

            $f2:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed shift left logical';
                  lastdisassembledata.opcode := 'pslld';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  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);
                  inc(offset, last - 1);
                end;
              end;

            $f3:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed shift left logical';
                  lastdisassembledata.opcode := 'psllq';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);
                  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);
                  inc(offset, last - 1);
                end;
              end;

            $f4:
              begin
                if $66 in prefix2 then
                begin
                  description := 'multiply packed unsigned doubleword integers';
                  lastdisassembledata.opcode := 'pmuludq';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $f5:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed multiply and add';
                  lastdisassembledata.opcode := 'pmaddwd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $f6:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed sum of absolute differences';
                  lastdisassembledata.opcode := 'psadbw';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $f7:
              begin
                if $66 in prefix2 then
                begin
                  description := 'store selected bytes of double quadword';
                  lastdisassembledata.opcode := 'maskmovdqu';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  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);

                  inc(offset, last - 1);
                end;
              end;

            $f8:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed subtract';
                  lastdisassembledata.opcode := 'psubb';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  inc(offset, last - 1);
                end
                else
                begin
                  description := 'packed subtract';
                  lastdisassembledata.opcode := 'psubb';
                  lastdisassembledata.parameters := mm(memory[2]) + ',' + modrm(memory, prefix2, 2, 3, last);

                  inc(offset, last - 1);
                end;
              end;

            $f9:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed subtract';
                  lastdisassembledata.opcode := 'psubw';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  inc(offset, last - 1);
                end
                else
                begin
                  description := 'packed subtract';
                  lastdisassembledata.opcode := 'psubw';
                  lastdisassembledata.parameters := mm(memory[2]) + ',' + modrm(memory, prefix2, 2, 3, last);

                  inc(offset, last - 1);
                end;
              end;

            $fa:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed subtract';
                  lastdisassembledata.opcode := 'psubd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  inc(offset, last - 1);
                end
                else
                begin
                  description := 'packed subtract';
                  lastdisassembledata.opcode := 'psubd';
                  lastdisassembledata.parameters := mm(memory[2]) + ',' + modrm(memory, prefix2, 2, 3, last);

                  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);

                  inc(offset, last - 1);
                end
                else
                begin
                  description := 'packed subtract';
                  lastdisassembledata.opcode := 'psubq';
                  lastdisassembledata.parameters := mm(memory[2]) + ',' + modrm(memory, prefix2, 2, 3, last);

                  inc(offset, last - 1);
                end;
              end;

            $fc:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed add';
                  lastdisassembledata.opcode := 'paddb';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  inc(offset, last - 1);
                end
                else
                begin
                  description := 'packed add';
                  lastdisassembledata.opcode := 'paddb';
                  lastdisassembledata.parameters := mm(memory[2]) + ',' + modrm(memory, prefix2, 2, 3, last);

                  inc(offset, last - 1);
                end;
              end;

            $fd:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed add';
                  lastdisassembledata.opcode := 'paddw';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  inc(offset, last - 1);
                end
                else
                begin
                  description := 'packed add';
                  lastdisassembledata.opcode := 'paddw';
                  lastdisassembledata.parameters := mm(memory[2]) + ',' + modrm(memory, prefix2, 2, 3, last);

                  inc(offset, last - 1);
                end;
              end;

            $fe:
              begin
                if $66 in prefix2 then
                begin
                  description := 'packed add';
                  lastdisassembledata.opcode := 'paddd';
                  lastdisassembledata.parameters := xmm(memory[2]) + ',' + modrm(memory, prefix2, 2, 4, last);

                  inc(offset, last - 1);
                end
                else
                begin
                  description := 'packed add';
                  lastdisassembledata.opcode := 'paddd';
                  lastdisassembledata.parameters := mm(memory[2]) + ',' + modrm(memory, prefix2, 2, 3, last);

                  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);

          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)
          else
            lastdisassembledata.parameters := r32(memory[1]) + ',' + modrm(memory, prefix2, 1, 0, last);

          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(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);

          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)
          else
            lastdisassembledata.parameters := r32(memory[1]) + ',' + modrm(memory, prefix2, 1, 0, last);

          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(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);
          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)
          else
            lastdisassembledata.parameters := r32(memory[1]) + ',' + modrm(memory, prefix2, 1, 0, last);

          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(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);

          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)
          else
            lastdisassembledata.parameters := r32(memory[1]) + ',' + modrm(memory, prefix2, 1, 0, last);

          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(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);

          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)
          else
            lastdisassembledata.parameters := r32(memory[1]) + ',' + modrm(memory, prefix2, 1, 0, last);

          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(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);

          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)
          else
            lastdisassembledata.parameters := r32(memory[1]) + ',' + modrm(memory, prefix2, 1, 0, last);

          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_x then
              lastdisassembledata.parameters := colorreg + 'rax' + endcolor + ',' + inttohexs(dwordptr^, 8)
            else
              lastdisassembledata.parameters := colorreg + 'eax' + endcolor + ',' + inttohexs(dwordptr^, 8);
            inc(offset, 4);
          end;
        end;

            //prefix bytes need fixing
        $3f:
        begin  //aas
          lastdisassembledata.opcode := 'aas';
          description := 'ascii adjust al after subtraction';
        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
            rexprefix := rexprefix or bit_rex_w; //so rd will pick the 64-bit version

          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
            rexprefix := rexprefix or bit_rex_w; //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)
          else
            lastdisassembledata.parameters := r32(memory[1]) + ',' + modrm(memory, prefix2, 1, 0, last);

          inc(offset, last - 1);

        end;

      $63:
        begin
              //arpl or movsxd
          if is64bit then
          begin
            lastdisassembledata.opcode := 'movsxd';
            RexPrefix := RexPrefix and (not BIT_REX_W);

            lastdisassembledata.parameters := ' ' + r64(memory[1]) + ',' + modrm(memory, prefix2, 1, 0, last, 32);
            inc(offset, last - 1);
            description := 'Move doubleword to quadword with signextension'
          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';
            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);
            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);
            dwordptr := @memory[last];
            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)
          else
            lastdisassembledata.parameters := r32(memory[1]) + ',' + modrm(memory, prefix2, 1, 0, last);

          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';
          lastdisassembledata.opcode := 'jo';
          lastdisassembledata.isjump := true;
          lastdisassembledata.isconditionaljump := true;
          inc(offset);

          lastdisassembledata.seperators[lastdisassembledata.seperatorcount] := 1;
          inc(lastdisassembledata.seperatorcount);

          lastdisassembledata.parametervaluetype := dvtAddress;

          if is64bit then
            lastdisassembledata.parametervalue := qword(offset + shortint(memory[1]))
          else
            lastdisassembledata.parametervalue := dword(offset + shortint(memory[1]));

          lastdisassembledata.parameters := inttohexs(lastdisassembledata.parametervalue, 8);

        end;

      $71:
        begin
          description := 'jump short if not overflow';
          lastdisassembledata.opcode := 'jno';
          lastdisassembledata.isjump := true;
          lastdisassembledata.isconditionaljump := true;
          inc(offset);

          lastdisassembledata.seperators[lastdisassembledata.seperatorcount] := 1;
          inc(lastdisassembledata.seperatorcount);

          lastdisassembledata.parametervaluetype := dvtAddress;

          if is64bit then
            lastdisassembledata.parametervalue := qword(offset + shortint(memory[1]))
          else
            lastdisassembledata.parametervalue := dword(offset + shortint(memory[1]));

          lastdisassembledata.parameters := inttohexs(lastdisassembledata.parametervalue, 8);

        end;

      $72:
        begin
          description := 'jump short if below/carry';
          lastdisassembledata.opcode := 'jb';
          lastdisassembledata.isjump := true;
          lastdisassembledata.isconditionaljump := true;
          inc(offset);

          lastdisassembledata.seperators[lastdisassembledata.seperatorcount] := 1;
          inc(lastdisassembledata.seperatorcount);

          lastdisassembledata.parametervaluetype := dvtAddress;

          if is64bit then
            lastdisassembledata.parametervalue := qword(offset + shortint(memory[1]))
          else
            lastdisassembledata.parametervalue := dword(offset + shortint(memory[1]));

          lastdisassembledata.parameters := inttohexs(lastdisassembledata.parametervalue, 8);

        end;

      $73:
        begin
          description := 'jump short if above or equal';
          lastdisassembledata.opcode := 'jae';
          lastdisassembledata.isjump := true;
          lastdisassembledata.isconditionaljump := true;
          inc(offset);

          lastdisassembledata.seperators[lastdisassembledata.seperatorcount] := 1;
          inc(lastdisassembledata.seperatorcount);

          lastdisassembledata.parametervaluetype := dvtAddress;

          if is64bit then
            lastdisassembledata.parametervalue := qword(offset + shortint(memory[1]))
          else
            lastdisassembledata.parametervalue := dword(offset + shortint(memory[1]));

          lastdisassembledata.parameters := inttohexs(lastdisassembledata.parametervalue, 8);

        end;

      $74:
        begin
          description := 'jump short if equal';
          lastdisassembledata.opcode := 'je';
          lastdisassembledata.isjump := true;
          lastdisassembledata.isconditionaljump := true;
          inc(offset);

          lastdisassembledata.seperators[lastdisassembledata.seperatorcount] := 1;
          inc(lastdisassembledata.seperatorcount);

          lastdisassembledata.parametervaluetype := dvtAddress;

          if is64bit then
            lastdisassembledata.parametervalue := qword(offset + shortint(memory[1]))
          else
            lastdisassembledata.parametervalue := dword(offset + shortint(memory[1]));

          lastdisassembledata.parameters := inttohexs(lastdisassembledata.parametervalue, 8);

        end;

      $75:
        begin
          description := 'jump short if not equal';
          lastdisassembledata.opcode := 'jne';
          lastdisassembledata.isjump := true;
          lastdisassembledata.isconditionaljump := true;
          inc(offset);

          lastdisassembledata.seperators[lastdisassembledata.seperatorcount] := 1;
          inc(lastdisassembledata.seperatorcount);

          lastdisassembledata.parametervaluetype := dvtAddress;

          if is64bit then
            lastdisassembledata.parametervalue := qword(offset + shortint(memory[1]))
          else
            lastdisassembledata.parametervalue := dword(offset + shortint(memory[1]));

          lastdisassembledata.parameters := inttohexs(lastdisassembledata.parametervalue, 8);

        end;

      $76:
        begin
          description := 'jump short if not above';
          lastdisassembledata.opcode := 'jna';
          lastdisassembledata.isjump := true;
          lastdisassembledata.isconditionaljump := true;
          inc(offset);

          lastdisassembledata.seperators[lastdisassembledata.seperatorcount] := 1;
          inc(lastdisassembledata.seperatorcount);

          lastdisassembledata.parametervaluetype := dvtAddress;

          if is64bit then
            lastdisassembledata.parametervalue := qword(offset + shortint(memory[1]))
          else
            lastdisassembledata.parametervalue := dword(offset + shortint(memory[1]));

          lastdisassembledata.parameters := inttohexs(lastdisassembledata.parametervalue, 8);

        end;

      $77:
        begin
          description := 'jump short if above';
          lastdisassembledata.opcode := 'ja';
          lastdisassembledata.isjump := true;
          lastdisassembledata.isconditionaljump := true;
          inc(offset);

          lastdisassembledata.seperators[lastdisassembledata.seperatorcount] := 1;
          inc(lastdisassembledata.seperatorcount);

          lastdisassembledata.parametervaluetype := dvtAddress;

          if is64bit then
            lastdisassembledata.parametervalue := qword(offset + shortint(memory[1]))
          else
            lastdisassembledata.parametervalue := dword(offset + shortint(memory[1]));

          lastdisassembledata.parameters := inttohexs(lastdisassembledata.parametervalue, 8);

        end;

      $78:
        begin
          description := 'jump short if sign';
          lastdisassembledata.opcode := 'js';
          lastdisassembledata.isjump := true;
          lastdisassembledata.isconditionaljump := true;
          inc(offset);

          lastdisassembledata.seperators[lastdisassembledata.seperatorcount] := 1;
          inc(lastdisassembledata.seperatorcount);

          lastdisassembledata.parametervaluetype := dvtAddress;

          if is64bit then
            lastdisassembledata.parametervalue := qword(offset + shortint(memory[1]))
          else
            lastdisassembledata.parametervalue := dword(offset + shortint(memory[1]));

          lastdisassembledata.parameters := inttohexs(lastdisassembledata.parametervalue, 8);

        end;

      $79:
        begin
          description := 'jump short if not sign';
          lastdisassembledata.opcode := 'jns';
          lastdisassembledata.isjump := true;
          lastdisassembledata.isconditionaljump := true;
          inc(offset);

          lastdisassembledata.seperators[lastdisassembledata.seperatorcount] := 1;
          inc(lastdisassembledata.seperatorcount);

          lastdisassembledata.parametervaluetype := dvtAddress;

          if is64bit then
            lastdisassembledata.parametervalue := qword(offset + shortint(memory[1]))
          else
            lastdisassembledata.parametervalue := dword(offset + shortint(memory[1]));

          lastdisassembledata.parameters := inttohexs(lastdisassembledata.parametervalue, 8);

        end;

      $7a:
        begin
          description := 'jump short if parity';
          lastdisassembledata.opcode := 'jp';
          lastdisassembledata.isjump := true;
          lastdisassembledata.isconditionaljump := true;
          inc(offset);

          lastdisassembledata.seperators[lastdisassembledata.seperatorcount] := 1;
          inc(lastdisassembledata.seperatorcount);

          lastdisassembledata.parametervaluetype := dvtAddress;

          if is64bit then
            lastdisassembledata.parametervalue := qword(offset + shortint(memory[1]))
          else
            lastdisassembledata.parametervalue := dword(offset + shortint(memory[1]));

          lastdisassembledata.parameters := inttohexs(lastdisassembledata.parametervalue, 8);

        end;

      $7b:
        begin
          description := 'jump short if not parity';
          lastdisassembledata.opcode := 'jnp';
          lastdisassembledata.isjump := true;
          lastdisassembledata.isconditionaljump := true;
          inc(offset);

          lastdisassembledata.seperators[lastdisassembledata.seperatorcount] := 1;
          inc(lastdisassembledata.seperatorcount);

          lastdisassembledata.parametervaluetype := dvtAddress;

          if is64bit then
            lastdisassembledata.parametervalue := qword(offset + shortint(memory[1]))
          else
            lastdisassembledata.parametervalue := dword(offset + shortint(memory[1]));

          lastdisassembledata.parameters := inttohexs(lastdisassembledata.parametervalue, 8);

        end;

      $7c:
        begin
          description := 'jump short if not greater or equal';
          lastdisassembledata.opcode := 'jnge';
          lastdisassembledata.isjump := true;
          lastdisassembledata.isconditionaljump := true;
          inc(offset);

          lastdisassembledata.seperators[lastdisassembledata.seperatorcount] := 1;
          inc(lastdisassembledata.seperatorcount);

          lastdisassembledata.parametervaluetype := dvtAddress;

          if is64bit then
            lastdisassembledata.parametervalue := qword(offset + shortint(memory[1]))
          else
            lastdisassembledata.parametervalue := dword(offset + shortint(memory[1]));

          lastdisassembledata.parameters := inttohexs(lastdisassembledata.parametervalue, 8);

        end;

      $7d:
        begin
          description := 'jump short if not less (greater or equal)';
          lastdisassembledata.opcode := 'jnl';
          lastdisassembledata.isjump := true;
          lastdisassembledata.isconditionaljump := true;
          inc(offset);

          lastdisassembledata.seperators[lastdisassembledata.seperatorcount] := 1;
          inc(lastdisassembledata.seperatorcount);

          lastdisassembledata.parametervaluetype := dvtAddress;

          if is64bit then
            lastdisassembledata.parametervalue := qword(offset + shortint(memory[1]))
          else
            lastdisassembledata.parametervalue := dword(offset + shortint(memory[1]));

          lastdisassembledata.parameters := inttohexs(lastdisassembledata.parametervalue, 8);

        end;

      $7e:
        begin
          description := 'jump short if less or equal';
          lastdisassembledata.opcode := 'jle';
          lastdisassembledata.isjump := true;
          lastdisassembledata.isconditionaljump := true;
          inc(offset);

          lastdisassembledata.seperators[lastdisassembledata.seperatorcount] := 1;
          inc(lastdisassembledata.seperatorcount);

          if is64bit then
            lastdisassembledata.parametervalue := qword(offset + shortint(memory[1]))
          else
            lastdisassembledata.parametervalue := dword(offset + shortint(memory[1]));

          lastdisassembledata.parameters := inttohexs(lastdisassembledata.parametervalue, 8);
          lastdisassembledata.parameterValueType := dvtAddress;
        end;

      $7f:
        begin
          description := 'jump short if greater';
          lastdisassembledata.opcode := 'jg';
          lastdisassembledata.isjump := true;
          lastdisassembledata.isconditionaljump := true;
          inc(offset);

          lastdisassembledata.seperators[lastdisassembledata.seperatorcount] := 1;
          inc(lastdisassembledata.seperatorcount);

          if is64bit then
            lastdisassembledata.parametervalue := qword(offset + shortint(memory[1]))
          else
            lastdisassembledata.parametervalue := dword(offset + 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
                      //and
                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^;

                  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^;

                  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^;

                  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^;

                  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^;

                  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^;

                  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^;

                  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
                    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^;

                  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 := 'exchage 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 := 'exchage 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);

          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)
          else
            lastdisassembledata.parameters := r32(memory[1]) + ',' + modrm(memory, prefix2, 1, 0, last);

          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
            lastdisassembledata.parameters := r16(memory[1]) + ',' + modrm(memory, prefix2, 1, 1, last)
          else
            lastdisassembledata.parameters := r32(memory[1]) + ',' + modrm(memory, prefix2, 1, 0, last);

          inc(offset, last - 1);
        end;

      $8e:
        begin
          description := 'copy memory';
          lastdisassembledata.opcode := 'mov';
          lastdisassembledata.parameters := sreg(memory[1]) + ',' + modrm(memory, prefix2, 1, 1, last);

          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';
        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 is64bit then
          begin
            lastdisassembledata.parameters := colorreg + 'ax' + endcolor + ',' + getsegmentoverride(prefix2) + '[' + inttohexs(pqword(dwordptr)^, 8) + ']';
            inc(offset, 8);
          end
          else
          begin
            lastdisassembledata.parameters := colorreg + 'ax' + 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 is64bit then
              lastdisassembledata.parameters := lastdisassembledata.parameters + getsegmentoverride(prefix2) + '[' + inttohexs(pqword(dwordptr)^, 8) + ']'
            else
              lastdisassembledata.parameters := lastdisassembledata.parameters + getsegmentoverride(prefix2) + '[' + inttohexs(dwordptr^, 8) + ']';

          end;

          if 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 is64bit then
            lastdisassembledata.parameters := 'byte ptr ' + getsegmentoverride(prefix2) + '[' + inttohexs(pqword(dwordptr)^, 8) + '],' + colorreg + 'al' + endcolor
          else
            lastdisassembledata.parameters := 'byte ptr ' + getsegmentoverride(prefix2) + '[' + inttohexs(dwordptr^, 8) + '],' + colorreg + 'al' + endcolor;

          if 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 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 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(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);

          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;

            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
          description := 'near return to calling procedure and pop 2 bytes from stack';
          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);

        end;

      $c3:
        begin
          description := 'near return to calling procedure';
          lastdisassembledata.opcode := 'ret';
          LastDisassembleData.isret := true;
        end;

      $c4:
        begin
          description := 'load far pointer';
          lastdisassembledata.opcode := 'les';
          if $66 in prefix2 then
            lastdisassembledata.parameters := r16(memory[1]) + ',' + modrm(memory, prefix2, 1, 1, last)
          else
            lastdisassembledata.parameters := r32(memory[1]) + ',' + modrm(memory, prefix2, 1, 0, last);

          inc(offset, last - 1);
        end;

      $c5:
        begin
          description := 'load far pointer';
          lastdisassembledata.opcode := 'lds';
          if $66 in prefix2 then
            lastdisassembledata.parameters := r16(memory[1]) + ',' + modrm(memory, prefix2, 1, 1, last)
          else
            lastdisassembledata.parameters := r32(memory[1]) + ',' + modrm(memory, prefix2, 1, 0, last);

          inc(offset, last - 1);
        end;

      $c6:
        begin
          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
          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';
                  lastdisassembledata.parameters := modrm(memory, prefix2, 1, 0, last);

                  dwordptr := @memory[last];
                  lastdisassembledata.parametervaluetype := dvtvalue;
                  lastdisassembledata.parametervalue := dwordptr^;

                  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';
        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 devide by 2, once';
                lastdisassembledata.opcode := 'shr';
                lastdisassembledata.parameters := modrm(memory, prefix2, 1, 2, last, 8) + '1';
                inc(offset, last - 1);
              end;

            6:
              begin
                description := 'not defined by the intel documentation';
                lastdisassembledata.opcode := 'db';
                lastdisassembledata.parameters := inttohexs(memory[0], 2) + ' ' + inttohexs(memory[1], 2);
              end;

            7:
              begin
                description := 'signed devide 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) + '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) + '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) + '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) + '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) + '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) + '1';
                  inc(offset, last - 1);
                end;
              end;

            6:
              begin
                description := 'undefined by the intel documentation';
                lastdisassembledata.opcode := 'db';
                lastdisassembledata.parameters := inttohexs(memory[0], 2);
              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) + '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 devide 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 devide 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;

            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
          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?';
                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 := 'devide';
                  lastdisassembledata.opcode := 'fidiv';
                  lastdisassembledata.parameters := modrm(memory, prefix2, 1, 0, last);

                  inc(offset, last - 1);
                end;

              7:
                begin
                  description := 'reverse devide';
                  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;

                  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
                      description := 'load floating point value';
                      lastdisassembledata.opcode := 'fld';
                      lastdisassembledata.parameters := modrm(memory, prefix2, 1, 0, last, 80);

                      inc(offset, last - 1);
                    end;

                  7:
                    begin
                      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
          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
                      description := 'load floating point value';
                      lastdisassembledata.opcode := 'fld';
                      lastdisassembledata.parameters := modrm(memory, prefix2, 1, 0, last, 64);

                      inc(offset, last - 1);
                    end;

                  2:
                    begin
                      description := 'store double';
                      lastdisassembledata.opcode := 'fst';
                      lastdisassembledata.parameters := modrm(memory, prefix2, 1, 0, last, 64);

                      inc(offset, last - 1);
                    end;

                  3:
                    begin
                      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 := 'fsave';
                      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 devide';
                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 devide';
                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
                  lastdisassembledata.opcode := 'db';
                  lastdisassembledata.parameters := inttohexs(memory[0], 2);
                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
          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;

            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;

          lastdisassembledata.parametervaluetype := dvtaddress;
          if is64bit then
            lastdisassembledata.parametervalue := qword(offset + pshortint(@memory[1])^)
          else
            lastdisassembledata.parametervalue := dword(offset + pshortint(@memory[1])^);

          if $66 in prefix2 then
            lastdisassembledata.opcode := 'loopne'
          else
            lastdisassembledata.opcode := 'loopnz';

          inc(offset);
          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 $66 in prefix2 then
          begin
            lastdisassembledata.opcode := 'loope';
          end
          else
          begin
            lastdisassembledata.opcode := 'loopz';
          end;
          inc(offset);

          lastdisassembledata.parametervaluetype := dvtaddress;
          if is64bit then
            lastdisassembledata.parametervalue := qword(offset + pshortint(@memory[1])^)
          else
            lastdisassembledata.parametervalue := dword(offset + 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';
          lastdisassembledata.isjump := true;
          inc(offset);

          lastdisassembledata.parametervaluetype := dvtaddress;
          if is64bit then
            lastdisassembledata.parametervalue := qword(offset + pshortint(@memory[1])^)
          else
            lastdisassembledata.parametervalue := dword(offset + 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
            lastdisassembledata.opcode := 'jcxz'
          else
            lastdisassembledata.opcode := 'jecxz';
          inc(offset);

          lastdisassembledata.parametervaluetype := dvtaddress;

          if is64bit then
            lastdisassembledata.parametervalue := qword(offset + pshortint(@memory[1])^)
          else
            lastdisassembledata.parametervalue := dword(offset + 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;

          inc(offset, 4);
          lastdisassembledata.parametervaluetype := dvtaddress;

          if is64bit then
            lastdisassembledata.parametervalue := qword(offset + pinteger(@memory[1])^)
          else
            lastdisassembledata.parametervalue := dword(offset + 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 + psmallint(@memory[1])^);
            lastdisassembledata.parameters := inttohexs(lastdisassembledata.parametervalue, 8);
          end
          else
          begin
            lastdisassembledata.opcode := 'jmp';
            inc(offset, 4);
            lastdisassembledata.parametervaluetype := dvtaddress;

            if is64bit then
              lastdisassembledata.parametervalue := qword(offset + pinteger(@memory[1])^)
            else
              lastdisassembledata.parametervalue := dword(offset + 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 + pshortint(@memory[1])^)
          else
            lastdisassembledata.parametervalue := dword(offset + 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^;
                  lastdisassembledata.parameters := lastdisassembledata.parameters + inttohexs(dwordptr^, 4);
                  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);

                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);

                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
                  lastdisassembledata.parameters := modrm(memory, prefix2, 1, 0, last)
                else
                begin
                  if is64bit then
                    lastdisassembledata.parameters := modrm(memory, prefix2, 1, 0, last, 64)
                  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
                  lastdisassembledata.parameters := modrm(memory, prefix2, 1, 0, last, 64)
                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;

   // 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

    //strip off the , if it has one
    if (LastDisassembleData.parameters <> '') and (LastDisassembleData.parameters[length(LastDisassembleData.parameters)] = ',') then
      LastDisassembleData.parameters := copy(LastDisassembleData.parameters, 0, length(LastDisassembleData.parameters) - 1);

   // tempresult:=tempresult+LastDisassembleData.opcode+' '+LastDisassembleData.parameters;

    LastDisassembleData.description := description;
    j := length(LastDisassembleData.Bytes);
    setlength(LastDisassembleData.Bytes, j + offset - startoffset);

    for i := 0 to (offset - startoffset) - 1 do
    begin
      LastDisassembleData.Bytes[j + i] := memory[i];
      result := result + inttohex(memory[i], 2) + ' ';
    end;

    //adjust for the prefix.
    if j <> 0 then
      for i := 0 to LastDisassembleData.SeperatorCount - 1 do
        inc(LastDisassembleData.Seperators[i], prefixsize);

    //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;
    if riprelative then
    begin
      //add the current offset to the code between []
      LastDisassembleData.modrmValue := offset + 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;

  end
  else
  begin
    LastDisassembleData.opcode := '??';
    inc(offset);
  end;

  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;
end;

function TDisassembler.getLastBytestring: string;
var
  i, j: integer;
begin
  result := '';
  for i := 0 to length(LastDisassembleData.Bytes) - 1 do
  begin
    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 + ' ';
  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;

constructor TDisassembler.Create(isX64: Boolean);
begin
  is64bit := isX64;
  if isX64 then
  begin
    pointersize := 8;
  end
  else
  begin
    pointersize := 4;
  end;
end;

function TDisAssembler.inttohexs_withoutsymbols(value: UINT_PTR; 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;

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;

initialization

finalization

end.

