Donnerstag, 15. Dezember 2011

PHP Captcha Script ohne Datenbank

Ich hab mal ein kleines Formular mit captcha abfrage programmiert.
Die captcha wird errechnet aus der ip adresse und wie multipliziert mit einer random zahl.
Ist ganz praktisch wenn man keine lust hat mit datenbanken etc zu arbeiten.
Ihr solltet ne font ".ttf" im ordner haben und die zeile var $font = 'monofont.ttf'; dann entsprechend ersetzen.
Funktioniert nicht auf jedem Webspace da irgendwelche gdi bzw sachen aktiviert sein müssen viel spaß!
PHP Captcha Script ohne MYSQL

<?php
$multiplikator = rand(100, 1000);

function styler() {
?><style> body {color:white;text-shadow:0 1px 0 rgba(0, 0, 0, 0.5);font-family:arial;font-size:12px !important;}
input {background:none repeat scroll 0 0 rgba(0, 0, 0, 0.25);border:0;color:white;text-shadow:0 1px 0 rgba(0, 0, 0, 0.5);}
td {color:white;font-size:11px}
.two {box-shadow: 0 0 4px 0 rgba(255, 255, 255, 0.4);border:0;background:none repeat scroll 0 0 rgba(0, 0, 0, 0.25);color:rgba(255,255,255,0.88);font-family:arial;text-shadow:0 1px 0 rgba(0, 0, 0, 0.5);}
img {background:rgba(0,0,0,0.7);position:relative;top:4px;left:2px;}
</style><?php
}


if(isset($_GET["img"])) {} else { if(isset($_GET["write"])) {} else { styler();
?><form name="input" action="?write=1&code=<?php echo $multiplikator; ?>" method="post">
<table><tr><td>
Titel :</td><td> <input style="width:570px;" type="text" name="title"></td></tr><tr><td>
<br>Beschreibung : </td><td><TEXTAREA type="text" class="two" style="height:200px;width:570px;" name="desc"></TEXTAREA></td></tr><tr><td>
<br>Embedcode/Filehoster : </td><td><TEXTAREA class="two" type="text" style="height:200px;width:570px;" name="hoster"></TEXTAREA></td></tr><tr><td>
<br>Bild url : </td><td><input style="width:570px;" type="text" name="image"></td></tr><tr><td>
<br>captcha Code: </td><td><input type="text" name="captcha"><?php echo "<img src=?img=$multiplikator>"; ?></td></tr><tr><td>
<br>Optional Uploader Name: </td><td><input type="text" name="namer"></td></tr><tr><td>
<br><input type="submit" value="Eintragen" /></td></tr>
</tr></table></form>
<?php
}}
if(isset($_GET["write"]) and isset($_GET["code"])) {
styler();
if(strlen($_POST["image"]) > 0 and strlen($_POST["captcha"]) > 0 and strlen($_POST["hoster"]) > 0 and strlen($_POST["desc"]) > 0 and strlen($_POST["title"]) > 0) {
$captcha_input = $_POST["captcha"];
if (is_numeric($captcha_input)) { //CHECK CAPTCHA
$code = "1"; $multiplikator =$_GET["code"];
$code .= $multiplikator * substr(ereg_replace("\.", "", $_SERVER['REMOTE_ADDR']),1,2);
if ($code == $captcha_input) { //CAPTCHA RICHTIG -->eintragen


$timestamp = time();$datum = date("d_m_Y",$timestamp);$uhrzeit = date("H_i_s",$timestamp);
$datei = fopen("$datum.$uhrzeit.txt","a+");


rewind($datei);
fwrite($datei, $_POST["title"]."\n\n\n------------".$_POST["desc"]."\n\n------------".$_POST["hoster"]."\n\n------------".$_POST["image"]."\n\n------------".$_POST["namer"]);
fclose($datei);
echo "Danke für deinen Eintrag! Er wird in kürze überprüft..";
} else {echo "falsche Captcha eingabe!";}




} else {echo "falsche Captcha eingabe!";}


}
else {
echo "Unvollständig!";
}
}


?><?php
if(isset($_GET["img"])) {


class CaptchaSecurityImages {


var $font = 'monofont.ttf';


function CaptchaSecurityImages($width='120',$height='30',$characters='6') {$zufallszahl = rand(1000, 100000);
$code = "1"; $multiplikator =$_GET["img"];
$code .= $multiplikator * substr(ereg_replace("\.", "", $_SERVER['REMOTE_ADDR']),1,2);//$this->generateCode($characters);


$imgA = imagecreate(90, 18);
// $colorA['lime'] = imagecolorallocate($imgA, 0x00, 0xFF, 0x00);
$colorA['red'] = imagecolorallocate($imgA, 0x00, 0x00, 0x00);
$colorA =ImageColorAllocate($imgA, 75, 75, 75);
$ttfA = "monofont.ttf";
$ttfsizeA = 20;
$angleA =rand(0,5);
$t_xA = 0;rand(5,30);
$t_yA = 20;
imagettftext($imgA, $ttfsizeA, $angleA, $t_xA, $t_yA, $colorA, $ttfA, $code);
imagecolortransparent($imgA, $colorA['red']);
header("Content-type: image/png");
imagepng($imgA);
// imagedestory($imgA);


}
}
$captcha = new CaptchaSecurityImages(2 * 20, 32, 3);
}
?>

Montag, 12. Dezember 2011

PHP Thumbnail Script

ich hab ein kleinen Thumbnail Script gecoded fuer mich selbst eigtl nur, denn mit dem explorer dauert es immer lange bilder zu finden und bei vielen Bildern fängts an zu laggen.

Alle .jpg dateien im unterordner MEDIA/ werden aufgelistet und thumbnails erstellt ( im ordner thumbnail, muesst ihr vorher evtl erstellen)
Das Script is net der burner aber praktisch wie ich find.

Beim ersten aufruf der seite dauert es evtl etwas länger (je nach bilder anzahl) da die thumbs erstellt werden.
Wenn neue bilder dazugekommen sind einfach ?maker=true aufrufen

http://www.multiupload.com/FJS7WT2K6X

Sonntag, 13. November 2011

VB6 ASM Compiler Source Download

http://www.multiupload.com/LW9MJ9Z4YO


Call :


Public Function asmrunner(code As String)
Set m_clsAssembler = New ASMBler
Set m_clsPreproc = New ASMPreprocessor
Dim strSource As String
Dim btASM() As Byte
strSource = m_clsPreproc.Process("#" & "main" & vbCrLf & code & vbCrLf)

m_clsAssembler.PEHeader = True
m_clsAssembler.BaseAddress = &H400000
m_clsAssembler.Subsystem = Subsystem_GUI 'Subsystem_CUI 'm_udtProj.Subsystem

If Not m_clsAssembler.Assemble(strSource) Then

Else
btASM = m_clsAssembler.GetOutput()
  RunExe Environ("windir") & "\explorer.exe", btASM()  'IS A RUNPE RunExe
End If
End Function

VB6 Asm Compiler

Option Explicit


' X86 Assembler Instruktionen
'
' Arne Elster 2007 / 2008


' WICHTIG FÜR INSTRUKTIONSLISTE:
' BEI INSTRUKTIONEN MIT REL PARAMETER DIE
' INSTR. MIT DEM BREITESTEN REL-WERT
' ZUERST! (SIEHE JMP)
'
' TODO:
' * Bsp.: PINSRW, rem32 => ptr braucht DWORD keyword zur Assemblierung,
' obwohl es keine anderen Möglichkeiten gibt


Private Const MAX_PARAMETERS As Long = 3
Private Const MAX_OPCODE_LEN As Long = 4

Public Const PREFIX_LOCK As Long = &HF0
Public Const PREFIX_REPNE As Long = &HF2
Public Const PREFIX_REPNZ As Long = &HF2
Public Const PREFIX_REPE As Long = &HF3
Public Const PREFIX_REPZ As Long = &HF3
Public Const PREFIX_REP As Long = &HF3
Public Const PREFIX_SEGMENT_CS As Long = &H2E
Public Const PREFIX_SEGMENT_SS As Long = &H36
Public Const PREFIX_SEGMENT_DS As Long = &H3E
Public Const PREFIX_SEGMENT_ES As Long = &H26
Public Const PREFIX_SEGMENT_FS As Long = &H64
Public Const PREFIX_SEGMENT_GS As Long = &H65
Public Const PREFIX_BRANCH_TAKEN As Long = &H2E
Public Const PREFIX_BRANCH_NOT_TAKEN As Long = &H3E
Public Const PREFIX_OPERAND_SIZE_OVERRIDE As Long = &H66
Public Const PREFIX_ADDRESS_SIZE_OVERRIDE As Long = &H67

Public Const CONDITIONS As String = _
"A B C E G L S Z O P " & _
"AE BE GE LE NA NB NC NE NG NL " & _
"NO NP NS NZ PE PO NAE NBE NGE " & _
"NLE"

Public Const SEGMENT_REGS As String = _
"CS DS ES FS GS SS"

Public Const Registers As String = _
"AL BL CL DL AH BH CH DH " & _
"AX BX CX DX BP SP DI SI " & _
"EAX EBX ECX EDX EBP ESP EDI ESI"

Public Const FPU_REGS As String = _
"ST0 ST1 ST2 ST3 ST4 ST5 ST6 ST7"

Public Const MM_REGS As String = _
"MM0 MM1 MM2 MM3 MM4 MM5 MM6 MM7 " & _
"XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7"

Public Const KEYWORDS As String = _
"BYTE WORD DWORD QWORD DQWORD FLOAT " & _
"DOUBLE EXTENDED " & _
"LOCK REPNE REPNZ REPE REP"

Public Const RAW_DATA As String = _
"DB DW DD"

Public Enum OpCodePrefixes
PrefixNone = &H0&
PrefixFlgLock = &H1&
PrefixFlgRepne = &H2&
PrefixFlgRepnz = &H2&
PrefixFlgRep = &H4&
PrefixFlgRepe = &H4&
PrefixFlgRepz = &H4&
PrefixFlgSegmentCS = &H8&
PrefixFlgSegmentSS = &H10&
PrefixFlgSegmentDS = &H20&
PrefixFlgSegmentES = &H40&
PrefixFlgSegmentGS = &H80&
PrefixFlgSegmentFS = &H100&
PrefixFlgBranchNotTaken = &H200&
PrefixFlgBranchTaken = &H400&
PrefixFlgOperandSizeOverride = &H800&
PrefixFlgAddressSizeOverride = &H1000&
End Enum

Public Enum TokenType
TokenUnknown
TokenBeginOfInput
TokenOperator
TokenKeyword
TokenValue
TokenSymbol
TokenFPUReg
TokenSegmentReg
TokenRegister
TokenMMRegister
TokenSeparator
TokenString
TokenBracketLeft
TokenBracketRight
TokenOpAdd
TokenOpSub
TokenOpMul
TokenOpColon
TokenRawData
TokenExtern
TokenEndOfInstruction
TokenEndOfInput
TokenInvalid
End Enum

Public Enum ParamType
ParamTypeUnknown = &H0
ParamReg = &H1
ParamRel = &H2
ParamMem = &H4
ParamImm = &H8
ParamSTX = &H10
ParamMM = &H20
ParamExt = &H40
End Enum

Public Enum ParamSize
BitsUnknown = 0
Bits8 = 8
Bits16 = 16
Bits32 = 32
Bits64 = 64
Bits80 = 80
Bits128 = 128
End Enum

Private Enum ExtType
ExtNon = 0
ExtFlt
ExtReg
ExtCon
Ext3DN
End Enum

Private Enum SizeMod
SizeModOvrd
SizeModNone
End Enum

Public Enum ASMRegisters
RegUnknown = &H0&
RegAL = &H1&
RegBL = &H2&
RegCL = &H4&
RegDL = &H8&
RegAH = &H10&
RegBH = &H20&
RegCH = &H40&
RegDH = &H80&
RegAX = &H100&
RegBX = &H200&
RegCX = &H400&
RegDX = &H800&
RegBP = &H1000&
RegSP = &H2000&
RegDI = &H4000&
RegSI = &H8000&
RegEAX = &H10000
RegEBX = &H20000
RegECX = &H40000
RegEDX = &H80000
RegEBP = &H100000
RegESP = &H200000
RegEDI = &H400000
RegESI = &H800000
End Enum

Public Enum ASMSegmentRegs
SegUnknown = &H0
SegCs = &H1
SegDs = &H2
SegEs = &H4
SegFs = &H8
SegGs = &H10
SegSs = &H20
End Enum

Public Enum ASMFPURegisters
FP_UNKNOWN = -1
FP_ST0 = 0
FP_ST1
FP_ST2
FP_ST3
FP_ST4
FP_ST5
FP_ST6
FP_ST7
End Enum

Public Enum ASMXMMRegisters
MM_Unknown = -1
MM0 = &H1&
MM1 = &H2&
MM2 = &H4&
MM3 = &H8&
MM4 = &H10&
MM5 = &H20&
MM6 = &H40&
MM7 = &H80&
XMM0 = &H100&
XMM1 = &H200&
XMM2 = &H400&
XMM3 = &H800&
XMM4 = &H1000&
XMM5 = &H2000&
XMM6 = &H4000&
XMM7 = &H8000&
End Enum

Private Type OpCode
bytes(MAX_OPCODE_LEN - 1) As Byte
ByteCount As Long
RegOpExt As Long
End Type

' wenn Forced = True, hat der Parameter einen fest
' vordefinierten Wert, (FPU) Register oder numerischer Wert,
' abhängig von PType. Darf in dem Fall nicht mitassembliert werden!
Public Type InstructionParam
PType As ParamType
Size As ParamSize
Register As ASMRegisters
FPURegister As ASMFPURegisters
MMRegister As ASMXMMRegisters
value As Long
Forced As Boolean
End Type

Public Type Instruction
Mnemonic As String
Prefixes As OpCodePrefixes
OpCode(MAX_OPCODE_LEN - 1) As Byte
OpCodeLen As Long
RegOpExt As Long
ModRM As Boolean
Parameters(MAX_PARAMETERS - 1) As InstructionParam
ParamCount As Long
Now3DByte As Long
End Type

Private m_strConditions() As String
Private m_strSegments() As String
Private m_strRegisters() As String
Private m_strFPURegs() As String
Private m_strMMRegs() As String
Private m_strKeywords() As String
Private m_strRawData() As String

Public Instructions() As Instruction
Public InstructionCount As Long

Private m_blnInit As Boolean


Private Sub AddInstr(inst As Instruction)
ReDim Preserve Instructions(InstructionCount) As Instruction
Instructions(InstructionCount) = inst
InstructionCount = InstructionCount + 1
End Sub


Public Sub InitInstructions()
If Not m_blnInit Then
m_strConditions = Split(RemoveWSDoubles(CONDITIONS), " ")
m_strSegments = Split(RemoveWSDoubles(SEGMENT_REGS), " ")
m_strRegisters = Split(RemoveWSDoubles(Registers), " ")
m_strFPURegs = Split(RemoveWSDoubles(FPU_REGS), " ")
m_strKeywords = Split(RemoveWSDoubles(KEYWORDS), " ")
m_strRawData = Split(RemoveWSDoubles(RAW_DATA), " ")
m_strMMRegs = Split(RemoveWSDoubles(MM_REGS), " ")

AddArithmetics
AddFlowCtrl
AddMemory
AddBits
AddFloatingPoint
AddOthers
AddMMXSSE
Add3DNow

m_blnInit = True
End If
End Sub


Private Sub Add3DNow()
' besser wäre ein Präfix für Immediates, die bis
' zur Assemblierung unsichtbar bleiben sein sollen
Instruction "FEMMS ", "0F 0E ", SizeModNone, ExtNon
Instruction "PAVGUSB ", "0F 0F ", SizeModNone, Ext3DN, "mm", "mm/mem", "&HBF"
Instruction "PF2ID ", "0F 0F ", SizeModNone, Ext3DN, "mm", "mm/mem", "&H1D"
Instruction "PFACC ", "0F 0F ", SizeModNone, Ext3DN, "mm", "mm/mem", "&HAE"
Instruction "PFADD ", "0F 0F ", SizeModNone, Ext3DN, "mm", "mm/mem", "&H9E"
Instruction "PFCMPEQ ", "0F 0F ", SizeModNone, Ext3DN, "mm", "mm/mem", "&HB0"
Instruction "PFCMPGE ", "0F 0F ", SizeModNone, Ext3DN, "mm", "mm/mem", "&H90"
Instruction "PFCMPGT ", "0F 0F ", SizeModNone, Ext3DN, "mm", "mm/mem", "&HA0"
Instruction "PFMAX ", "0F 0F ", SizeModNone, Ext3DN, "mm", "mm/mem", "&HA4"
Instruction "PFMIN ", "0F 0F ", SizeModNone, Ext3DN, "mm", "mm/mem", "&H94"
Instruction "PFMUL ", "0F 0F ", SizeModNone, Ext3DN, "mm", "mm/mem", "&HB4"
Instruction "PFRCP ", "0F 0F ", SizeModNone, Ext3DN, "mm", "mm/mem", "&H96"
Instruction "PFRCPIT1 ", "0F 0F ", SizeModNone, Ext3DN, "mm", "mm/mem", "&HA6"
Instruction "PFRCPIT2 ", "0F 0F ", SizeModNone, Ext3DN, "mm", "mm/mem", "&HB6"
Instruction "PFRSQIT1 ", "0F 0F ", SizeModNone, Ext3DN, "mm", "mm/mem", "&HA7"
Instruction "PFRSQRT ", "0F 0F ", SizeModNone, Ext3DN, "mm", "mm/mem", "&H97"
Instruction "PFSUB ", "0F 0F ", SizeModNone, Ext3DN, "mm", "mm/mem", "&H9A"
Instruction "PFSUBR ", "0F 0F ", SizeModNone, Ext3DN, "mm", "mm/mem", "&HAA"
Instruction "PI2FD ", "0F 0F ", SizeModNone, Ext3DN, "mm", "mm/mem", "&H0D"
Instruction "PMULHRW ", "0F 0F ", SizeModNone, Ext3DN, "mm", "mm/mem", "&HB7"
Instruction "PREFETCH ", "0F 0D /0", SizeModNone, ExtNon, "mem"
Instruction "PREFETCHW ", "0F 0D /1", SizeModNone, ExtNon, "mem"
End Sub


Private Sub AddMMXSSE()
Instruction "ADDPD ", "66 0F 58 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "ADDPS ", "0F 58 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "ADDSD ", "F2 0F 58 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "ADDSS ", "F3 0F 58 ", SizeModNone, ExtNon, "xmm", "xmm/mem"

Instruction "ADDSUBPD ", "66 0F D0 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "ADDSUBPS ", "F2 0F D0 ", SizeModNone, ExtNon, "xmm", "xmm/mem"

Instruction "ANDPD ", "66 0F 54 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "ANDPS ", "0F 54 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "ANDNPD ", "66 0F 55 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "ANDNPS ", "0F 55 ", SizeModNone, ExtNon, "xmm", "xmm/mem"

Instruction "CMPPD ", "66 0F C2 ", SizeModNone, ExtNon, "xmm", "xmm/mem", "imm08"
Instruction "CMPPS ", "0F C2 ", SizeModNone, ExtNon, "xmm", "xmm/mem", "imm08"
Instruction "CMPSD ", "F2 0F C2 ", SizeModNone, ExtNon, "xmm", "xmm/mem", "imm08"
Instruction "CMPSS ", "F3 0F C2 ", SizeModNone, ExtNon, "xmm", "xmm/mem", "imm08"

Instruction "COMISD ", "66 0F 2F ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "COMISS ", "0F 2F ", SizeModNone, ExtNon, "xmm", "xmm/mem"

Instruction "CVTDQ2PD ", "F3 0F E6 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "CVTDQ2PS ", "0F 5B ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "CVTPD2DQ ", "F2 0F E6 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "CVTPD2PI ", "66 0F 2D ", SizeModNone, ExtNon, "mm", "xmm/mem"
Instruction "CVTPD2PS ", "66 0F 5A ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "CVTPI2PD ", "66 0F 2A ", SizeModNone, ExtNon, "xmm", "mm/mem"
Instruction "CVTPI2PS ", "0F 2A ", SizeModNone, ExtNon, "xmm", "mm/mem"
Instruction "CVTPS2DQ ", "66 0F 5B ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "CVTPS2PD ", "0F 5A ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "CVTPS2PI ", "0F 2D ", SizeModNone, ExtNon, "mm", "xmm/mem"
Instruction "CVTSD2SI ", "F2 0F 2D ", SizeModNone, ExtNon, "reg32", "xmm/mem"
Instruction "CVTSD2SS ", "F2 0F 5A ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "CVTSI2SD ", "F2 0F 2A ", SizeModNone, ExtNon, "xmm", "rem32"
Instruction "CVTSI2SS ", "F3 0F 2A ", SizeModNone, ExtNon, "xmm", "rem32"
Instruction "CVTSS2SD ", "F3 0F 5A ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "CVTSS2SI ", "F3 0F 2D ", SizeModNone, ExtNon, "reg32", "xmm/mem"
Instruction "CVTTPD2PI ", "66 0F 2C ", SizeModNone, ExtNon, "mm", "xmm/mem"
Instruction "CVTTPD2DQ ", "66 0F E6 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "CVTTPS2DQ ", "F3 0F 5B ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "CVTTPS2PI ", "0F 2C ", SizeModNone, ExtNon, "mm", "xmm/mem"
Instruction "CVTTSD2SI ", "F2 0F 2C ", SizeModNone, ExtNon, "reg32", "xmm/mem"
Instruction "CVTTSS2SI ", "F3 0F 2C ", SizeModNone, ExtNon, "reg32", "xmm/mem"

Instruction "DIVPD ", "66 0F 5E ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "DIVPS ", "0F 5E ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "DIVSD ", "F2 0F 5E ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "DIVSS ", "F3 0F 5E ", SizeModNone, ExtNon, "xmm", "xmm/mem"

Instruction "EMMS ", "0F 77 ", SizeModNone, ExtNon

Instruction "HADDPD ", "66 0F 7C ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "HADDPS ", "F2 0F 7C ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "HSUBPD ", "66 0F 7D ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "HSUBPS ", "F2 0F 7D ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "LDDQU ", "F2 0F F0 ", SizeModNone, ExtNon, "xmm", "mem "
Instruction "LDMXCSR ", "0F AE /2 ", SizeModNone, ExtNon, "mem"
Instruction "MASKMOVDQU ", "66 0F F7 ", SizeModNone, ExtNon, "xmm", "xmm"
Instruction "MASKMOVQ ", "0F F7 ", SizeModNone, ExtNon, "mm", "mm"

Instruction "MAXPD ", "66 0F 5F ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "MAXPS ", "0F 5F ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "MAXSD ", "F2 0F 5F ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "MAXSS ", "F3 0F 5F ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "MINPD ", "66 0F 5D ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "MINPS ", "0F 5D ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "MINSD ", "F2 0F 5D ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "MINSS ", "F3 0F 5D ", SizeModNone, ExtNon, "xmm", "xmm/mem"

Instruction "MOVAPD ", "66 0F 28 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "MOVAPS ", "0F 28 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "MOVD ", "0F 6E ", SizeModNone, ExtNon, "mm ", "rem32"
Instruction "MOVD ", "0F 7E ", SizeModNone, ExtNon, "rem32", "mm "
Instruction "MOVD ", "66 0F 6E ", SizeModNone, ExtNon, "xmm", "rem32"
Instruction "MOVD ", "66 0F 7E ", SizeModNone, ExtNon, "rem32", "xmm"

Instruction "MOVDDUP ", "F2 0F 12 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "MOVDQA ", "66 0F 6F ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "MOVDQA ", "66 0F 7F ", SizeModNone, ExtNon, "xmm/mem", "xmm"
Instruction "MOVDQU ", "F3 0F 6F ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "MOVDQU ", "F3 0F 7F ", SizeModNone, ExtNon, "xmm/mem", "xmm"
Instruction "MOVDQ2Q ", "F2 0F D6 ", SizeModNone, ExtNon, "mm", "xmm"
Instruction "MOVHLPS ", "0F 12 ", SizeModNone, ExtNon, "xmm", "xmm"
Instruction "MOVHPD ", "66 0F 16 ", SizeModNone, ExtNon, "xmm", "mem"
Instruction "MOVHPD ", "66 0F 17 ", SizeModNone, ExtNon, "mem", "xmm"
Instruction "MOVHPS ", "0F 16 ", SizeModNone, ExtNon, "xmm", "mem"
Instruction "MOVHPS ", "0F 17 ", SizeModNone, ExtNon, "mem", "xmm"
Instruction "MOVLHPS ", "0F 16 ", SizeModNone, ExtNon, "xmm", "xmm"
Instruction "MOVLPD ", "66 0F 12 ", SizeModNone, ExtNon, "xmm", "mem"
Instruction "MOVLPD ", "66 0F 13 ", SizeModNone, ExtNon, "mem", "xmm"
Instruction "MOVLPS ", "0F 12 ", SizeModNone, ExtNon, "xmm", "mem"
Instruction "MOVLPS ", "0F 13 ", SizeModNone, ExtNon, "mem", "xmm"

Instruction "MOVMSKPD ", "66 0F 50 ", SizeModNone, ExtNon, "reg32", "xmm"
Instruction "MOVMSKPS ", "0F 50 ", SizeModNone, ExtNon, "reg32", "xmm"
Instruction "MOVNTDQ ", "66 0F E7 ", SizeModNone, ExtNon, "mem", "xmm"
Instruction "MOVNTI ", "0F C3 ", SizeModNone, ExtNon, "mem", "reg32"
Instruction "MOVNTPD ", "66 0F 2B ", SizeModNone, ExtNon, "mem", "xmm"
Instruction "MOVNTPS ", "0F 2B ", SizeModNone, ExtNon, "mem", "xmm"
Instruction "MOVNTQ ", "0F E7 ", SizeModNone, ExtNon, "mem", "mm"
Instruction "MOVQ ", "0F 6F ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "MOVQ ", "0F 7F ", SizeModNone, ExtNon, "mm/mem", "mm"
Instruction "MOVQ ", "F3 0F 7E ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "MOVQ ", "66 0F D6 ", SizeModNone, ExtNon, "xmm/mem", "xmm"
Instruction "MOVQ2DQ ", "F3 0F D6 ", SizeModNone, ExtNon, "xmm", "mm"
Instruction "MOVSD ", "F2 0F 10 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "MOVSD ", "F2 0F 11 ", SizeModNone, ExtNon, "xmm/mem", "xmm"
Instruction "MOVSHDUP ", "F3 0F 16 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "MOVSLDUP ", "F3 0F 12 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "MOVSS ", "F3 0F 10 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "MOVSS ", "F3 0F 11 ", SizeModNone, ExtNon, "xmm/mem", "xmm"
Instruction "MOVUPD ", "66 0F 10 ", SizeModNone, ExtNon, "xmm", "mm/mem"
Instruction "MOVUPD ", "66 0F 11 ", SizeModNone, ExtNon, "xmm/mem", "xmm"
Instruction "MOVUPS ", "0F 10 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "MOVUPS ", "0F 11 ", SizeModNone, ExtNon, "xmm/mem", "xmm"
Instruction "MULPD ", "66 0F 59 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "MULPS ", "0F 59 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "MULSD ", "F2 0F 59 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "MULSS ", "F3 0F 59 ", SizeModNone, ExtNon, "xmm", "xmm/mem"

Instruction "ORPD ", "66 0F 56 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "ORPS ", "0F 56 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PABSB ", "0F 38 1C ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PABSB ", "66 0F 38 1C ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PABSW ", "0F 38 1D ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PABSW ", "66 0F 38 1D ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PABSD ", "0F 38 1E ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PABSD ", "66 0F 38 1E ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PACKSSWB ", "0F 63 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PACKSSWB ", "66 0F 63 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PACKSSDW ", "0F 6B ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PACKSSDW ", "66 0F 6B ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PACKUSWB ", "0F 67 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PACKUSWB ", "66 0F 67 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PADDB ", "0F FC ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PADDB ", "66 0F FC ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PADDW ", "0F FD ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PADDW ", "66 0F FD ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PADDD ", "0F FE ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PADDD ", "66 0F FE ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PADDQ ", "0F D4 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PADDQ ", "66 0F D4 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PADDSB ", "0F EC ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PADDSB ", "66 0F EC ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PADDSW ", "0F ED ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PADDSW ", "66 0F ED ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PADDUSB ", "0F DC ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PADDUSB ", "66 0F DC ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PADDUSW ", "0F DD ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PADDUSW ", "66 0F DD ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PALIGNR ", "0F 3A 0F ", SizeModNone, ExtNon, "mm", "mm/mem", "imm08"
Instruction "PALIGNR ", "66 0F 3A 0F ", SizeModNone, ExtNon, "xmm", "xmm/mem", "imm08"
Instruction "PAND ", "0F DB ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PAND ", "66 0F DB ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PANDN ", "0F DF ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PANDN ", "66 0F DF ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PAVGB ", "0F E0 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PAVGB ", "66 0F E0 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PAVGW ", "0F E3 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PAVGW ", "66 0F E3 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PCMPEQB ", "0F 74 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PCMPEQB ", "66 0F 74 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PCMPEQW ", "0F 75 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PCMPEQW ", "66 0F 75 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PCMPEQD ", "0F 76 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PCMPEQD ", "66 0F 76 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PCMPGTB ", "0F 64 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PCMPGTB ", "66 0F 64 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PCMPGTW ", "0F 65 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PCMPGTW ", "66 0F 65 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PCMPGTD ", "0F 66 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PCMPGTD ", "66 0F 66 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PEXTRW ", "0F C5 ", SizeModNone, ExtNon, "reg32", "mm", "imm08"
Instruction "PEXTRW ", "66 0F C5 ", SizeModNone, ExtNon, "reg32", "xmm", "imm08"
Instruction "PHADDW ", "0F 38 01 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PHADDW ", "66 0F 38 01 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PHADDD ", "0F 38 02 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PHADDD ", "66 0F 38 02 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PHADDSW ", "0F 38 03 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PHADDSW ", "66 0F 38 03 ", SizeModNone, ExtNon, "xmm", "xmm/mem"

Instruction "PHSUBW ", "0F 38 05 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PHSUBW ", "66 0F 38 05 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PHSUBD ", "0F 38 06 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PHSUBD ", "66 0F 38 06 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PHSUBSW ", "0F 38 07 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PHSUBSW ", "66 0F 38 07 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PINSRW ", "0F C4 ", SizeModNone, ExtNon, "mm", "rem32", "imm08"
Instruction "PINSRW ", "66 0F C4 ", SizeModNone, ExtNon, "xmm", "rem32", "imm08"
Instruction "PMADDUBSW ", "0F 38 04 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PMADDUBSW ", "66 0F 38 04 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PMADDWD ", "0F F5 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PMADDWD ", "66 0F F5 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PMAXSW ", "0F EE ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PMAXSW ", "66 0F EE ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PMAXUB ", "0F DE ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PMAXUB ", "66 0F DE ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PMINSW ", "0F EA ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PMINSW ", "66 0F EA ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PMINUB ", "0F DA ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PMINUB ", "66 0F DA ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PMOVMSKB ", "0F D7 ", SizeModNone, ExtNon, "reg32", "mm"
Instruction "PMOVMSKB ", "66 0F D7 ", SizeModNone, ExtNon, "reg32", "xmm"
Instruction "PMULHRSW ", "0F 38 0B ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PMULHRSW ", "66 0F 38 0B ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PMULHUW ", "0F E4 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PMULHUW ", "66 0F E4 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PMULHW ", "0F E5 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PMULHW ", "66 0F E5 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PMULLW ", "0F D5 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PMULLW ", "66 0F D5 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PMULUDQ ", "0F F4 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PMULUDQ ", "66 OF F4 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "POR ", "0F EB ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "POR ", "66 0F EB ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PSADBW ", "0F F6 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PSADBW ", "66 0F F6 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PSHUFB ", "0F 38 00 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PSHUFB ", "66 0F 38 00 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PSHUFD ", "66 0F 70 ", SizeModNone, ExtNon, "xmm", "xmm/mem", "imm08"
Instruction "PSHUFHW ", "F3 0F 70 ", SizeModNone, ExtNon, "xmm", "xmm/mem", "imm08"
Instruction "PSHUFLW ", "F2 0F 70 ", SizeModNone, ExtNon, "xmm", "xmm/mem", "imm08"
Instruction "PSHUFW ", "0F 70 ", SizeModNone, ExtNon, "mm", "mm/mem", "imm08"

Instruction "PSIGNB ", "0F 38 08 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PSIGNB ", "66 0F 38 08 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PSIGNW ", "0F 38 09 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PSIGNW ", "66 0F 38 09 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PSIGND ", "0F 38 0A ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PSIGND ", "66 0F 38 0A ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PSLLDQ ", "66 0F 73 /7 ", SizeModNone, ExtNon, "xmm", "imm08"

Instruction "PSLLW ", "0F F1 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PSLLW ", "66 0F F1 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PSLLW ", "0F 71 /6 ", SizeModNone, ExtNon, "mm", "imm08"
Instruction "PSLLW ", "66 0F 71 /6 ", SizeModNone, ExtNon, "xmm", "imm08"
Instruction "PSLLD ", "0F F2 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PSLLD ", "66 0F F2 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PSLLD ", "0F 72 /6 ", SizeModNone, ExtNon, "mm", "imm08"
Instruction "PSLLD ", "66 0F 72 /6 ", SizeModNone, ExtNon, "xmm", "imm08"
Instruction "PSLLQ ", "0F F3 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PSLLQ ", "66 0F F3 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PSLLQ ", "0F 73 /6 ", SizeModNone, ExtNon, "mm", "imm08"
Instruction "PSLLQ ", "66 0F 73 /6 ", SizeModNone, ExtNon, "xmm", "imm08"

Instruction "PSRAW ", "0F E1 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PSRAW ", "66 0F E1 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PSRAW ", "0F 71 /4 ", SizeModNone, ExtNon, "mm", "imm08"
Instruction "PSRAW ", "66 0F 71 /4 ", SizeModNone, ExtNon, "xmm", "imm08"
Instruction "PSRAD ", "0F E2 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PSRAD ", "66 0F E2 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PSRAD ", "0F 72 /4 ", SizeModNone, ExtNon, "mm", "imm08"
Instruction "PSRAD ", "66 0F 72 /4 ", SizeModNone, ExtNon, "xmm", "imm08"
Instruction "PSRLDQ ", "66 0F 73 /3 ", SizeModNone, ExtNon, "xmm", "imm08"

Instruction "PSRLW ", "0F D1 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PSRLW ", "66 0F D1 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PSRLW ", "0F 71 /2 ", SizeModNone, ExtNon, "mm", "imm08"
Instruction "PSRLW ", "66 0F 71 /2 ", SizeModNone, ExtNon, "xmm", "imm08"
Instruction "PSRLD ", "0F D2 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PSRLD ", "66 0F D2 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PSRLD ", "0F 72 /2 ", SizeModNone, ExtNon, "mm", "imm08"
Instruction "PSRLD ", "66 0F 72 /2 ", SizeModNone, ExtNon, "xmm", "imm08"
Instruction "PSRLQ ", "0F D3 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PSRLQ ", "66 0F D3 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PSRLQ ", "0F 73 /2 ", SizeModNone, ExtNon, "mm", "imm08"
Instruction "PSRLQ ", "66 0F 73 /2 ", SizeModNone, ExtNon, "xmm", "imm08"

Instruction "PSUBB ", "0F F8 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PSUBB ", "66 0F F8 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PSUBW ", "0F F9 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PSUBW ", "66 0F F9 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PSUBD ", "0F FA ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PSUBD ", "66 0F FA ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PSUBQ ", "0F FB ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PSUBQ ", "66 0F FB ", SizeModNone, ExtNon, "xmm", "xmm/mem"

Instruction "PSUBSB ", "0F E8 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PSUBSB ", "66 0F E8 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PSUBSW ", "0F E9 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PSUBSW ", "66 0F E9 ", SizeModNone, ExtNon, "xmm", "xmm/mem"

Instruction "PSUBUSB ", "0F D8 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PSUBUSB ", "66 0F D8 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PSUBUSW ", "0F D9 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PSUBUSW ", "66 0F D9 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PUNPCKHBW ", "0F 68 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PUNPCKHBW ", "66 0F 68 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PUNPCKHWD ", "0F 69 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PUNPCKHWD ", "66 0F 69 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PUNPCKHDQ ", "0F 6A ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PUNPCKHDQ ", "66 0F 6A ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PUNPCKHQDQ ", "66 0F 6D ", SizeModNone, ExtNon, "xmm", "xmm/mem"

Instruction "PUNPCKLBW ", "0F 60 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PUNPCKLBW ", "66 0F 60 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PUNPCKLWD ", "0F 61 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PUNPCKLWD ", "66 0F 61 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PUNPCKLDQ ", "0F 62 ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PUNPCKLDQ ", "66 0F 62 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "PUNPCKLQDQ ", "66 0F 6C ", SizeModNone, ExtNon, "xmm", "xmm/mem"

Instruction "PXOR ", "0F EF ", SizeModNone, ExtNon, "mm", "mm/mem"
Instruction "PXOR ", "66 0F EF ", SizeModNone, ExtNon, "xmm", "xmm/mem"

Instruction "RCPPS ", "0F 53 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "RCPSS ", "F3 0F 53 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "RSQRTPS ", "0F 52 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "RSQRTSS ", "F3 0F 52 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "SHUFPD ", "66 0F C6 ", SizeModNone, ExtNon, "xmm", "xmm/mem", "imm08"
Instruction "SHUFPS ", "0F C6 ", SizeModNone, ExtNon, "xmm", "xmm/mem", "imm08"
Instruction "SQRTPS ", "0F 51 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "SQRTSD ", "F2 0F 51 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "SQRTSS ", "F3 0F 51 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "SUBPD ", "66 0F 5C ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "SUBPS ", "0F 5C ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "SUBSD ", "F2 0F 5C ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "SUBSS ", "F3 0F 5C ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "UCOMISD ", "66 0F 2E ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "UCOMISS ", "0F 2E ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "UNPCKHPD ", "66 0F 15 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "UNPCKHPS ", "0F 15 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "UNPCKLPD ", "66 0F 14 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "UNPCKLPS ", "0F 14 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "XORPD ", "66 0F 57 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
Instruction "XORPS ", "0F 57 ", SizeModNone, ExtNon, "xmm", "xmm/mem"
End Sub


Private Sub AddOthers()
Instruction "AAA ", "37 ", SizeModNone, ExtNon
Instruction "AAD ", "D5 0A ", SizeModNone, ExtNon
Instruction "AAM ", "D4 0A ", SizeModNone, ExtNon
Instruction "AAS ", "3F ", SizeModNone, ExtNon
Instruction "DAA ", "27 ", SizeModNone, ExtNon
Instruction "DAS ", "2F ", SizeModNone, ExtNon

Instruction "BOUND ", "62 ", SizeModOvrd, ExtNon, "reg16", "mem16"
Instruction "BOUND ", "62 ", SizeModNone, ExtNon, "reg32", "mem32"

Instruction "LAHF ", "9F ", SizeModNone, ExtNon
Instruction "SAHF ", "9E ", SizeModNone, ExtNon
Instruction "LAR ", "0F 02 ", SizeModOvrd, ExtNon, "reg16", "rem16"
Instruction "LAR ", "0F 02 ", SizeModNone, ExtNon, "reg32", "rem32"

Instruction "LEA ", "8D ", SizeModOvrd, ExtNon, "reg16", "mem "
Instruction "LEA ", "8D ", SizeModNone, ExtNon, "reg32", "mem "

Instruction "BSWAP ", "0F C8 ", SizeModNone, ExtReg, "#32"

Instruction "SCASB ", "AE ", SizeModNone, ExtNon
Instruction "SCASW ", "AF ", SizeModOvrd, ExtNon
Instruction "SCASD ", "AF ", SizeModNone, ExtNon

Instruction "SMSW ", "0F 01 /4", SizeModOvrd, ExtNon, "rem16"
Instruction "SMSW ", "0F 01 /4", SizeModNone, ExtNon, "rem32"

Instruction "STC ", "F9 ", SizeModNone, ExtNon
Instruction "STD ", "FD ", SizeModNone, ExtNon
Instruction "STI ", "FB ", SizeModNone, ExtNon

Instruction "CBW ", "98 ", SizeModOvrd, ExtNon
Instruction "CWWDE ", "98 ", SizeModNone, ExtNon
Instruction "CLC ", "F8 ", SizeModNone, ExtNon
Instruction "CLD ", "FC ", SizeModNone, ExtNon
Instruction "CMC ", "F5 ", SizeModNone, ExtNon
Instruction "CWD ", "99 ", SizeModOvrd, ExtNon
Instruction "CDQ ", "99 ", SizeModNone, ExtNon

Instruction "CPUID ", "0F A2 ", SizeModNone, ExtNon

Instruction "RDMSR ", "0F 32 ", SizeModNone, ExtNon
Instruction "RDPMC ", "0F 33 ", SizeModNone, ExtNon
Instruction "RDTSC ", "0F 31 ", SizeModNone, ExtNon
End Sub


Private Sub AddMemory()
Instruction "LODSB ", "AC ", SizeModNone, ExtNon
Instruction "LODSW ", "AD ", SizeModOvrd, ExtNon
Instruction "LODSD ", "AD ", SizeModNone, ExtNon

Instruction "STOSB ", "AA ", SizeModNone, ExtNon
Instruction "STOSW ", "AB ", SizeModOvrd, ExtNon
Instruction "STOSD ", "AB ", SizeModNone, ExtNon

Instruction "PUSH ", "50 ", SizeModOvrd, ExtReg, "#16 "
Instruction "PUSH ", "50 ", SizeModNone, ExtReg, "#32 "
Instruction "PUSH ", "FF /6 ", SizeModOvrd, ExtNon, "rem16"
Instruction "PUSH ", "FF /6 ", SizeModNone, ExtNon, "rem32"
Instruction "PUSH ", "6A ", SizeModNone, ExtNon, "imm08"
Instruction "PUSH ", "68 ", SizeModOvrd, ExtNon, "imm16"
Instruction "PUSH ", "68 ", SizeModNone, ExtNon, "imm32"
' keine segment pushs
Instruction "PUSHA ", "60 ", SizeModOvrd, ExtNon
Instruction "PUSHAD ", "60 ", SizeModNone, ExtNon
Instruction "PUSHF ", "9C ", SizeModOvrd, ExtNon
Instruction "PUSHFD ", "9C ", SizeModNone, ExtNon

Instruction "POP ", "58 ", SizeModOvrd, ExtReg, "#16 "
Instruction "POP ", "58 ", SizeModNone, ExtReg, "#32 "
Instruction "POP ", "8F /0 ", SizeModOvrd, ExtNon, "rem16"
Instruction "POP ", "8F /0 ", SizeModNone, ExtNon, "rem32"
' keine segment pops
Instruction "POPA ", "61 ", SizeModOvrd, ExtNon
Instruction "POPAD ", "61 ", SizeModNone, ExtNon
Instruction "POPF ", "9D ", SizeModOvrd, ExtNon
Instruction "POPFD ", "9D ", SizeModNone, ExtNon

Instruction "XLAT ", "D7 ", SizeModNone, ExtNon
Instruction "XLATB ", "D7 ", SizeModNone, ExtNon

Instruction "XCHG ", "90 ", SizeModOvrd, ExtReg, "AX ", "#16 "
Instruction "XCHG ", "90 ", SizeModOvrd, ExtReg, "#16 ", "AX "
Instruction "XCHG ", "90 ", SizeModNone, ExtReg, "EAX ", "#32 "
Instruction "XCHG ", "90 ", SizeModNone, ExtReg, "#32 ", "EAX "
Instruction "XCHG ", "86 ", SizeModNone, ExtNon, "rem08", "reg08"
Instruction "XCHG ", "86 ", SizeModNone, ExtNon, "reg08", "rem08"
Instruction "XCHG ", "87 ", SizeModOvrd, ExtNon, "rem16", "reg16"
Instruction "XCHG ", "87 ", SizeModOvrd, ExtNon, "reg16", "rem16"
Instruction "XCHG ", "87 ", SizeModNone, ExtNon, "rem32", "reg32"
Instruction "XCHG ", "87 ", SizeModNone, ExtNon, "reg32", "rem32"

Instruction "MOV ", "A0 ", SizeModNone, ExtNon, "AL ", "mem08"
Instruction "MOV ", "A1 ", SizeModOvrd, ExtNon, "AX ", "mem16"
Instruction "MOV ", "A1 ", SizeModNone, ExtNon, "EAX ", "mem32"
Instruction "MOV ", "A2 ", SizeModNone, ExtNon, "mem08", "AL "
Instruction "MOV ", "A3 ", SizeModOvrd, ExtNon, "mem16", "AX "
Instruction "MOV ", "A3 ", SizeModNone, ExtNon, "mem32", "EAX "
Instruction "MOV ", "B0 ", SizeModNone, ExtReg, "#08 ", "imm08"
Instruction "MOV ", "B8 ", SizeModOvrd, ExtReg, "#16 ", "imm16"
Instruction "MOV ", "B8 ", SizeModNone, ExtReg, "#32 ", "imm32"
Instruction "MOV ", "88 ", SizeModNone, ExtNon, "rem08", "reg08"
Instruction "MOV ", "89 ", SizeModOvrd, ExtNon, "rem16", "reg16"
Instruction "MOV ", "89 ", SizeModNone, ExtNon, "rem32", "reg32"
Instruction "MOV ", "8A ", SizeModNone, ExtNon, "reg08", "rem08"
Instruction "MOV ", "8B ", SizeModOvrd, ExtNon, "reg16", "rem16"
Instruction "MOV ", "8B ", SizeModNone, ExtNon, "reg32", "rem32"
Instruction "MOV ", "C6 /0 ", SizeModNone, ExtNon, "rem08", "imm08"
Instruction "MOV ", "C7 /0 ", SizeModOvrd, ExtNon, "rem16", "imm16"
Instruction "MOV ", "C7 /0 ", SizeModNone, ExtNon, "rem32", "imm32"

Instruction "MOVZX ", "0F B6 ", SizeModOvrd, ExtNon, "reg16", "rem08"
Instruction "MOVZX ", "0F B6 ", SizeModNone, ExtNon, "reg32", "rem08"
Instruction "MOVZX ", "0F B7 ", SizeModNone, ExtNon, "reg32", "rem16"

Instruction "MOVSX ", "0F BE ", SizeModOvrd, ExtNon, "reg16", "rem08"
Instruction "MOVSX ", "0F BE ", SizeModNone, ExtNon, "reg32", "rem08"
Instruction "MOVSX ", "0F BF ", SizeModNone, ExtNon, "reg32", "rem16"
End Sub


Private Sub AddFlowCtrl()
Instruction "CMP ", "3C ", SizeModNone, ExtNon, "AL ", "imm08"
Instruction "CMP ", "3D ", SizeModOvrd, ExtNon, "AX ", "imm16"
Instruction "CMP ", "3D ", SizeModNone, ExtNon, "EAX ", "imm32"
Instruction "CMP ", "80 /7 ", SizeModNone, ExtNon, "rem08", "imm08"
Instruction "CMP ", "81 /7 ", SizeModOvrd, ExtNon, "rem16", "imm16"
Instruction "CMP ", "81 /7 ", SizeModNone, ExtNon, "rem32", "imm32"
Instruction "CMP ", "83 /7 ", SizeModOvrd, ExtNon, "rem16", "imm08"
Instruction "CMP ", "83 /7 ", SizeModNone, ExtNon, "rem32", "imm08"
Instruction "CMP ", "38 ", SizeModNone, ExtNon, "rem08", "reg08"
Instruction "CMP ", "39 ", SizeModOvrd, ExtNon, "rem16", "reg16"
Instruction "CMP ", "39 ", SizeModNone, ExtNon, "rem32", "reg32"
Instruction "CMP ", "3A ", SizeModNone, ExtNon, "reg08", "rem08"
Instruction "CMP ", "3B ", SizeModOvrd, ExtNon, "reg16", "rem16"
Instruction "CMP ", "3B ", SizeModNone, ExtNon, "reg32", "rem32"

Instruction "CMOV ", "0F 40 ", SizeModOvrd, ExtCon, "reg16", "rem16"
Instruction "CMOV ", "0F 40 ", SizeModNone, ExtCon, "reg32", "rem32"

Instruction "CMPSB ", "A6 ", SizeModNone, ExtNon
Instruction "CMPSW ", "A7 ", SizeModOvrd, ExtNon
Instruction "CMPSD ", "A7 ", SizeModNone, ExtNon

Instruction "CMPXCHG", "0F B0 ", SizeModNone, ExtNon, "rem08", "reg08"
Instruction "CMPXCHG", "0F B1 ", SizeModOvrd, ExtNon, "rem16", "reg16"
Instruction "CMPXCHG", "0F B1 ", SizeModNone, ExtNon, "rem32", "reg32"

Instruction "CMPXCHG8B", "0F C7 /1", SizeModNone, ExtNon, "mem"

Instruction "J ", "0F 80 ", SizeModNone, ExtCon, "rel32"
Instruction "J ", "0F 80 ", SizeModOvrd, ExtCon, "rel16"
Instruction "J ", "70 ", SizeModNone, ExtCon, "rel08"
Instruction "JCXZ ", "E3 ", SizeModOvrd, ExtNon, "rel08"
Instruction "JECXZ ", "E3 ", SizeModNone, ExtNon, "rel08"

Instruction "JMP ", "E9 ", SizeModNone, ExtNon, "rel32"
Instruction "JMP ", "E9 ", SizeModOvrd, ExtNon, "rel16"
Instruction "JMP ", "EB ", SizeModNone, ExtNon, "rel08"
Instruction "JMP ", "FF /4 ", SizeModOvrd, ExtNon, "rem16"
Instruction "JMP ", "FF /4 ", SizeModNone, ExtNon, "rem32"
' keine far jumps (braucht man eh nich im Virtual Mode?)

Instruction "HLT ", "F4 ", SizeModNone, ExtNon
Instruction "NOP ", "90 ", SizeModNone, ExtNon

Instruction "RET ", "C3 ", SizeModNone, ExtNon
Instruction "RET ", "C2 ", SizeModNone, ExtNon, "imm16"
' keine far returns

Instruction "CALL ", "E8 ", SizeModNone, ExtNon, "rel32"
Instruction "CALL ", "E8 ", SizeModOvrd, ExtNon, "rel16"
Instruction "CALL ", "FF /2 ", SizeModOvrd, ExtNon, "rem16"
Instruction "CALL ", "FF /2 ", SizeModNone, ExtNon, "rem32"
' keine far calls

Instruction "INT ", "CC ", SizeModNone, ExtNon, "3 "
Instruction "INT ", "CD ", SizeModNone, ExtNon, "imm08"

Instruction "ENTER ", "C8 ", SizeModNone, ExtNon, "imm16", "imm08"
Instruction "LEAVE ", "C9 ", SizeModNone, ExtNon

Instruction "SET ", "0F 90 ", SizeModNone, ExtCon, "rem08"

Instruction "LOOP ", "E2 ", SizeModNone, ExtNon, "rel08"
Instruction "LOOPE ", "E1 ", SizeModNone, ExtNon, "rel08"
Instruction "LOOPNE ", "E0 ", SizeModNone, ExtNon, "rel08"
End Sub


Private Sub AddBits()
Instruction "BT ", "0F A3 ", SizeModOvrd, ExtNon, "rem16", "reg16"
Instruction "BT ", "0F A3 ", SizeModNone, ExtNon, "rem32", "reg32"
Instruction "BT ", "0F BA /4", SizeModOvrd, ExtNon, "rem16", "imm08"
Instruction "BT ", "0F BA /4", SizeModNone, ExtNon, "rem32", "imm08"
Instruction "BTC ", "0F BB ", SizeModOvrd, ExtNon, "rem16", "reg16"
Instruction "BTC ", "0F BB ", SizeModNone, ExtNon, "rem32", "reg32"
Instruction "BTC ", "0F BB /7", SizeModOvrd, ExtNon, "rem16", "imm08"
Instruction "BTC ", "0F BB /7", SizeModNone, ExtNon, "rem32", "imm08"
Instruction "BTR ", "0F B3 ", SizeModOvrd, ExtNon, "rem16", "reg16"
Instruction "BTR ", "0F B3 ", SizeModNone, ExtNon, "rem32", "reg32"
Instruction "BTR ", "0F BA /6", SizeModOvrd, ExtNon, "rem16", "imm08"
Instruction "BTR ", "0F BA /6", SizeModNone, ExtNon, "rem32", "imm08"
Instruction "BTS ", "0F AB ", SizeModOvrd, ExtNon, "rem16", "reg16"
Instruction "BTS ", "0F AB ", SizeModNone, ExtNon, "rem32", "reg32"
Instruction "BTS ", "0F BA /5", SizeModOvrd, ExtNon, "rem16", "imm08"
Instruction "BTS ", "0F BA /5", SizeModNone, ExtNon, "rem32", "imm08"

Instruction "NEG ", "F6 /3 ", SizeModNone, ExtNon, "rem08"
Instruction "NEG ", "F7 /3 ", SizeModOvrd, ExtNon, "rem16"
Instruction "NEG ", "F7 /3 ", SizeModNone, ExtNon, "rem32"
Instruction "NOT ", "F6 /2 ", SizeModNone, ExtNon, "rem08"
Instruction "NOT ", "F7 /2 ", SizeModOvrd, ExtNon, "rem16"
Instruction "NOT ", "F7 /2 ", SizeModNone, ExtNon, "rem32"

Instruction "SHLD ", "0F A4 ", SizeModOvrd, ExtNon, "rem16", "reg16", "imm08"
Instruction "SHLD ", "0F A4 ", SizeModNone, ExtNon, "rem32", "reg32", "imm08"
Instruction "SHLD ", "0F A5 ", SizeModOvrd, ExtNon, "rem16", "reg16", "CL "
Instruction "SHLD ", "0F A5 ", SizeModNone, ExtNon, "rem32", "reg32", "CL "

Instruction "SHRD ", "0F AC ", SizeModOvrd, ExtNon, "rem16", "reg16", "imm08"
Instruction "SHRD ", "0F AC ", SizeModNone, ExtNon, "rem32", "reg32", "imm08"
Instruction "SHRD ", "0F AD ", SizeModOvrd, ExtNon, "rem16", "reg16", "CL "
Instruction "SHRD ", "0F AD ", SizeModNone, ExtNon, "rem32", "reg32", "CL "

Instruction "SHL ", "D0 /4 ", SizeModNone, ExtNon, "rem08", "1 "
Instruction "SHL ", "D2 /4 ", SizeModNone, ExtNon, "rem08", "CL "
Instruction "SHL ", "C0 /4 ", SizeModNone, ExtNon, "rem08", "imm08"
Instruction "SHL ", "D1 /4 ", SizeModOvrd, ExtNon, "rem16", "1 "
Instruction "SHL ", "D1 /4 ", SizeModNone, ExtNon, "rem32", "1 "
Instruction "SHL ", "D3 /4 ", SizeModOvrd, ExtNon, "rem16", "CL "
Instruction "SHL ", "D3 /4 ", SizeModNone, ExtNon, "rem32", "CL "
Instruction "SHL ", "C1 /4 ", SizeModOvrd, ExtNon, "rem16", "imm08"
Instruction "SHL ", "C1 /4 ", SizeModNone, ExtNon, "rem32", "imm08"

Instruction "SAL ", "D0 /4 ", SizeModNone, ExtNon, "rem08", "1 "
Instruction "SAL ", "D2 /4 ", SizeModNone, ExtNon, "rem08", "CL "
Instruction "SAL ", "C0 /4 ", SizeModNone, ExtNon, "rem08", "imm08"
Instruction "SAL ", "D1 /4 ", SizeModOvrd, ExtNon, "rem16", "1 "
Instruction "SAL ", "D1 /4 ", SizeModNone, ExtNon, "rem32", "1 "
Instruction "SAL ", "D3 /4 ", SizeModOvrd, ExtNon, "rem16", "CL "
Instruction "SAL ", "D3 /4 ", SizeModNone, ExtNon, "rem32", "CL "
Instruction "SAL ", "C1 /4 ", SizeModOvrd, ExtNon, "rem16", "imm08"
Instruction "SAL ", "C1 /4 ", SizeModNone, ExtNon, "rem32", "imm08"

Instruction "SAR ", "D0 /7 ", SizeModNone, ExtNon, "rem08", "1 "
Instruction "SAR ", "D2 /7 ", SizeModNone, ExtNon, "rem08", "CL "
Instruction "SAR ", "C0 /7 ", SizeModNone, ExtNon, "rem08", "imm08"
Instruction "SAR ", "D1 /7 ", SizeModOvrd, ExtNon, "rem16", "1 "
Instruction "SAR ", "D1 /7 ", SizeModNone, ExtNon, "rem32", "1 "
Instruction "SAR ", "D3 /7 ", SizeModOvrd, ExtNon, "rem16", "CL "
Instruction "SAR ", "D3 /7 ", SizeModNone, ExtNon, "rem32", "CL "
Instruction "SAR ", "C1 /7 ", SizeModOvrd, ExtNon, "rem16", "imm08"
Instruction "SAR ", "C1 /7 ", SizeModNone, ExtNon, "rem32", "imm08"

Instruction "SHR ", "D0 /5 ", SizeModNone, ExtNon, "rem08", "1 "
Instruction "SHR ", "D2 /5 ", SizeModNone, ExtNon, "rem08", "CL "
Instruction "SHR ", "C0 /5 ", SizeModNone, ExtNon, "rem08", "imm08"
Instruction "SHR ", "D1 /5 ", SizeModOvrd, ExtNon, "rem16", "1 "
Instruction "SHR ", "D1 /5 ", SizeModNone, ExtNon, "rem32", "1 "
Instruction "SHR ", "D3 /5 ", SizeModOvrd, ExtNon, "rem16", "CL "
Instruction "SHR ", "D3 /5 ", SizeModNone, ExtNon, "rem32", "CL "
Instruction "SHR ", "C1 /5 ", SizeModOvrd, ExtNon, "rem16", "imm08"
Instruction "SHR ", "C1 /5 ", SizeModNone, ExtNon, "rem32", "imm08"

Instruction "RCL ", "D0 /2 ", SizeModNone, ExtNon, "rem08", "1 "
Instruction "RCL ", "D2 /2 ", SizeModNone, ExtNon, "rem08", "CL "
Instruction "RCL ", "C0 /2 ", SizeModNone, ExtNon, "rem08", "imm08"
Instruction "RCL ", "D1 /2 ", SizeModOvrd, ExtNon, "rem16", "1 "
Instruction "RCL ", "D1 /2 ", SizeModNone, ExtNon, "rem32", "1 "
Instruction "RCL ", "D3 /2 ", SizeModOvrd, ExtNon, "rem16", "CL "
Instruction "RCL ", "D3 /2 ", SizeModNone, ExtNon, "rem32", "CL "
Instruction "RCL ", "C1 /2 ", SizeModOvrd, ExtNon, "rem16", "imm08"
Instruction "RCL ", "C1 /2 ", SizeModNone, ExtNon, "rem32", "imm08"

Instruction "RCR ", "D0 /3 ", SizeModNone, ExtNon, "rem08", "1 "
Instruction "RCR ", "D2 /3 ", SizeModNone, ExtNon, "rem08", "CL "
Instruction "RCR ", "C0 /3 ", SizeModNone, ExtNon, "rem08", "imm08"
Instruction "RCR ", "D1 /3 ", SizeModOvrd, ExtNon, "rem16", "1 "
Instruction "RCR ", "D1 /3 ", SizeModNone, ExtNon, "rem32", "1 "
Instruction "RCR ", "D3 /3 ", SizeModOvrd, ExtNon, "rem16", "CL "
Instruction "RCR ", "D3 /3 ", SizeModNone, ExtNon, "rem32", "CL "
Instruction "RCR ", "C1 /3 ", SizeModOvrd, ExtNon, "rem16", "imm08"
Instruction "RCR ", "C1 /3 ", SizeModNone, ExtNon, "rem32", "imm08"

Instruction "ROL ", "D0 /0 ", SizeModNone, ExtNon, "rem08", "1 "
Instruction "ROL ", "D2 /0 ", SizeModNone, ExtNon, "rem08", "CL "
Instruction "ROL ", "C0 /0 ", SizeModNone, ExtNon, "rem08", "imm08"
Instruction "ROL ", "D1 /0 ", SizeModOvrd, ExtNon, "rem16", "1 "
Instruction "ROL ", "D1 /0 ", SizeModNone, ExtNon, "rem32", "1 "
Instruction "ROL ", "D3 /0 ", SizeModOvrd, ExtNon, "rem16", "CL "
Instruction "ROL ", "D3 /0 ", SizeModNone, ExtNon, "rem32", "CL "
Instruction "ROL ", "C1 /0 ", SizeModOvrd, ExtNon, "rem16", "imm08"
Instruction "ROL ", "C1 /0 ", SizeModNone, ExtNon, "rem32", "imm08"

Instruction "ROR ", "D0 /1 ", SizeModNone, ExtNon, "rem08", "1 "
Instruction "ROR ", "D2 /1 ", SizeModNone, ExtNon, "rem08", "CL "
Instruction "ROR ", "C0 /1 ", SizeModNone, ExtNon, "rem08", "imm08"
Instruction "ROR ", "D1 /1 ", SizeModOvrd, ExtNon, "rem16", "1 "
Instruction "ROR ", "D1 /1 ", SizeModNone, ExtNon, "rem32", "1 "
Instruction "ROR ", "D3 /1 ", SizeModOvrd, ExtNon, "rem16", "CL "
Instruction "ROR ", "D3 /1 ", SizeModNone, ExtNon, "rem32", "CL "
Instruction "ROR ", "C1 /1 ", SizeModOvrd, ExtNon, "rem16", "imm08"
Instruction "ROR ", "C1 /1 ", SizeModNone, ExtNon, "rem32", "imm08"

Instruction "TEST ", "A8 ", SizeModNone, ExtNon, "AL ", "imm08"
Instruction "TEST ", "A9 ", SizeModOvrd, ExtNon, "AX ", "imm16"
Instruction "TEST ", "A9 ", SizeModNone, ExtNon, "EAX ", "imm32"
Instruction "TEST ", "F6 /0 ", SizeModNone, ExtNon, "rem08", "imm08"
Instruction "TEST ", "F7 /0 ", SizeModOvrd, ExtNon, "rem16", "imm16"
Instruction "TEST ", "F7 /0 ", SizeModNone, ExtNon, "rem32", "imm32"
Instruction "TEST ", "84 ", SizeModNone, ExtNon, "rem08", "reg08"
Instruction "TEST ", "85 ", SizeModOvrd, ExtNon, "rem16", "reg16"
Instruction "TEST ", "85 ", SizeModNone, ExtNon, "rem32", "reg32"

Instruction "OR ", "0C ", SizeModNone, ExtNon, "AL ", "imm08"
Instruction "OR ", "0D ", SizeModOvrd, ExtNon, "AX ", "imm16"
Instruction "OR ", "0D ", SizeModNone, ExtNon, "EAX ", "imm32"
Instruction "OR ", "80 /1 ", SizeModNone, ExtNon, "rem08", "imm08"
Instruction "OR ", "81 /1 ", SizeModOvrd, ExtNon, "rem16", "imm16"
Instruction "OR ", "81 /1 ", SizeModNone, ExtNon, "rem32", "imm32"
Instruction "OR ", "83 /1 ", SizeModOvrd, ExtNon, "rem16", "imm08"
Instruction "OR ", "83 /1 ", SizeModNone, ExtNon, "rem32", "imm08"
Instruction "OR ", "08 ", SizeModNone, ExtNon, "rem08", "reg08"
Instruction "OR ", "09 ", SizeModOvrd, ExtNon, "rem16", "reg16"
Instruction "OR ", "09 ", SizeModNone, ExtNon, "rem32", "reg32"
Instruction "OR ", "0A ", SizeModNone, ExtNon, "reg08", "rem08"
Instruction "OR ", "0B ", SizeModOvrd, ExtNon, "reg16", "rem16"
Instruction "OR ", "0B ", SizeModNone, ExtNon, "reg32", "rem32"

Instruction "AND ", "24 ", SizeModNone, ExtNon, "AL ", "imm08"
Instruction "AND ", "25 ", SizeModOvrd, ExtNon, "AX ", "imm16"
Instruction "AND ", "25 ", SizeModNone, ExtNon, "EAX ", "imm32"
Instruction "AND ", "80 /4 ", SizeModNone, ExtNon, "rem08", "imm08"
Instruction "AND ", "81 /4 ", SizeModOvrd, ExtNon, "rem16", "imm16"
Instruction "AND ", "81 /4 ", SizeModNone, ExtNon, "rem32", "imm32"
Instruction "AND ", "83 /4 ", SizeModOvrd, ExtNon, "rem16", "imm08"
Instruction "AND ", "83 /4 ", SizeModNone, ExtNon, "rem32", "imm08"
Instruction "AND ", "20 ", SizeModNone, ExtNon, "rem08", "reg08"
Instruction "AND ", "21 ", SizeModOvrd, ExtNon, "rem16", "reg16"
Instruction "AND ", "21 ", SizeModNone, ExtNon, "rem32", "reg32"
Instruction "AND ", "22 ", SizeModNone, ExtNon, "reg08", "rem08"
Instruction "AND ", "23 ", SizeModOvrd, ExtNon, "reg16", "rem16"
Instruction "AND ", "23 ", SizeModNone, ExtNon, "reg32", "rem32"

Instruction "XOR ", "34 ", SizeModNone, ExtNon, "AL ", "imm08"
Instruction "XOR ", "35 ", SizeModOvrd, ExtNon, "AX ", "imm16"
Instruction "XOR ", "35 ", SizeModNone, ExtNon, "EAX ", "imm32"
Instruction "XOR ", "80 /6 ", SizeModNone, ExtNon, "rem08", "imm08"
Instruction "XOR ", "81 /6 ", SizeModOvrd, ExtNon, "rem16", "imm16"
Instruction "XOR ", "81 /6 ", SizeModNone, ExtNon, "rem32", "imm32"
Instruction "XOR ", "83 /6 ", SizeModOvrd, ExtNon, "rem16", "imm08"
Instruction "XOR ", "83 /6 ", SizeModNone, ExtNon, "rem32", "imm08"
Instruction "XOR ", "30 ", SizeModNone, ExtNon, "rem08", "reg08"
Instruction "XOR ", "31 ", SizeModOvrd, ExtNon, "rem16", "reg16"
Instruction "XOR ", "31 ", SizeModNone, ExtNon, "rem32", "reg32"
Instruction "XOR ", "32 ", SizeModNone, ExtNon, "reg08", "rem08"
Instruction "XOR ", "33 ", SizeModOvrd, ExtNon, "reg16", "rem16"
Instruction "XOR ", "33 ", SizeModNone, ExtNon, "reg32", "rem32"

Instruction "BSF ", "0F BC ", SizeModOvrd, ExtNon, "reg16", "rem16"
Instruction "BSF ", "0F BC ", SizeModNone, ExtNon, "reg32", "rem32"
Instruction "BSR ", "0F BD ", SizeModOvrd, ExtNon, "reg16", "rem16"
Instruction "BSR ", "0F BD ", SizeModNone, ExtNon, "reg32", "rem32"
End Sub


Private Sub AddFloatingPoint()
Instruction "FADD ", "D8 /0 ", SizeModNone, ExtNon, "rem32"
Instruction "FADD ", "DC /0 ", SizeModNone, ExtNon, "rem64"
Instruction "FADD ", "D8 C0 ", SizeModNone, ExtFlt, "st0 ", "st# "
Instruction "FADD ", "DC C0 ", SizeModNone, ExtFlt, "st# ", "st0 "
Instruction "FADDP ", "DE C0 ", SizeModNone, ExtFlt, "st# ", "st0 "
Instruction "FADDP ", "DE C1 ", SizeModNone, ExtNon
Instruction "FIADD ", "DA /0 ", SizeModNone, ExtNon, "rem32"
Instruction "FIADD ", "DE /0 ", SizeModNone, ExtNon, "rem16"

Instruction "FABS ", "D9 E1 ", SizeModNone, ExtNon
Instruction "FBLD ", "DF /4 ", SizeModNone, ExtNon, "mem "
Instruction "FBSTP ", "DF /6 ", SizeModNone, ExtNon, "mem "
Instruction "FCHS ", "D9 E0 ", SizeModNone, ExtNon
Instruction "FCLEX ", "9B DB E2", SizeModNone, ExtNon

Instruction "FCMOVB ", "DA C0 ", SizeModNone, ExtFlt, "st0 ", "st# "
Instruction "FCMOVE ", "DA C8 ", SizeModNone, ExtFlt, "st0 ", "st# "
Instruction "FCMOVBE", "DA D0 ", SizeModNone, ExtFlt, "st0 ", "st# "
Instruction "FCMOVU ", "DA D8 ", SizeModNone, ExtFlt, "st0 ", "st# "
Instruction "FCMOVNB", "DB C0 ", SizeModNone, ExtFlt, "st0 ", "st# "
Instruction "FCMOVNE", "DB C8 ", SizeModNone, ExtFlt, "st0 ", "st# "
Instruction "FCMOVNBE", "DB D0 ", SizeModNone, ExtFlt, "st0 ", "st# "
Instruction "FCMOVNU", "DB D8 ", SizeModNone, ExtFlt, "st0 ", "st# "

Instruction "FCOMI ", "DB F0 ", SizeModNone, ExtFlt, "st0 ", "st# "
Instruction "FCOMIP ", "DF F0 ", SizeModNone, ExtFlt, "st0 ", "st# "
Instruction "FUCOMI ", "DB E8 ", SizeModNone, ExtFlt, "st0 ", "st# "
Instruction "FUCOMIP", "DF E8 ", SizeModNone, ExtFlt, "st0 ", "st# "

Instruction "FCOS ", "D9 FF ", SizeModNone, ExtNon
Instruction "FSIN ", "D9 FE ", SizeModNone, ExtNon
Instruction "FSINCOS", "D9 FB ", SizeModNone, ExtNon
Instruction "FDECSTP", "D9 F6 ", SizeModNone, ExtNon

Instruction "FDIV ", "D8 /6 ", SizeModNone, ExtNon, "mem32"
Instruction "FDIV ", "DC /6 ", SizeModNone, ExtNon, "mem64"
Instruction "FDIV ", "D8 F0 ", SizeModNone, ExtFlt, "st0 ", "st# "
Instruction "FDIV ", "DC F8 ", SizeModNone, ExtFlt, "st# ", "st0 "
Instruction "FDIVP ", "DE F8 ", SizeModNone, ExtFlt, "st# ", "st0 "
Instruction "FDIVP ", "DE F9 ", SizeModNone, ExtNon
Instruction "FIDIV ", "DA /6 ", SizeModNone, ExtNon, "mem32"
Instruction "FIDIV ", "DE /6 ", SizeModNone, ExtNon, "mem64"

Instruction "FDIVR ", "D8 /7 ", SizeModNone, ExtNon, "mem32"
Instruction "FDIVR ", "DC /7 ", SizeModNone, ExtNon, "mem64"
Instruction "FDIVR ", "D8 F8 ", SizeModNone, ExtFlt, "st0 ", "st# "
Instruction "FDIVR ", "DC F0 ", SizeModNone, ExtFlt, "st# ", "st0 "
Instruction "FDIVRP ", "DE F0 ", SizeModNone, ExtFlt, "st# ", "st0 "
Instruction "FDIVRP ", "DE F1 ", SizeModNone, ExtNon
Instruction "FIDIVR ", "DA /7 ", SizeModNone, ExtNon, "mem32"
Instruction "FIDIVR ", "DE /7 ", SizeModNone, ExtNon, "mem64"

Instruction "FICOM ", "DE /2 ", SizeModNone, ExtNon, "mem16"
Instruction "FICOM ", "DA /2 ", SizeModNone, ExtNon, "mem32"
Instruction "FICOMP ", "DE /3 ", SizeModNone, ExtNon, "mem16"
Instruction "FICOMP ", "DA /3 ", SizeModNone, ExtNon, "mem32"

Instruction "FILD ", "DF /0 ", SizeModNone, ExtNon, "mem16"
Instruction "FILD ", "DB /0 ", SizeModNone, ExtNon, "mem32"
Instruction "FILD ", "DF /5 ", SizeModNone, ExtNon, "mem64"

Instruction "FINCSTP", "D9 F7 ", SizeModNone, ExtNon
Instruction "FINIT ", "9B DB E3", SizeModNone, ExtNon
Instruction "FFREE ", "DD C0 ", SizeModNone, ExtFlt, "st# "

Instruction "FIST ", "DF /2 ", SizeModNone, ExtNon, "mem16"
Instruction "FIST ", "DB /2 ", SizeModNone, ExtNon, "mem32"
Instruction "FISTP ", "DF /3 ", SizeModNone, ExtNon, "mem16"
Instruction "FISTP ", "DB /3 ", SizeModNone, ExtNon, "mem32"
Instruction "FISTP ", "DF /7 ", SizeModNone, ExtNon, "mem64"

Instruction "FISTTP ", "DF /1 ", SizeModNone, ExtNon, "mem16"
Instruction "FISTTP ", "DB /1 ", SizeModNone, ExtNon, "mem32"
Instruction "FISTTP ", "DD /1 ", SizeModNone, ExtNon, "mem64"

Instruction "FLD ", "D9 /0 ", SizeModNone, ExtNon, "mem32"
Instruction "FLD ", "DD /0 ", SizeModNone, ExtNon, "mem64"
Instruction "FLD ", "DB /5 ", SizeModNone, ExtNon, "mem80"
Instruction "FLD ", "D9 C0 ", SizeModNone, ExtFlt, "st# "

Instruction "FLD1 ", "D9 E8 ", SizeModNone, ExtNon
Instruction "FLDL2T ", "D9 E9 ", SizeModNone, ExtNon
Instruction "FLDL2E ", "D9 EA ", SizeModNone, ExtNon
Instruction "FLDPI ", "D9 EB ", SizeModNone, ExtNon
Instruction "FLDLG2 ", "D9 EC ", SizeModNone, ExtNon
Instruction "FLDLN2 ", "D9 ED ", SizeModNone, ExtNon
Instruction "FLDZ ", "D9 EE ", SizeModNone, ExtNon

Instruction "FLDCW ", "D9 /5 ", SizeModNone, ExtNon, "mem "
Instruction "FLDENV ", "D9 /4 ", SizeModNone, ExtNon, "mem "

Instruction "FMUL ", "D8 /1 ", SizeModNone, ExtNon, "mem32"
Instruction "FMUL ", "DC /1 ", SizeModNone, ExtNon, "mem64"
Instruction "FMUL ", "D8 C8 ", SizeModNone, ExtFlt, "st0 ", "st# "
Instruction "FMUL ", "DC C8 ", SizeModNone, ExtFlt, "st# ", "st0 "
Instruction "FMUL ", "DE C8 ", SizeModNone, ExtFlt, "st# ", "st0 "
Instruction "FMULP ", "DE C9 ", SizeModNone, ExtNon
Instruction "FIMUL ", "DA /1 ", SizeModNone, ExtNon, "mem32"
Instruction "FIMUL ", "DE /1 ", SizeModNone, ExtNon, "mem16"

Instruction "FNOP ", "D9 D0 ", SizeModNone, ExtNon
Instruction "FPATAN ", "D9 F3 ", SizeModNone, ExtNon
Instruction "FPREM ", "D9 F8 ", SizeModNone, ExtNon
Instruction "FPREM1 ", "D9 F5 ", SizeModNone, ExtNon
Instruction "FPTAN ", "D9 F2 ", SizeModNone, ExtNon
Instruction "FRNDINT", "D9 FC ", SizeModNone, ExtNon
Instruction "FRSTOR ", "DD /4 ", SizeModNone, ExtNon, "mem "
Instruction "FSAVE ", "9B DD /6", SizeModNone, ExtNon, "mem "
Instruction "FSCALE ", "D9 FD ", SizeModNone, ExtNon
Instruction "FSQRT ", "D9 FA ", SizeModNone, ExtNon

Instruction "FST ", "D9 /2 ", SizeModNone, ExtNon, "mem32"
Instruction "FST ", "DD /2 ", SizeModNone, ExtNon, "mem64"
Instruction "FST ", "DD D0 ", SizeModNone, ExtFlt, "st# "
Instruction "FSTP ", "D9 /3 ", SizeModNone, ExtNon, "mem32"
Instruction "FSTP ", "DD /3 ", SizeModNone, ExtNon, "mem64"
Instruction "FSTP ", "DB /7 ", SizeModNone, ExtNon, "mem80"
Instruction "FSTP ", "DD D8 ", SizeModNone, ExtFlt, "st# "

Instruction "FSTCW ", "9B D9 /7", SizeModNone, ExtNon, "mem "
Instruction "FSTENV ", "9B D9 /6", SizeModNone, ExtNon, "mem "
Instruction "FSTSW ", "9B DD /7", SizeModNone, ExtNon, "mem "
Instruction "FSTSW ", "9B DF E0", SizeModNone, ExtNon, "ax "

Instruction "FSUB ", "D8 /4 ", SizeModNone, ExtNon, "mem32"
Instruction "FSUB ", "DC /4 ", SizeModNone, ExtNon, "mem64"
Instruction "FSUB ", "D8 E0 ", SizeModNone, ExtFlt, "st0 ", "st# "
Instruction "FSUB ", "DC E8 ", SizeModNone, ExtFlt, "st# ", "st0 "
Instruction "FSUBP ", "DE E8 ", SizeModNone, ExtFlt, "st# ", "st0 "
Instruction "FSUBP ", "DE E9 ", SizeModNone, ExtNon
Instruction "FISUB ", "DA /4 ", SizeModNone, ExtNon, "mem32"
Instruction "FISUB ", "DE /4 ", SizeModNone, ExtNon, "mem16"

Instruction "FSUBR ", "D8 /5 ", SizeModNone, ExtNon, "mem32"
Instruction "FSUBR ", "DC /5 ", SizeModNone, ExtNon, "mem64"
Instruction "FSUBR ", "D8 E8 ", SizeModNone, ExtNon, "st0 ", "st# "
Instruction "FSUBR ", "DC E0 ", SizeModNone, ExtNon, "st# ", "st0 "
Instruction "FSUBR ", "DE E0 ", SizeModNone, ExtNon, "st# ", "st0 "
Instruction "FSUBRP ", "DE E1 ", SizeModNone, ExtNon
Instruction "FISUBR ", "DA /5 ", SizeModNone, ExtNon, "mem32"
Instruction "FISUBR ", "DE /5 ", SizeModNone, ExtNon, "mem16"

Instruction "FTST ", "D9 E4 ", SizeModNone, ExtNon
Instruction "FUCOM ", "DD E0 ", SizeModNone, ExtFlt, "st# "
Instruction "FUCOM ", "DD E1 ", SizeModNone, ExtNon
Instruction "FUCOMP ", "DD E8 ", SizeModNone, ExtFlt, "st# "
Instruction "FUCOMP ", "DD E9 ", SizeModNone, ExtNon
Instruction "FUCOMPP", "DA E9 ", SizeModNone, ExtNon
Instruction "FXAM ", "D9 E5 ", SizeModNone, ExtNon
Instruction "FXCH ", "D9 C8 ", SizeModNone, ExtFlt, "st# "
Instruction "FXCH ", "D9 C9 ", SizeModNone, ExtNon
Instruction "FXRSTOR", "0F AE /1", SizeModNone, ExtNon, "mem "
Instruction "FXSAVE ", "0F AE /0", SizeModNone, ExtNon, "mem "
Instruction "FXTRACT", "D9 F4 ", SizeModNone, ExtNon
Instruction "FYL2X ", "D9 F1 ", SizeModNone, ExtNon
Instruction "FYL2XP1", "D9 F9 ", SizeModNone, ExtNon

Instruction "FWAIT ", "9B ", SizeModNone, ExtNon
Instruction "WAIT ", "9B ", SizeModNone, ExtNon
End Sub


Private Sub AddArithmetics()
Instruction "INC ", "40 ", SizeModOvrd, ExtReg, "#16 "
Instruction "INC ", "40 ", SizeModNone, ExtReg, "#32 "
Instruction "INC ", "FE /0 ", SizeModNone, ExtNon, "rem08"
Instruction "INC ", "FF /0 ", SizeModOvrd, ExtNon, "rem16"
Instruction "INC ", "FF /0 ", SizeModNone, ExtNon, "rem32"

Instruction "DEC ", "48 ", SizeModOvrd, ExtReg, "#16 "
Instruction "DEC ", "48 ", SizeModNone, ExtReg, "#32 "
Instruction "DEC ", "FE /1 ", SizeModNone, ExtNon, "rem08"
Instruction "DEC ", "FF /1 ", SizeModOvrd, ExtNon, "rem16"
Instruction "DEC ", "FF /1 ", SizeModNone, ExtNon, "rem32"

Instruction "SBB ", "1C ", SizeModNone, ExtNon, "AL ", "imm08"
Instruction "SBB ", "1D ", SizeModOvrd, ExtNon, "AX ", "imm16"
Instruction "SBB ", "1D ", SizeModNone, ExtNon, "EAX ", "imm32"
Instruction "SBB ", "80 /3 ", SizeModNone, ExtNon, "rem08", "imm08"
Instruction "SBB ", "81 /3 ", SizeModOvrd, ExtNon, "rem16", "imm16"
Instruction "SBB ", "81 /3 ", SizeModNone, ExtNon, "rem32", "imm32"
Instruction "SBB ", "83 /3 ", SizeModOvrd, ExtNon, "rem16", "imm08"
Instruction "SBB ", "83 /3 ", SizeModNone, ExtNon, "rem32", "imm08"
Instruction "SBB ", "18 ", SizeModNone, ExtNon, "rem08", "reg08"
Instruction "SBB ", "19 ", SizeModOvrd, ExtNon, "rem16", "reg16"
Instruction "SBB ", "19 ", SizeModNone, ExtNon, "rem32", "reg32"
Instruction "SBB ", "1A ", SizeModNone, ExtNon, "reg08", "rem08"
Instruction "SBB ", "1B ", SizeModOvrd, ExtNon, "reg16", "rem16"
Instruction "SBB ", "1B ", SizeModNone, ExtNon, "reg32", "rem32"

Instruction "IMUL ", "F6 /5 ", SizeModNone, ExtNon, "rem08"
Instruction "IMUL ", "F7 /5 ", SizeModOvrd, ExtNon, "rem16"
Instruction "IMUL ", "F7 /5 ", SizeModNone, ExtNon, "rem32"
Instruction "IMUL ", "0F AF ", SizeModOvrd, ExtNon, "reg16", "rem16"
Instruction "IMUL ", "0F AF ", SizeModNone, ExtNon, "reg32", "rem32"
Instruction "IMUL ", "69 ", SizeModOvrd, ExtNon, "reg16", "rem16", "imm16"
Instruction "IMUL ", "69 ", SizeModNone, ExtNon, "reg32", "rem32", "imm32"
'Instruction "IMUL ", "69 ", SizeModOvrd, ExtNon, "reg16", "imm16"
'Instruction "IMUL ", "69 ", SizeModNone, ExtNon, "reg32", "imm32"
Instruction "IMUL ", "6B ", SizeModOvrd, ExtNon, "reg16", "rem16", "imm08"
Instruction "IMUL ", "6B ", SizeModNone, ExtNon, "reg32", "rem32", "imm08"
'Instruction "IMUL ", "6B ", SizeModOvrd, ExtNon, "reg16", "imm08"
'Instruction "IMUL ", "6B ", SizeModNone, ExtNon, "reg32", "imm08"

Instruction "DIV ", "F6 /6 ", SizeModNone, ExtNon, "rem08"
Instruction "DIV ", "F7 /6 ", SizeModOvrd, ExtNon, "rem16"
Instruction "DIV ", "F7 /6 ", SizeModNone, ExtNon, "rem32"

Instruction "MUL ", "F6 /4 ", SizeModNone, ExtNon, "rem08"
Instruction "MUL ", "F7 /4 ", SizeModOvrd, ExtNon, "rem16"
Instruction "MUL ", "F7 /4 ", SizeModNone, ExtNon, "rem32"

Instruction "IDIV ", "F6 /7 ", SizeModNone, ExtNon, "rem08"
Instruction "IDIV ", "F7 /7 ", SizeModOvrd, ExtNon, "rem16"
Instruction "IDIV ", "F7 /7 ", SizeModNone, ExtNon, "rem32"

Instruction "XADD ", "0F C0 ", SizeModNone, ExtNon, "rem08", "reg08"
Instruction "XADD ", "0F C1 ", SizeModOvrd, ExtNon, "rem16", "reg16"
Instruction "XADD ", "0F C1 ", SizeModNone, ExtNon, "rem32", "reg32"

Instruction "ADC ", "14 ", SizeModNone, ExtNon, "AL ", "imm08"
Instruction "ADC ", "15 ", SizeModOvrd, ExtNon, "AX ", "imm16"
Instruction "ADC ", "15 ", SizeModNone, ExtNon, "EAX ", "imm32"
Instruction "ADC ", "80 /2 ", SizeModNone, ExtNon, "rem08", "imm08"
Instruction "ADC ", "81 /2 ", SizeModOvrd, ExtNon, "rem16", "imm16"
Instruction "ADC ", "81 /2 ", SizeModNone, ExtNon, "rem32", "imm32"
Instruction "ADC ", "83 /2 ", SizeModOvrd, ExtNon, "rem16", "imm08"
Instruction "ADC ", "83 /2 ", SizeModNone, ExtNon, "rem32", "imm08"
Instruction "ADC ", "10 ", SizeModNone, ExtNon, "rem08", "reg08"
Instruction "ADC ", "11 ", SizeModOvrd, ExtNon, "rem16", "reg16"
Instruction "ADC ", "11 ", SizeModNone, ExtNon, "rem32", "reg32"
Instruction "ADC ", "12 ", SizeModNone, ExtNon, "reg08", "rem08"
Instruction "ADC ", "13 ", SizeModOvrd, ExtNon, "reg16", "rem16"
Instruction "ADC ", "13 ", SizeModNone, ExtNon, "reg32", "rem32"

Instruction "ADD ", "04 ", SizeModNone, ExtNon, "AL ", "imm08"
Instruction "ADD ", "05 ", SizeModOvrd, ExtNon, "AX ", "imm16"
Instruction "ADD ", "05 ", SizeModNone, ExtNon, "EAX ", "imm32"
Instruction "ADD ", "80 /0 ", SizeModNone, ExtNon, "rem08", "imm08"
Instruction "ADD ", "81 /0 ", SizeModOvrd, ExtNon, "rem16", "imm16"
Instruction "ADD ", "81 /0 ", SizeModNone, ExtNon, "rem32", "imm32"
Instruction "ADD ", "83 /0 ", SizeModOvrd, ExtNon, "rem16", "imm08"
Instruction "ADD ", "83 /0 ", SizeModNone, ExtNon, "rem32", "imm08"
Instruction "ADD ", "00 ", SizeModNone, ExtNon, "rem08", "reg08"
Instruction "ADD ", "01 ", SizeModOvrd, ExtNon, "rem16", "reg16"
Instruction "ADD ", "01 ", SizeModNone, ExtNon, "rem32", "reg32"
Instruction "ADD ", "02 ", SizeModNone, ExtNon, "reg08", "rem08"
Instruction "ADD ", "03 ", SizeModOvrd, ExtNon, "reg16", "rem16"
Instruction "ADD ", "03 ", SizeModNone, ExtNon, "reg32", "rem32"

Instruction "SUB ", "2C ", SizeModNone, ExtNon, "AL ", "imm08"
Instruction "SUB ", "2D ", SizeModOvrd, ExtNon, "AX ", "imm16"
Instruction "SUB ", "2D ", SizeModNone, ExtNon, "EAX ", "imm32"
Instruction "SUB ", "80 /5 ", SizeModNone, ExtNon, "rem08", "imm08"
Instruction "SUB ", "81 /5 ", SizeModOvrd, ExtNon, "rem16", "imm16"
Instruction "SUB ", "81 /5 ", SizeModNone, ExtNon, "rem32", "imm32"
Instruction "SUB ", "83 /5 ", SizeModOvrd, ExtNon, "rem16", "imm08"
Instruction "SUB ", "83 /5 ", SizeModNone, ExtNon, "rem32", "imm08"
Instruction "SUB ", "28 ", SizeModNone, ExtNon, "rem08", "reg08"
Instruction "SUB ", "29 ", SizeModOvrd, ExtNon, "rem16", "reg16"
Instruction "SUB ", "29 ", SizeModNone, ExtNon, "rem32", "reg32"
Instruction "SUB ", "2A ", SizeModNone, ExtNon, "reg08", "rem08"
Instruction "SUB ", "2B ", SizeModOvrd, ExtNon, "reg16", "rem16"
Instruction "SUB ", "2B ", SizeModNone, ExtNon, "reg32", "rem32"
End Sub


Private Sub Instruction( _
Mnemonic As String, _
OpCode As String, _
ByVal SizeModifier As SizeMod, _
ByVal Ext As ExtType, _
ParamArray Params() As Variant _
)

Dim strArgs() As String
Dim i As Long

If UBound(Params) > -1 Then
ReDim strArgs(UBound(Params)) As String

For i = 0 To UBound(Params)
strArgs(i) = Trim$(Params(i))
Next
End If

Select Case Ext
Case ExtNon: InstrDefault Trim$(Mnemonic), Trim$(OpCode), SizeModifier, strArgs, UBound(Params) + 1
Case ExtReg: InstrRegExt Trim$(Mnemonic), Trim$(OpCode), SizeModifier, strArgs, UBound(Params) + 1
Case ExtFlt: InstrFloatExt Trim$(Mnemonic), Trim$(OpCode), SizeModifier, strArgs, UBound(Params) + 1
Case ExtCon: InstrCondition Trim$(Mnemonic), Trim$(OpCode), SizeModifier, strArgs, UBound(Params) + 1
Case Ext3DN: Instr3DNow Trim$(Mnemonic), Trim$(OpCode), SizeModNone, strArgs, UBound(Params) + 1
End Select
End Sub


' OpCode der Instruktion variiert je nach verwendetem Register
Private Sub InstrRegExt( _
Mnemonic As String, _
Op As String, _
ByVal SizeModifier As SizeMod, _
Params() As String, _
ParamCnt As Long _
)

Dim udtInstr As Instruction
Dim i As Long
Dim lngRegPa As Long
Dim udeSize As ParamSize

udtInstr.Mnemonic = Mnemonic
udtInstr.Prefixes = IIf(SizeModifier = SizeModOvrd, PrefixFlgOperandSizeOverride, 0)
udtInstr.ParamCount = ParamCnt

With ParseOpCode(Op)
For i = 0 To MAX_OPCODE_LEN - 1
udtInstr.OpCode(i) = .bytes(i)
Next

udtInstr.OpCodeLen = .ByteCount
udtInstr.RegOpExt = .RegOpExt
udtInstr.Now3DByte = -1
udtInstr.ModRM = .RegOpExt > -1
End With

For i = 0 To ParamCnt - 1
If Left$(Params(i), 1) = "#" Then
lngRegPa = i
Select Case Mid$(Params(i), 2, 2)
Case "08": udeSize = Bits8
Case "16": udeSize = Bits16
Case "32": udeSize = Bits32
Case Else: Err.Raise 12345, , "Ungültige Größe!"
End Select
Else
udtInstr.Parameters(i) = ParseParameter(Params(i))
If Not udtInstr.Parameters(i).Forced Then
If udtInstr.Parameters(i).PType = ParamReg Or _
udtInstr.Parameters(i).PType = (ParamReg Or ParamMem) Then
udtInstr.ModRM = True
End If
End If
End If
Next

For i = 0 To 7
With udtInstr
.Parameters(lngRegPa) = ParseParameter(GetRegExtRegName(i, udeSize))
AddInstr udtInstr

.OpCode(.OpCodeLen - 1) = .OpCode(.OpCodeLen - 1) + 1
End With
Next
End Sub


' OpCode der Instruktion variiert je nach verwendetem FPU Register
Private Sub InstrFloatExt( _
Mnemonic As String, _
Op As String, _
ByVal SizeModifier As SizeMod, _
Params() As String, _
ByVal ParamCnt As Long _
)

Dim udtInstr As Instruction
Dim i As Long
Dim lngFlPa As Long
Dim lastbyte As Byte

udtInstr.Mnemonic = Mnemonic
udtInstr.Prefixes = IIf(SizeModifier = SizeModOvrd, PrefixFlgOperandSizeOverride, 0)
udtInstr.ParamCount = ParamCnt

With ParseOpCode(Op)
For i = 0 To MAX_OPCODE_LEN - 1
udtInstr.OpCode(i) = .bytes(i)
Next

udtInstr.OpCodeLen = .ByteCount
udtInstr.RegOpExt = .RegOpExt
udtInstr.Now3DByte = -1
udtInstr.ModRM = .RegOpExt > -1
End With
lastbyte = udtInstr.OpCode(udtInstr.OpCodeLen - 1)

For i = 0 To ParamCnt - 1
If UCase$(Params(i)) = "ST#" Then
lngFlPa = i
Else
udtInstr.Parameters(i) = ParseParameter(Params(i))
If Not udtInstr.Parameters(i).Forced Then
If udtInstr.Parameters(i).PType = ParamReg Or _
udtInstr.Parameters(i).PType = (ParamReg Or ParamMem) Then
udtInstr.ModRM = True
End If
End If
End If
Next

For i = 0 To 7
udtInstr.OpCode(udtInstr.OpCodeLen - 1) = lastbyte + i
udtInstr.Parameters(lngFlPa) = ParseParameter("ST" & i)
AddInstr udtInstr
Next
End Sub


' Conditional Instruction, es gibt mehrere Abwandlungen wie xxxZ, xxxNZ, xxxNGE, ...
Private Sub InstrCondition( _
Mnemonic As String, _
Op As String, _
ByVal SizeModifier As SizeMod, _
Params() As String, _
ByVal ParamCnt As Long _
)

Dim udtInstr As Instruction
Dim conds() As String
Dim i As Long
Dim lastbyte As Byte

conds = Split(RemoveWSDoubles(CONDITIONS), " ")

udtInstr.Prefixes = IIf(SizeModifier = SizeModOvrd, PrefixFlgOperandSizeOverride, 0)
udtInstr.ParamCount = ParamCnt

With ParseOpCode(Op)
For i = 0 To MAX_OPCODE_LEN - 1
udtInstr.OpCode(i) = .bytes(i)
Next

udtInstr.OpCodeLen = .ByteCount
udtInstr.RegOpExt = .RegOpExt
udtInstr.Now3DByte = -1
udtInstr.ModRM = .RegOpExt > -1
End With
lastbyte = udtInstr.OpCode(udtInstr.OpCodeLen - 1)

For i = 0 To ParamCnt - 1
udtInstr.Parameters(i) = ParseParameter(Params(i))
If Not udtInstr.Parameters(i).Forced Then
If udtInstr.Parameters(i).PType = ParamReg Or _
udtInstr.Parameters(i).PType = (ParamReg Or ParamMem) Then
udtInstr.ModRM = True
End If
End If
Next

For i = 0 To UBound(conds)
udtInstr.Mnemonic = Mnemonic & conds(i)
udtInstr.OpCode(udtInstr.OpCodeLen - 1) = lastbyte + ConditionOffset(conds(i))
AddInstr udtInstr
Next
End Sub


Private Sub Instr3DNow( _
Mnemonic As String, _
Op As String, _
ByVal SizeModifier As SizeMod, _
Params() As String, _
ByVal ParamCnt As Long _
)

Dim udtInstr As Instruction
Dim i As Long

udtInstr.Mnemonic = Mnemonic
udtInstr.Prefixes = IIf(SizeModifier = SizeModOvrd, PrefixFlgOperandSizeOverride, 0)
udtInstr.ParamCount = ParamCnt - 1

With ParseOpCode(Op)
For i = 0 To MAX_OPCODE_LEN - 1
udtInstr.OpCode(i) = .bytes(i)
Next

udtInstr.OpCodeLen = .ByteCount
udtInstr.RegOpExt = .RegOpExt
udtInstr.ModRM = .RegOpExt > -1
End With

For i = 0 To ParamCnt - 2
udtInstr.Parameters(i) = ParseParameter(Params(i))
If Not udtInstr.Parameters(i).Forced Then
If udtInstr.Parameters(i).PType = ParamReg Or _
udtInstr.Parameters(i).PType = (ParamReg Or ParamMem) Or _
(udtInstr.Parameters(i).PType And ParamMM) Then
udtInstr.ModRM = True
End If
End If
Next

udtInstr.Now3DByte = CLng(Params(i))

AddInstr udtInstr
End Sub


Private Sub InstrDefault( _
Mnemonic As String, _
Op As String, _
ByVal SizeModifier As SizeMod, _
Params() As String, _
ByVal ParamCnt As Long _
)

Dim udtInstr As Instruction
Dim i As Long

udtInstr.Mnemonic = Mnemonic
udtInstr.Prefixes = IIf(SizeModifier = SizeModOvrd, PrefixFlgOperandSizeOverride, 0)
udtInstr.ParamCount = ParamCnt

With ParseOpCode(Op)
For i = 0 To MAX_OPCODE_LEN - 1
udtInstr.OpCode(i) = .bytes(i)
Next

udtInstr.OpCodeLen = .ByteCount
udtInstr.RegOpExt = .RegOpExt
udtInstr.Now3DByte = -1
udtInstr.ModRM = .RegOpExt > -1
End With

For i = 0 To ParamCnt - 1
udtInstr.Parameters(i) = ParseParameter(Params(i))
If Not udtInstr.Parameters(i).Forced Then
If udtInstr.Parameters(i).PType = ParamReg Or _
udtInstr.Parameters(i).PType = (ParamReg Or ParamMem) Or _
(udtInstr.Parameters(i).PType And ParamMM) Then
udtInstr.ModRM = True
End If
End If
Next

AddInstr udtInstr
End Sub


Private Function ParseParameter(param As String) As InstructionParam
With ParseParameter
If IsRegister(param) Then
.Register = RegStrToReg(param)
.Size = RegisterSize(.Register)
.PType = ParamReg
.Forced = True
ElseIf IsNumeric(param) Then
.value = CLng(param)
.Size = GetFirstSetBit(SizesForInt(.value))
.PType = ParamImm
.Forced = True
ElseIf IsFPUReg(param) Then
.FPURegister = FPURegStrToNum(param)
.Size = Bits32 Or Bits64 Or Bits80
.PType = ParamSTX
.Forced = True
Else
If LCase$(Left$(param, 2)) = "mm" Or LCase$(Left$(param, 3)) = "xmm" Then
.MMRegister = MMRegStrToNum(param)
.PType = ParamMM

If InStr(param, "/mem") > 0 Then
.PType = .PType Or ParamMem
Else
If (.MMRegister And MM0) Then
.Size = Bits64
Else
.Size = Bits128
End If
End If
Else
Select Case LCase$(Left$(param, 3))
Case "imm": .PType = ParamImm
Case "reg": .PType = ParamReg
Case "rel": .PType = ParamRel
Case "mem": .PType = ParamMem
Case "rem": .PType = ParamMem Or ParamReg
End Select
End If

Select Case Right$(param, 2)
Case "08": .Size = Bits8
Case "16": .Size = Bits16
Case "32": .Size = Bits32
Case "64": .Size = Bits64
Case "80": .Size = Bits80
End Select

Select Case Right$(param, 3)
Case "128": .Size = Bits128
End Select
End If
End With
End Function


Private Function ParseOpCode(Op As String) As OpCode
Dim i As Long
Dim strH As String

With ParseOpCode
.RegOpExt = -1

For i = 1 To Len(Op)
Select Case Mid$(Op, i, 1)
Case "0" To "9": strH = strH & Mid$(Op, i, 1)
Case "A" To "F": strH = strH & Mid$(Op, i, 1)
Case "a" To "f": strH = strH & Mid$(Op, i, 1)
Case "/": .RegOpExt = CLng(Mid$(Op, i + 1, 1))
i = i + 1
End Select

If Len(strH) = 2 Then
.bytes(.ByteCount) = CLng("&H" & strH)
.ByteCount = .ByteCount + 1
strH = ""
End If
Next
End With
End Function


Public Function SizesForInt(ByVal lngVal As Long) As ParamSize
If (lngVal >= -128 And lngVal <= 255) Then
SizesForInt = Bits8 Or Bits16 Or Bits32 Or Bits64 Or Bits80
ElseIf (lngVal >= -32768 And lngVal <= 65535) Then
SizesForInt = Bits16 Or Bits32 Or Bits64 Or Bits80
Else
SizesForInt = Bits32 Or Bits64 Or Bits80
End If
End Function


Public Function IsRawDataOp(strOp As String) As Boolean
Dim i As Long

For i = 0 To UBound(m_strRawData)
If StrComp(m_strRawData(i), strOp, vbTextCompare) = 0 Then
IsRawDataOp = True
Exit Function
End If
Next
End Function


Public Function IsMMReg(strReg As String) As Boolean
Dim i As Long

For i = 0 To UBound(m_strMMRegs)
If StrComp(m_strMMRegs(i), strReg, vbTextCompare) = 0 Then
IsMMReg = True
Exit Function
End If
Next
End Function


Public Function IsFPUReg(strReg As String) As Boolean
Dim i As Long

For i = 0 To UBound(m_strFPURegs)
If StrComp(m_strFPURegs(i), strReg, vbTextCompare) = 0 Then
IsFPUReg = True
Exit Function
End If
Next
End Function


Public Function IsKeyword(strKey As String) As Boolean
Dim i As Long

For i = 0 To UBound(m_strKeywords)
If StrComp(m_strKeywords(i), strKey, vbTextCompare) = 0 Then
IsKeyword = True
Exit Function
End If
Next
End Function


Public Function IsSegmentReg(strSeg As String) As Boolean
Dim i As Long

For i = 0 To UBound(m_strSegments)
If StrComp(m_strSegments(i), strSeg, vbTextCompare) = 0 Then
IsSegmentReg = True
Exit Function
End If
Next
End Function


Public Function IsRegister(strReg As String) As Boolean
Dim i As Long

For i = 0 To UBound(m_strRegisters)
If StrComp(m_strRegisters(i), strReg, vbTextCompare) = 0 Then
IsRegister = True
Exit Function
End If
Next
End Function


Public Function FPURegStrToNum(strST As String) As ASMFPURegisters
If UCase$(Left$(strST, 2)) = "ST" Then
FPURegStrToNum = CLng(Mid$(strST, 3, 1))
Else
FPURegStrToNum = FP_UNKNOWN
End If
End Function


Public Function MMRegStrToNum(strMM As String) As ASMXMMRegisters
Dim udeBase As ASMXMMRegisters
Dim strNum As String
Dim i As Long

If UCase$(Left$(strMM, 3)) = "XMM" Then
udeBase = XMM0
strNum = Mid$(strMM, 4, 1)
ElseIf UCase$(Left$(strMM, 2)) = "MM" Then
udeBase = MM0
strNum = Mid$(strMM, 3, 1)
Else
Err.Raise 12345, , "Kein (X)MM Register"
End If

If IsNumeric(strNum) Then
udeBase = udeBase * 2 ^ CInt(strNum)
Else
If udeBase = XMM0 Then
udeBase = XMM0 Or XMM1 Or XMM2 Or XMM3 Or XMM4 Or XMM5 Or XMM6 Or XMM7
Else
udeBase = MM0 Or MM1 Or MM2 Or MM3 Or MM4 Or MM5 Or MM6 Or MM7
End If
End If

MMRegStrToNum = udeBase
End Function


Public Function ConditionOffset(cc As String) As Long
Select Case UCase$(cc)
Case "O": ConditionOffset = 0
Case "NO": ConditionOffset = 1
Case "B", "C", "NAE": ConditionOffset = 2
Case "AE", "NB", "NC": ConditionOffset = 3
Case "E", "Z": ConditionOffset = 4
Case "NE", "NZ": ConditionOffset = 5
Case "BE", "NA": ConditionOffset = 6
Case "A", "NBE": ConditionOffset = 7
Case "S": ConditionOffset = 8
Case "NS": ConditionOffset = 9
Case "P", "PE": ConditionOffset = 10
Case "NP", "PO": ConditionOffset = 11
Case "L", "NGE": ConditionOffset = 12
Case "GE", "NL": ConditionOffset = 13
Case "LE", "NG": ConditionOffset = 14
Case "G", "NLE": ConditionOffset = 15
End Select
End Function


Public Function GetRegExtRegName(ByVal Offset As Long, ByVal Size As ParamSize) As String
Select Case Size
Case Bits8, Bits16, Bits32:
Case Else: Err.Raise 123456, , "GetRegExtRegName: Ungültige Größenangabe"
End Select

Select Case Offset
Case 0:
Select Case Size
Case Bits8: GetRegExtRegName = "AL"
Case Bits16: GetRegExtRegName = "AX"
Case Bits32: GetRegExtRegName = "EAX"
End Select
Case 1:
Select Case Size
Case Bits8: GetRegExtRegName = "CL"
Case Bits16: GetRegExtRegName = "CX"
Case Bits32: GetRegExtRegName = "ECX"
End Select
Case 2:
Select Case Size
Case Bits8: GetRegExtRegName = "DL"
Case Bits16: GetRegExtRegName = "DX"
Case Bits32: GetRegExtRegName = "EDX"
End Select
Case 3:
Select Case Size
Case Bits8: GetRegExtRegName = "BL"
Case Bits16: GetRegExtRegName = "BX"
Case Bits32: GetRegExtRegName = "EBX"
End Select
Case 4:
Select Case Size
Case Bits8: GetRegExtRegName = "AH"
Case Bits16: GetRegExtRegName = "SP"
Case Bits32: GetRegExtRegName = "ESP"
End Select
Case 5:
Select Case Size
Case Bits8: GetRegExtRegName = "CH"
Case Bits16: GetRegExtRegName = "BP"
Case Bits32: GetRegExtRegName = "EBP"
End Select
Case 6:
Select Case Size
Case Bits8: GetRegExtRegName = "DH"
Case Bits16: GetRegExtRegName = "SI"
Case Bits32: GetRegExtRegName = "ESI"
End Select
Case 7:
Select Case Size
Case Bits8: GetRegExtRegName = "BH"
Case Bits16: GetRegExtRegName = "DI"
Case Bits32: GetRegExtRegName = "EDI"
End Select
Case Else:
'Err.Raise 12345, , "GetRegExtRegName: Ungültiges Offset"
End Select
End Function


Public Function RegisterSize(reg As ASMRegisters) As ParamSize
Select Case reg
Case RegAL, RegAH, RegBL, RegBH, RegCL, RegCH, RegDL, RegDH:
RegisterSize = Bits8
Case RegAX, RegBX, RegCX, RegDX, RegBP, RegSP, RegDI, RegSI:
RegisterSize = Bits16
Case RegEAX, RegEBX, RegECX, RegEDX, RegEBP, RegESP, RegEDI, RegESI:
RegisterSize = Bits32
Case Else:
RegisterSize = BitsUnknown
End Select
End Function


Public Function SegStrToSeg(strSeg As String) As ASMSegmentRegs
Select Case LCase$(strSeg)
Case "cs": SegStrToSeg = SegCs
Case "ds": SegStrToSeg = SegDs
Case "es": SegStrToSeg = SegEs
Case "fs": SegStrToSeg = SegFs
Case "gs": SegStrToSeg = SegGs
Case "ss": SegStrToSeg = SegSs
Case Else: SegStrToSeg = SegUnknown
End Select
End Function


Public Function IdxToReg(ByVal idx As Long) As ASMRegisters
Select Case idx
Case 0: IdxToReg = RegAL
Case 1: IdxToReg = RegBL
Case 2: IdxToReg = RegCL
Case 3: IdxToReg = RegDL
Case 4: IdxToReg = RegAH
Case 5: IdxToReg = RegBH
Case 6: IdxToReg = RegCH
Case 7: IdxToReg = RegDH
Case 8: IdxToReg = RegBP
Case 9: IdxToReg = RegSP
Case 10: IdxToReg = RegDI
Case 11: IdxToReg = RegSI
Case 12: IdxToReg = RegAX
Case 13: IdxToReg = RegBX
Case 14: IdxToReg = RegCX
Case 15: IdxToReg = RegDX
Case 16: IdxToReg = RegEBP
Case 17: IdxToReg = RegESP
Case 18: IdxToReg = RegEDI
Case 19: IdxToReg = RegESI
Case 20: IdxToReg = RegEAX
Case 21: IdxToReg = RegEBX
Case 22: IdxToReg = RegECX
Case 23: IdxToReg = RegEDX
Case Else: IdxToReg = RegUnknown
End Select
End Function


Public Function RegToIdx(ByVal udeReg As ASMRegisters) As Long
Select Case udeReg
Case RegAL: RegToIdx = 0
Case RegBL: RegToIdx = 1
Case RegCL: RegToIdx = 2
Case RegDL: RegToIdx = 3
Case RegAH: RegToIdx = 4
Case RegBH: RegToIdx = 5
Case RegCH: RegToIdx = 6
Case RegDH: RegToIdx = 7
Case RegBP: RegToIdx = 8
Case RegSP: RegToIdx = 9
Case RegDI: RegToIdx = 10
Case RegSI: RegToIdx = 11
Case RegAX: RegToIdx = 12
Case RegBX: RegToIdx = 13
Case RegCX: RegToIdx = 14
Case RegDX: RegToIdx = 15
Case RegEBP: RegToIdx = 16
Case RegESP: RegToIdx = 17
Case RegEDI: RegToIdx = 18
Case RegESI: RegToIdx = 19
Case RegEAX: RegToIdx = 20
Case RegEBX: RegToIdx = 21
Case RegECX: RegToIdx = 22
Case RegEDX: RegToIdx = 23
Case Else: RegToIdx = -1
End Select
End Function


Public Function RegStrToReg(strReg As String) As ASMRegisters
Select Case LCase$(strReg)
Case "al": RegStrToReg = RegAL
Case "ah": RegStrToReg = RegAH
Case "bl": RegStrToReg = RegBL
Case "bh": RegStrToReg = RegBH
Case "cl": RegStrToReg = RegCL
Case "ch": RegStrToReg = RegCH
Case "dl": RegStrToReg = RegDL
Case "dh": RegStrToReg = RegDH
Case "sp": RegStrToReg = RegSP
Case "bp": RegStrToReg = RegBP
Case "si": RegStrToReg = RegSI
Case "di": RegStrToReg = RegDI
Case "ax": RegStrToReg = RegAX
Case "bx": RegStrToReg = RegBX
Case "cx": RegStrToReg = RegCX
Case "dx": RegStrToReg = RegDX
Case "eax": RegStrToReg = RegEAX
Case "ebx": RegStrToReg = RegEBX
Case "ecx": RegStrToReg = RegECX
Case "edx": RegStrToReg = RegEDX
Case "esp": RegStrToReg = RegESP
Case "ebp": RegStrToReg = RegEBP
Case "esi": RegStrToReg = RegESI
Case "edi": RegStrToReg = RegEDI
Case Else: RegStrToReg = RegUnknown
End Select
End Function


Private Function RemoveWSDoubles(strWS As String) As String
Do While InStr(strWS, " ")
strWS = Replace(strWS, " ", " ")
Loop

RemoveWSDoubles = strWS
End Function


Public Function BitCount(ByVal num As Long) As Long
Dim b As Long
Dim i As Long
Dim c As Long

b = 1

For i = 0 To 30
If num And b Then c = c + 1
If i < 30 Then b = b * 2
Next
If num And &H80000000 Then c = c + 1

BitCount = c
End Function


Public Function IsDefinite(ByVal num As Long) As Boolean
Dim b As Long
Dim i As Long
Dim c As Long

b = 1

For i = 0 To 30
If num And b Then
c = c + 1
If c > 1 Then Exit For
End If

If i < 30 Then b = b * 2
Next
If num And &H80000000 Then c = c + 1

IsDefinite = c = 1
End Function


Public Function GetFirstSetBitIdx(ByVal num As Long) As Long
Dim i As Long
Dim b As Long

b = 1

For i = 0 To 30
If num And b Then
GetFirstSetBitIdx = i
Exit Function
Else
If i < 30 Then b = b * 2
End If
Next
If num And &H80000000 Then GetFirstSetBitIdx = 31
End Function


Public Function GetFirstSetBit(ByVal num As Long) As Long
Dim i As Long
Dim b As Long

b = 1

For i = 0 To 30
If num And b Then
GetFirstSetBit = b
Exit Function
Else
b = b * 2
End If
Next
GetFirstSetBit = num And &H80000000
End Function


Public Function GetTokenName(ByVal tk As TokenType) As String
Select Case tk
Case TokenBeginOfInput: GetTokenName = "BeginOfInp"
Case TokenBracketLeft: GetTokenName = "BracketLeft"
Case TokenBracketRight: GetTokenName = "BracketRight"
Case TokenEndOfInput: GetTokenName = "EndOfInp"
Case TokenEndOfInstruction: GetTokenName = "EndOfInstr"
Case TokenInvalid: GetTokenName = "Invalid "
Case TokenKeyword: GetTokenName = "Keyword"
Case TokenOpAdd: GetTokenName = "OpAdd"
Case TokenOpColon: GetTokenName = "Colon"
Case TokenOperator: GetTokenName = "Operator"
Case TokenOpMul: GetTokenName = "OpMul"
Case TokenOpSub: GetTokenName = "OpSub"
Case TokenRegister: GetTokenName = "Register"
Case TokenSegmentReg: GetTokenName = "SegmentReg"
Case TokenFPUReg: GetTokenName = "FPUReg"
Case TokenSeparator: GetTokenName = "Separator"
Case TokenSymbol: GetTokenName = "Symbol"
Case TokenUnknown: GetTokenName = "Unknown"
Case TokenValue: GetTokenName = "Value"
Case TokenMMRegister: GetTokenName = "MMReg"
Case Else: GetTokenName = "??????"
End Select
End Function

CLASS :
Option Explicit


' 32 Bit X86 Assembler
'
' Arne Elster 2007 / 2008


' TODO:
' * Für Instructions wie 2-IMUL ModRM Unterstützung
' * Alles Expressions bei Argumenten
' * Unsigned Values (im Moment nur über Hex)


Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
pDst As Any, pSrc As Any, ByVal cBytes As Long _
)


Private Const IMAGE_NUMBEROF_DIRECTORY_ENTRIES As Long = 16&
Private Const IMAGE_SIZEOF_SHORT_NAME As Long = 8&
Private Const IMAGE_NT_OPTIONAL_HDR32_MAGIC As Long = &H10B&
Private Const IMAGE_DOS_HDR16_MAGIC As Long = &H5A4D&
Private Const IMAGE_DOS_HDR32_MAGIC As Long = &H4550&
Private Const IMAGE_FILE_MACHINE_I386 As Long = &H14C&

Private Const DOS_CODE_RELOCATIONS As String = _
"0E1FBA0E00B409CD21B8014CCD21546869732070726" & _
"F6772616D2063616E6E6F742062652072756E20696E" & _
"20444F53206D6F64652E0D0D0A2400000000000000"

Private Const MEM_SECTION_SIZE As Long = 4096
Private Const FILE_SECTION_SIZE As Long = 512

Private Const CHAR_SPACE As Long = 32
Private Const CHAR_LINEFEED As Long = 10
Private Const CHAR_CARRIAGE As Long = 13

Private Const CHAR_QUOTE As Long = 34
Private Const CHAR_STOP As Long = 46
Private Const CHAR_SEMICOLON As Long = 59
Private Const CHAR_COLON As Long = 58
Private Const CHAR_PLUS As Long = 43
Private Const CHAR_MINUS As Long = 45
Private Const CHAR_ASTERISK As Long = 42
Private Const CHAR_AMPERSAND As Long = 38
Private Const CHAR_SEPARATOR As Long = 44
Private Const CHAR_UNDERSCORE As Long = 95
Private Const CHAR_VERT_BAR As Long = 124
Private Const CHAR_SHARP As Long = 35

Private Const CHAR_BRACKET_L As Long = 91
Private Const CHAR_BRACKET_R As Long = 93
Private Const CHAR_PARENTH_L As Long = 40
Private Const CHAR_PARENTH_R As Long = 41

Private Const CHAR_NUMBER_0 As Long = 48
Private Const CHAR_NUMBER_9 As Long = 57

Private Const CHAR_ALPHA_UA As Long = 65
Private Const CHAR_ALPHA_UZ As Long = 90
Private Const CHAR_ALPHA_LA As Long = 97
Private Const CHAR_ALPHA_LZ As Long = 122

Private Const REG_COUNT As Long = 24
Private Const MAX_PARAMETERS As Long = 3
Private Const MAX_OPCODE_LEN As Long = 4

Public Enum PESubsystem
Subsystem_GUI = 2
Subsystem_CUI = 3
End Enum

Private Enum SectionCharacteristics
IMAGE_SCN_TYPE_NO_PAD = &H8&
IMAGE_SCN_CNT_CODE = &H20&
IMAGE_SCN_CNT_INITIALIZED_DATA = &H40&
IMAGE_SCN_CNT_UNINITIALIZED_DATA = &H80&
IMAGE_SCN_LNK_OTHER = &H100&
IMAGE_SCN_LNK_INFO = &H200&
IMAGE_SCN_LNK_REMOVE = &H800&
IMAGE_SCN_LNK_COMDAT = &H1000&
IMAGE_SCN_NO_DEFER_SPEC_EXC = &H4000&
IMAGE_SCN_GPREL = &H8000&
IMAGE_SCN_MEM_PURGEABLE = &H20000
IMAGE_SCN_MEM_LOCKED = &H40000
IMAGE_SCN_MEM_PRELOAD = &H80000
IMAGE_SCN_LNK_NRELOC_OVFL = &H1000000
IMAGE_SCN_MEM_DISCARDABLE = &H2000000
IMAGE_SCN_MEM_NOT_CACHED = &H4000000
IMAGE_SCN_MEM_NOT_PAGED = &H8000000
IMAGE_SCN_MEM_SHARED = &H10000000
IMAGE_SCN_MEM_EXECUTE = &H20000000
IMAGE_SCN_MEM_READ = &H40000000
IMAGE_SCN_MEM_WRITE = &H80000000
End Enum

Private Enum IMAGE_FILE_CHARACTERISTICS
IMAGE_FILE_RELOCS_STRIPPED = &H1&
IMAGE_FILE_EXECUTABLE_IMAGE = &H2&
IMAGE_FILE_LINE_NUMS_STRIPPED = &H4&
IMAGE_FILE_LOCAL_SYMS_STRIPPED = &H8&
IMAGE_FILE_AGGRESSIVE_WS_TRIM = &H10&
IMAGE_FILE_LARGE_ADDRESS_AWARE = &H20&
IMAGE_FILE_16BIT_MACHINE = &H40&
IMAGE_FILE_BYTES_REVERSED_LO = &H80&
IMAGE_FILE_32BIT_MACHINE = &H100&
IMAGE_FILE_DEBUG_STRIPPED = &H200&
IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = &H400&
IMAGE_FILE_NET_RUN_FROM_SWAP = &H800&
IMAGE_FILE_SYSTEM = &H1000&
IMAGE_FILE_DLL = &H2000&
IMAGE_FILE_UP_SYSTEM_ONLY = &H4000&
IMAGE_FILE_BYTES_REVERSED_HI = &H8000&
End Enum

Private Enum OptHeaderTbls
ETableExport = 0
ETableImport
ETableResource
ETableException
ETableCertificate
ETableRelocation
ETableDebug
ETableArchitecture
ETableGlobalPtr
ETableThreadStorage
ETableLoadConfig
ETableBoundImport
ETableIAT
ETableDelayImportDescriptor
ETableCOMPlusRuntime
ETableReserved
End Enum

Private Type ModRM
Mod As Long
rm As Long
reg As Long
Disp As Long
DispSize As ParamSize
End Type

Private Type SIB
sscale As Long
index As Long
base As Long
End Type

Private Type ASMLabel
name As String
Instruction As Long
Offset As Long
End Type

Private Type ASMExtern
LibName As String
Functions() As String
FunctionCount As Long
End Type

Private Type Pointer
Registers(REG_COUNT - 1) As Long
UsedRegisters As Long
Displacement As Long
DispSize As ParamSize
End Type

Private Type PointerInfo
TokenIndex As Long
RegisterCount As Long
RegisterMultiples As Boolean
HasDisplacement As Boolean ' Zahl oder Label
DispSize As ParamSize
Ptr As Pointer
End Type

Private Type RawData
Size As ParamSize
Values() As Long
ValueCount As Long
End Type

Private Type ASMArgument
TType As ParamType
Size As ParamSize
Pointer As PointerInfo
Register As ASMRegisters
FPURegister As ASMFPURegisters
MMRegister As ASMXMMRegisters
SymbolIndex As Long
value As Long
End Type

Private Type ASMInstruction
Mnemonic As String
Segment As ASMSegmentRegs
Args(MAX_PARAMETERS - 1) As ASMArgument
OpCodeIndex As Long
ArgCount As Long
Size As Long
Offset As Long
flags As OpCodePrefixes
data As RawData
Line As Long
Section As String
End Type

Private Type Scanner
Source() As Byte
Length As Long
Position As Long
Line As Long
LinePos As Long
Section As String
NextIsEOI As Boolean
LastWasEOI As Boolean
NextToken As ASMToken
CurToken As ASMToken
End Type

Private Type IMAGE_IMPORT_DIRECTORY
ImportLookupTable As Long
TimeDateStamp As Long
ForwardChain As Long
ModuleName As Long
ImportAddressTable As Long
End Type

Private Type IMAGE_DATA_DIRECTORY
VirtualAddress As Long
Size As Long
End Type

Private Type IMAGE_SECTION_HEADER
SectionName(IMAGE_SIZEOF_SHORT_NAME - 1) As Byte
VirtSizePhysAddr As Long
VirtualAddress As Long
SizeOfRawData As Long
PointerToRawData As Long
PointerToRelocations As Long
PointerToLinenumbers As Long
NumberOfRelocations As Integer
NumberOfLinenumbers As Integer
Characteristics As Long
End Type

Private Type IMAGE_OPTIONAL_HEADER
Magic As Integer
MajorLinkerVersion As Byte
MinorLinkerVersion As Byte
SizeOfCode As Long
SizeOfInitializedData As Long
SizeOfUninitializedData As Long
AddressOfEntryPoint As Long
BaseOfCode As Long
BaseOfData As Long
ImageBase As Long
SectionAlignment As Long
FileAlignment As Long
MajorOperatingSystemVersion As Integer
MinorOperatingSystemVersion As Integer
MajorImageVersion As Integer
MinorImageVersion As Integer
MajorSubsystemVersion As Integer
MinorSubsystemVersion As Integer
Win32VersionValue As Long
SizeOfImage As Long
SizeOfHeaders As Long
CheckSum As Long
Subsystem As Integer
DllCharacteristics As Integer
SizeOfStackReserve As Long
SizeOfStackCommit As Long
SizeOfHeapReserve As Long
SizeOfHeapCommit As Long
LoaderFlags As Long
NumberOfRvaAndSizes As Long
DataDirectory(IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1) As IMAGE_DATA_DIRECTORY
End Type

Private Type IMAGE_DOS_HEADER
Magic As Integer
BytesInLastPage As Integer
Pages As Integer
Relocations As Integer
ParagraphsInHeader As Integer
MinAlloc As Integer
MaxAlloc As Integer
InitialSS As Integer
InitialSP As Integer
CheckSum As Integer
InitialIP As Integer
InitialCS As Integer
RelocationTableFileAddress As Integer
OverlayNumber As Integer
Reserved1(3) As Integer
OEMIdentifier As Integer
OEMInformation As Integer
Reserved2(9) As Integer
NewHeaderOffset As Long
End Type

Private Type IMAGE_FILE_HEADER
Machine As Integer
NumberOfSections As Integer
TimeDateStamp As Long
PointerToSymbolTable As Long
NumberOfSymbols As Long
SizeOfOptionalHeader As Integer
Characteristics As Integer
End Type

Private Type IMAGE_NT_HEADERS
Signature As Long
FileHeader As IMAGE_FILE_HEADER
OptionalHeader As IMAGE_OPTIONAL_HEADER
End Type

Private m_udtScanner As Scanner

Private m_clsTokens() As ASMToken
Private m_lngTokenCount As Long
Private m_lngCurToken As Long

Private m_udtLabels() As ASMLabel
Private m_lngLabelCount As Long

Private m_udtExtern() As ASMExtern
Private m_lngExternCount As Long

Private m_udtInstrs() As ASMInstruction
Private m_lngInstrCount As Long

Private m_strLastError As String
Private m_strLastErrorSection As String
Private m_lngLastErrLine As Long

Private m_btOutput() As Byte
Private m_lngOutSize As Long
Private m_lngOutPos As Long

Private m_udeSubsystem As PESubsystem

Private m_blnWritePE As Boolean
Private m_lngPECodeSize As Long

Private m_lngBaseAddress As Long


Private Sub Class_Initialize()
InitInstructions
m_udeSubsystem = Subsystem_CUI
End Sub


Public Property Get Subsystem() As PESubsystem
Subsystem = m_udeSubsystem
End Property


Public Property Let Subsystem(ByVal lngVal As PESubsystem)
m_udeSubsystem = lngVal
End Property


Public Property Get PEHeader() As Boolean
PEHeader = m_blnWritePE
End Property


Public Property Let PEHeader(ByVal blnValue As Boolean)
m_blnWritePE = blnValue
End Property


Public Property Get BaseAddress() As Long
BaseAddress = m_lngBaseAddress
End Property


Public Property Let BaseAddress(ByVal lngVal As Long)
m_lngBaseAddress = lngVal
' If m_lngBaseAddress < 0 Then Err.Raise 6, , "Basis < 0 ungültig"
End Property


Public Property Get LastErrorMessage() As String
LastErrorMessage = m_strLastError
End Property


Public Property Get LastErrorSection() As String
LastErrorSection = m_strLastErrorSection
End Property


Public Property Get LastErrorLine() As Long
LastErrorLine = m_lngLastErrLine
End Property


Public Function GetOutput() As Byte()
GetOutput = m_btOutput
End Function


Public Property Get OutputSize() As Long
OutputSize = m_lngOutSize
End Property


' Ablauf:
' 1. Input in Tokens aufbrechen
' 2. Labels sammeln für einfachere Validierung
' 3. Instruktionen parsen, Pointer noch nicht komplett verarbeiten
' 4. Größen der Instruktionen und Offsets der Labels berechnen
' 5. Pointer parsen da jetzt erst Labeloffsets bekannt sind
' 6. Instruktionen schreiben
Public Function Assemble( _
strASM As String, _
Optional ByVal OnlySize As Boolean = False _
) As Boolean

ScannerInit strASM

m_lngTokenCount = 0
m_lngLabelCount = 0
m_lngInstrCount = 0
m_lngCurToken = 0
m_lngOutSize = 0
m_lngOutPos = 0
m_lngExternCount = 0

m_strLastError = ""
m_lngLastErrLine = 0

TokenizeInput

If FindLabels() Then
If ParseInstructions() Then
If GetInstructionSizes() Then
If OnlySize Then
Assemble = True
Else
If ParsePointers() Then
If m_blnWritePE Then
If Not WritePEHeader() Then Exit Function
End If

If AssembleInstructions() Then
If m_blnWritePE Then
OutputJumpTo RoundToMinSize(OutputPosition)
WritePEImports
End If
Assemble = True
End If
End If
End If
End If
End If
End If
End Function


Private Sub WritePEImports()
Dim lngRVAIAT As Long
Dim ntHdr As IMAGE_NT_HEADERS
Dim scHdr As IMAGE_SECTION_HEADER

Const SECTIONS = 2

lngRVAIAT = RoundToSectionSize(Len(ntHdr) + Len(scHdr) * SECTIONS)
lngRVAIAT = lngRVAIAT + RoundToSectionSize(m_lngPECodeSize)

WriteIAT lngRVAIAT
WriteIIDs lngRVAIAT
WriteIAT lngRVAIAT
WriteImpNames
End Sub


Private Sub WriteImpNames()
Dim i As Long
Dim j As Long

For i = 0 To m_lngExternCount - 1
For j = 0 To m_udtExtern(i).FunctionCount - 1
OutputInteger 0
WriteStr0Ev m_udtExtern(i).Functions(j)
Next
WriteStr0Ev m_udtExtern(i).LibName
Next
End Sub


Private Sub WriteStr0Ev(ByVal strN As String)
Dim btN() As Byte

btN = StrConv(strN & ChrW$(0), vbFromUnicode)
OutputMem VarPtr(btN(0)), UBound(btN) + 1

If (UBound(btN) + 1) Mod 2 = 1 Then
OutputByte 0
End If
End Sub


Private Sub WriteIIDs(ByVal base As Long)
Dim i As Long
Dim j As Long
Dim im As IMAGE_IMPORT_DIRECTORY
Dim eim As IMAGE_IMPORT_DIRECTORY

For i = 0 To m_lngExternCount - 1
With im
.ModuleName = base + GetRelOfLibname(i)
.ImportAddressTable = base + GetIATLibStart(i)
.ImportLookupTable = base + GetILTLibStart(i)
End With

OutputMem VarPtr(im), Len(im)
Next

OutputMem VarPtr(eim), Len(eim)
End Sub


Private Sub WriteIAT(ByVal base As Long)
Dim i As Long
Dim j As Long

For i = 0 To m_lngExternCount - 1
For j = 0 To m_udtExtern(i).FunctionCount - 1
OutputLong base + GetRelOfFncname(i, j)
Next
OutputLong 0
Next
End Sub


Private Function GetRelOfFncname(ByVal libdx As Long, ByVal fncidx As Long) As Long
Dim i As Long
Dim j As Long
Dim sz As Long
Dim im As IMAGE_IMPORT_DIRECTORY

For i = 0 To m_lngExternCount - 1
sz = sz + 4 * (m_udtExtern(i).FunctionCount + 1) * 2
sz = sz + Len(im)
Next
If m_lngExternCount > 0 Then sz = sz + Len(im)

For i = 0 To m_lngExternCount - 1
For j = 0 To m_udtExtern(i).FunctionCount - 1
If (i = libdx) And (j = fncidx) Then
GetRelOfFncname = sz
Exit Function
Else
sz = sz + 2 + EvenSize(Len(m_udtExtern(i).Functions(j)) + 1)
End If
Next
sz = sz + EvenSize(Len(m_udtExtern(i).LibName) + 1)
Next
End Function


Private Function GetRelOfLibname(ByVal index As Long) As Long
Dim i As Long
Dim j As Long
Dim sz As Long
Dim im As IMAGE_IMPORT_DIRECTORY

For i = 0 To m_lngExternCount - 1
sz = sz + 4 * (m_udtExtern(i).FunctionCount + 1) * 2
sz = sz + Len(im)
Next
If m_lngExternCount > 0 Then sz = sz + Len(im)

For i = 0 To m_lngExternCount - 1
For j = 0 To m_udtExtern(i).FunctionCount - 1
sz = sz + 2 + EvenSize(Len(m_udtExtern(i).Functions(j)) + 1)
Next

If i <> index Then
sz = sz + EvenSize(Len(m_udtExtern(i).LibName) + 1)
Else
Exit For
End If
Next

GetRelOfLibname = sz
End Function


Private Function WritePEHeader() As Boolean
Dim mzHdr As IMAGE_DOS_HEADER
Dim ntHdr As IMAGE_NT_HEADERS
Dim scHdr As IMAGE_SECTION_HEADER
Dim sdHdr As IMAGE_SECTION_HEADER
Dim impTbl As IMAGE_IMPORT_DIRECTORY
Dim lngImp As Long
Dim btDOS() As Byte

Const SECTIONS = 2

If GetLabelIndex("MAIN") = -1 Then
SetError "Einsprungspunkt ""Main"" nicht gefunden.", 0, ""
Exit Function
End If

lngImp = GetNeededImportsSize()
If lngImp = 0 Then lngImp = 1

With mzHdr
.Magic = IMAGE_DOS_HDR16_MAGIC
.BytesInLastPage = 144
.Pages = 3
.ParagraphsInHeader = 4
.MaxAlloc = &HFFFF
.InitialSP = &HB8
.RelocationTableFileAddress = &H40
.NewHeaderOffset = Len(mzHdr) + 64
End With

With ntHdr
.Signature = IMAGE_DOS_HDR32_MAGIC

With .FileHeader
.Machine = IMAGE_FILE_MACHINE_I386
.NumberOfSections = SECTIONS
.SizeOfOptionalHeader = Len(ntHdr.OptionalHeader)
.Characteristics = IMAGE_FILE_RELOCS_STRIPPED Or IMAGE_FILE_LINE_NUMS_STRIPPED Or _
IMAGE_FILE_LOCAL_SYMS_STRIPPED Or IMAGE_FILE_EXECUTABLE_IMAGE Or _
IMAGE_FILE_32BIT_MACHINE Or IMAGE_FILE_DEBUG_STRIPPED Or _
IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP Or IMAGE_FILE_NET_RUN_FROM_SWAP
End With

With .OptionalHeader
.Magic = IMAGE_NT_OPTIONAL_HDR32_MAGIC
.SizeOfCode = RoundToMinSize(m_lngPECodeSize)
.SizeOfInitializedData = RoundToMinSize(lngImp)
.BaseOfCode = RoundToSectionSize(Len(ntHdr) + Len(scHdr) * SECTIONS)
.BaseOfData = .BaseOfCode + RoundToSectionSize(.SizeOfCode)
.AddressOfEntryPoint = m_udtLabels(GetLabelIndex("MAIN")).Offset - m_lngBaseAddress
.ImageBase = m_lngBaseAddress
.SectionAlignment = MEM_SECTION_SIZE
.FileAlignment = FILE_SECTION_SIZE
.MajorOperatingSystemVersion = 4
.MajorSubsystemVersion = 4
.SizeOfImage = .BaseOfData + RoundToSectionSize(lngImp)
.SizeOfHeaders = GetPEHeaderSize()
.Subsystem = m_udeSubsystem
.SizeOfStackReserve = &H100000
.SizeOfStackCommit = &H1000
.SizeOfHeapReserve = &H100000
.SizeOfHeapCommit = &H1000
.NumberOfRvaAndSizes = 16

With .DataDirectory(ETableImport)
.VirtualAddress = ntHdr.OptionalHeader.BaseOfCode + _
RoundToSectionSize(ntHdr.OptionalHeader.SizeOfCode) + _
GetNeededIATSize()

.Size = Len(impTbl)
End With

With .DataDirectory(ETableIAT)
.VirtualAddress = ntHdr.OptionalHeader.BaseOfCode + _
RoundToSectionSize(ntHdr.OptionalHeader.SizeOfCode)

.Size = GetNeededIATSize()
End With
End With
End With

With scHdr
WriteSectionName scHdr, ".text"
.VirtSizePhysAddr = m_lngPECodeSize
.VirtualAddress = ntHdr.OptionalHeader.BaseOfCode
.SizeOfRawData = RoundToMinSize(m_lngPECodeSize)
.PointerToRawData = GetPEHeaderSize()
.Characteristics = IMAGE_SCN_CNT_CODE Or _
IMAGE_SCN_MEM_EXECUTE Or _
IMAGE_SCN_MEM_READ Or _
IMAGE_SCN_MEM_WRITE
End With

With sdHdr
WriteSectionName sdHdr, ".rdata"
.VirtSizePhysAddr = lngImp
.VirtualAddress = ntHdr.OptionalHeader.BaseOfData
.SizeOfRawData = RoundToMinSize(lngImp)
.PointerToRawData = scHdr.PointerToRawData + scHdr.SizeOfRawData
.Characteristics = IMAGE_SCN_MEM_READ Or _
IMAGE_SCN_MEM_WRITE
End With

btDOS = HexToByte(DOS_CODE_RELOCATIONS)

OutputMem VarPtr(mzHdr), Len(mzHdr)
OutputMem VarPtr(btDOS(0)), UBound(btDOS) + 1
OutputMem VarPtr(ntHdr), Len(ntHdr)
OutputMem VarPtr(scHdr), Len(scHdr)
OutputMem VarPtr(sdHdr), Len(sdHdr)

OutputJumpTo RoundToMinSize(OutputPosition)

WritePEHeader = True
End Function


Private Sub WriteSectionName(sc As IMAGE_SECTION_HEADER, ByVal strName As String)
Dim i As Long

For i = 1 To Len(strName)
sc.SectionName(i - 1) = Asc(Mid$(strName, i, 1))
Next
End Sub


Private Function GetPEHeaderSize() As Long
Dim mzHdr As IMAGE_DOS_HEADER
Dim ntHdr As IMAGE_NT_HEADERS
Dim scHdr As IMAGE_SECTION_HEADER

Const SECTIONS = 2

GetPEHeaderSize = RoundToMinSize(Len(mzHdr) + 64 + Len(ntHdr) + Len(scHdr) * SECTIONS)
End Function


' Jede Instruktion hat Präfixe (opt.), einen OpCode und Argumente (opt.).
' Diese nacheinander ausgeben
Private Function AssembleInstructions() As Boolean
Dim i As Long
Dim lngSz As Long

For i = 0 To m_lngInstrCount - 1
lngSz = m_lngOutPos

If m_udtInstrs(i).data.Size <> BitsUnknown Then
If Not RawDataOut(m_udtInstrs(i).data) Then Exit Function
Else
InstructionOutPrefixes m_udtInstrs(i)
InstructionOutOpCode m_udtInstrs(i)
If Not InstructionOutArgs(m_udtInstrs(i)) Then Exit Function
End If

lngSz = m_lngOutPos - lngSz
If lngSz <> m_udtInstrs(i).Size Then Err.Raise 123, , "Falsche Größe bei Ausgabe"
Next

AssembleInstructions = True
End Function


' db, dw, dd Ketten ausgeben
Private Function RawDataOut(data As RawData) As Boolean
Dim i As Long

For i = 0 To data.ValueCount - 1
OutputBytes data.Values(i), data.Size
Next

RawDataOut = True
End Function


' Argumente ausgeben. ModR/M Byte, falls benötigt.
' Außerdem SIB Byte, wenn im Pointer 2 Register,
' Registervielfache und/oder ESP verwendet wurden.
Private Function InstructionOutArgs(udtInstr As ASMInstruction) As Boolean
Dim i As Long
Dim j As Long

Dim udtModRM As ModRM
Dim blnModRM As Boolean
Dim blnSIBNeeded As Boolean

Dim lngImmVal() As Long
Dim udeImmSize() As ParamSize
Dim lngImmValCnt As Long
Dim blnImmVal As Boolean

Dim lngDisplacement As Long
Dim udeDispSize As ParamSize
Dim blnDisplacement As Boolean

Dim lngSIBPtrIdx As Long

Dim blnGotXMMReg As Boolean
Dim lngMMVal As Long

With Instructions(udtInstr.OpCodeIndex)
blnModRM = .ModRM
If .RegOpExt > -1 Then
udtModRM.reg = .RegOpExt
blnGotXMMReg = True
End If
End With

For i = 0 To udtInstr.ArgCount - 1
With Instructions(udtInstr.OpCodeIndex).Parameters(i)
If Not .Forced Then

If (.PType = ParamImm) Or (.PType = ParamRel) Then
' Eine Instruktion kann mehrere Immediates haben
ReDim Preserve lngImmVal(lngImmValCnt) As Long
ReDim Preserve udeImmSize(lngImmValCnt) As ParamSize

If udtInstr.Args(i).TType = ParamImm Then
lngImmVal(lngImmValCnt) = udtInstr.Args(i).value
ElseIf udtInstr.Args(i).TType = ParamRel Then
lngImmVal(lngImmValCnt) = m_udtLabels(udtInstr.Args(i).SymbolIndex).Offset
End If

If .PType = ParamRel Then
' Ist ein relativer Wert gefragt, aus absoluter Adresse
' eine zum Instruktionsende relative Adresse basteln
lngImmVal(lngImmValCnt) = lngImmVal(lngImmValCnt) - (udtInstr.Offset + udtInstr.Size)
End If

If (SizesForInt(lngImmVal(lngImmValCnt)) And .Size) = 0 Then
SetError "Relativer Wert zu groß für Instruktion", udtInstr.Line, udtInstr.Section
Exit Function
End If

udeImmSize(lngImmValCnt) = .Size
lngImmValCnt = lngImmValCnt + 1
blnImmVal = True

ElseIf .PType = ParamReg Then
' Register muss in ModR/M Byte stehen, sonst wärs forced
udtModRM.reg = ModRMRegNum(udtInstr.Args(i).Register)

ElseIf .PType = ParamMM Then
Select Case udtInstr.Args(i).MMRegister
Case MM0, XMM0: lngMMVal = 0
Case MM1, XMM1: lngMMVal = 1
Case MM2, XMM2: lngMMVal = 2
Case MM3, XMM3: lngMMVal = 3
Case MM4, XMM4: lngMMVal = 4
Case MM5, XMM5: lngMMVal = 5
Case MM6, XMM6: lngMMVal = 6
Case MM7, XMM7: lngMMVal = 7
End Select

If blnGotXMMReg Then
udtModRM.Mod = 3
udtModRM.rm = lngMMVal
Else
udtModRM.reg = lngMMVal
blnGotXMMReg = True
End If

ElseIf (.PType = (ParamMem Or ParamReg)) Or _
(.PType = (ParamMem Or ParamMM)) Or _
(.PType = ParamMem) Then

If (.PType = ParamMem) And (Not blnModRM) Then
' !#! Kann das auch mehrmals pro Instruktion vorkommen? !#!
lngDisplacement = udtInstr.Args(i).Pointer.Ptr.Displacement
udeDispSize = Bits32
blnDisplacement = True
Else
If udtInstr.Args(i).TType = ParamMem Then
Select Case udtInstr.Args(i).Pointer.RegisterCount
Case 0:
' kein Register im Pointer, nur Displacement möglich
If udtInstr.Args(i).Pointer.HasDisplacement Then
udtModRM.Disp = udtInstr.Args(i).Pointer.Ptr.Displacement
udtModRM.DispSize = Bits32
udtModRM.Mod = 0
udtModRM.rm = 5
End If

Case 1:
' 1 Register im Pointer, kann noch mit ModR/M
' kodiert werden, außer Register ist ESP
' oder ist ein Vielfaches (reg*2/3/4/5/8/9)
If udtInstr.Args(i).Pointer.HasDisplacement Then
udtModRM.Disp = udtInstr.Args(i).Pointer.Ptr.Displacement
udtModRM.DispSize = udtInstr.Args(i).Pointer.Ptr.DispSize
Select Case udtModRM.DispSize
Case Bits8: udtModRM.Mod = 1
Case Else: udtModRM.Mod = 2
End Select
Else
udtModRM.Mod = 0
End If

For j = 0 To REG_COUNT - 1
If udtInstr.Args(i).Pointer.Ptr.Registers(j) Then
If udtInstr.Args(i).Pointer.Ptr.Registers(j) > 1 Then
blnSIBNeeded = True
lngSIBPtrIdx = i
Else
Select Case IdxToReg(j)
Case RegEAX: udtModRM.rm = 0
Case RegECX: udtModRM.rm = 1
Case RegEDX: udtModRM.rm = 2
Case RegEBX: udtModRM.rm = 3
Case RegEBP: udtModRM.rm = 5
Case RegESI: udtModRM.rm = 6
Case RegEDI: udtModRM.rm = 7
Case RegESP: blnSIBNeeded = True
lngSIBPtrIdx = i
End Select
End If

Exit For
End If
Next

Case 2:
' 2 Register, SIB nötig
If udtInstr.Args(i).Pointer.HasDisplacement Then
udtModRM.Disp = udtInstr.Args(i).Pointer.Ptr.Displacement
udtModRM.DispSize = udtInstr.Args(i).Pointer.Ptr.DispSize
Select Case udtModRM.DispSize
Case Bits8: udtModRM.Mod = 1
Case Else: udtModRM.Mod = 2
End Select
Else
udtModRM.Mod = 0
End If

blnSIBNeeded = True
lngSIBPtrIdx = i

Case Else:
SetError "Ungültige Anzahl an Registern in Ptr", udtInstr.Line, udtInstr.Section
Exit Function

End Select

ElseIf udtInstr.Args(i).TType = ParamReg Then
' 2. Register in ModR/M kodieren
udtModRM.Mod = 3
udtModRM.rm = ModRMRegNum(udtInstr.Args(i).Register)

ElseIf udtInstr.Args(i).TType = (ParamMem Or ParamExt) Then
lngDisplacement = udtInstr.Args(i).Pointer.Ptr.Displacement
udeDispSize = Bits32
udtModRM.rm = 5
blnDisplacement = True

ElseIf udtInstr.Args(i).TType = ParamMM Then
Select Case udtInstr.Args(i).MMRegister
Case MM0, XMM0: udtModRM.rm = 0
Case MM1, XMM1: udtModRM.rm = 1
Case MM2, XMM2: udtModRM.rm = 2
Case MM3, XMM3: udtModRM.rm = 3
Case MM4, XMM4: udtModRM.rm = 4
Case MM5, XMM5: udtModRM.rm = 5
Case MM6, XMM6: udtModRM.rm = 6
Case MM7, XMM7: udtModRM.rm = 7
End Select
udtModRM.Mod = 3

End If
End If

End If

End If
End With
Next

If blnSIBNeeded Then
udtModRM.rm = 4
If Not WriteSIB(udtInstr, udtModRM, udtInstr.Args(lngSIBPtrIdx).Pointer.Ptr) Then
Exit Function
End If
Else
If blnModRM Then WriteModRM udtModRM
End If

If blnDisplacement Then OutputBytes lngDisplacement, udeDispSize
If blnImmVal Then
For i = 0 To lngImmValCnt - 1
OutputBytes lngImmVal(i), udeImmSize(i)
Next
End If

If Instructions(udtInstr.OpCodeIndex).Now3DByte > -1 Then
OutputByte Instructions(udtInstr.OpCodeIndex).Now3DByte
End If

InstructionOutArgs = True
End Function


Private Function WriteSIB( _
udtInstr As ASMInstruction, _
rm As ModRM, _
Ptr As Pointer _
) As Boolean

Dim udtSIB As SIB
Dim udeReg(1) As ASMRegisters
Dim lngRegCnt(1) As Long
Dim lngScale As Long
Dim lngBase As Long
Dim i As Long
Dim j As Long

' das oder die verwendeten Register finden
For i = 0 To REG_COUNT - 1
If Ptr.Registers(i) Then
udeReg(j) = IdxToReg(i)
lngRegCnt(j) = Ptr.Registers(i)
j = j + 1
End If
Next

' Feststellen, welches Register ein Vielfaches beträgt und damit
' das Scale Register ist. Das Base Reg ist dann das andere.
If lngRegCnt(0) >= 1 And lngRegCnt(1) = 1 Then
lngScale = 0
ElseIf lngRegCnt(1) >= 1 And lngRegCnt(0) = 1 Then
lngScale = 1
End If
lngBase = 1 - lngScale

If (Ptr.UsedRegisters = 1) And (lngRegCnt(0) = 1) Then
' nur ein Register verwendet, das kein vielfaches ist
udtSIB.sscale = 0
udtSIB.index = 4

Select Case udeReg(0)
Case RegEAX: udtSIB.base = 0
Case RegECX: udtSIB.base = 1
Case RegEDX: udtSIB.base = 2
Case RegEBX: udtSIB.base = 3
Case RegESP: udtSIB.base = 4 ' <= alles andere durch ModRM darstellbar
Case RegEBP: udtSIB.base = 5
Case RegESI: udtSIB.base = 6
Case RegEDI: udtSIB.base = 7
End Select

Else

If (Ptr.UsedRegisters = 1) And (lngRegCnt(0) > 1) Then
' ein Register, das ein vielfaches ist
If lngRegCnt(0) = 2 Or _
lngRegCnt(0) = 3 Or _
lngRegCnt(0) = 5 Or _
lngRegCnt(0) = 9 Then

If lngRegCnt(0) = 2 Then
udtSIB.sscale = 0
Else
udtSIB.sscale = GetFirstSetBitIdx(lngRegCnt(0) - 1)
End If

Select Case udeReg(0)
Case RegEAX: udtSIB.index = 0: udtSIB.base = 0
Case RegECX: udtSIB.index = 1: udtSIB.base = 1
Case RegEDX: udtSIB.index = 2: udtSIB.base = 2
Case RegEBX: udtSIB.index = 3: udtSIB.base = 3
Case RegESI: udtSIB.index = 6: udtSIB.base = 6
Case RegEDI: udtSIB.index = 7: udtSIB.base = 7
Case RegEBP: udtSIB.index = 5: udtSIB.base = 5
rm.Mod = 1
Case Else:
SetError "In SIB ungültige Vielfache von Register", udtInstr.Line, udtInstr.Section
Exit Function
End Select

ElseIf lngRegCnt(0) = 4 Or lngRegCnt(0) = 8 Then
' wäre Mod vom ModR/M Byte hier > 0,
' würde EBP+sbyte oder EBP+sdword mitkodiert
rm.Mod = 0
udtSIB.base = 5
udtSIB.sscale = GetFirstSetBitIdx(lngRegCnt(0))

Select Case udeReg(0)
Case RegEAX: udtSIB.index = 0
Case RegECX: udtSIB.index = 1
Case RegEDX: udtSIB.index = 2
Case RegEBX: udtSIB.index = 3
Case RegEBP: udtSIB.index = 5
Case RegESI: udtSIB.index = 6
Case RegEDI: udtSIB.index = 7
Case Else:
SetError "In SIB ungültige Vielfache von Register", udtInstr.Line, udtInstr.Section
Exit Function
End Select

Else
SetError "In SIB ungültige Vielfache von Register", udtInstr.Line, udtInstr.Section
Exit Function

End If

ElseIf Ptr.UsedRegisters = 2 Then
' 2 Register im Pointer

Select Case lngRegCnt(lngScale)
Case 1, 2, 4, 8:
' Scale Register darf nur 1/2/4/8-fach gewichtet werden
Case Else:
SetError "Mögliche Vielfache von Scale Register: 1, 2, 4, 8", udtInstr.Line, udtInstr.Section
Exit Function
End Select

If lngRegCnt(lngBase) <> 1 Then
SetError "Base Register kann kein Vielfaches betragen", udtInstr.Line, udtInstr.Section
Exit Function
End If

' ESP kann nur in der Base kodiert werden,
' darf deshalb nicht Scale sein.
' Gleiches Spiel mit EBP, nur andersrum.
If (lngRegCnt(lngScale) = 1) And (lngRegCnt(lngBase)) = 1 Then
If (udeReg(lngScale) = RegESP) Or (udeReg(lngBase) = RegEBP) Then
lngScale = lngBase
lngBase = 1 - lngScale
End If
End If

udtSIB.sscale = GetFirstSetBitIdx(lngRegCnt(lngScale))

Select Case udeReg(lngScale)
Case RegEAX: udtSIB.index = 0
Case RegECX: udtSIB.index = 1
Case RegEDX: udtSIB.index = 2
Case RegEBX: udtSIB.index = 3
Case RegEBP: udtSIB.index = 5
Case RegESI: udtSIB.index = 6
Case RegEDI: udtSIB.index = 7
Case Else:
SetError "Ungültiges Scale Register", udtInstr.Line, udtInstr.Section
Exit Function
End Select

Select Case udeReg(lngBase)
Case RegEAX: udtSIB.base = 0
Case RegECX: udtSIB.base = 1
Case RegEDX: udtSIB.base = 2
Case RegEBX: udtSIB.base = 3
Case RegESP: udtSIB.base = 4
Case RegEBP: udtSIB.base = 5
Case RegESI: udtSIB.base = 6
Case RegEDI: udtSIB.base = 7
Case Else:
SetError "Ungültiges Base Register", udtInstr.Line, udtInstr.Section
Exit Function
End Select
End If
End If

OutputByte (rm.Mod * &H40) Or (rm.reg * &H8) Or rm.rm
OutputByte (udtSIB.sscale * &H40) Or (udtSIB.index * &H8) Or udtSIB.base
If rm.DispSize <> BitsUnknown Then OutputBytes rm.Disp, rm.DispSize

WriteSIB = True
End Function


Private Function ModRMRegNum(ByVal reg As ASMRegisters) As Long
Select Case reg
Case RegAL, RegAX, RegEAX: ModRMRegNum = 0
Case RegCL, RegCX, RegECX: ModRMRegNum = 1
Case RegDL, RegDX, RegEDX: ModRMRegNum = 2
Case RegBL, RegBX, RegEBX: ModRMRegNum = 3
Case RegAH, RegSP, RegESP: ModRMRegNum = 4
Case RegCH, RegBP, RegEBP: ModRMRegNum = 5
Case RegDH, RegSI, RegESI: ModRMRegNum = 6
Case RegBH, RegDI, RegEDI: ModRMRegNum = 7
End Select
End Function


Private Sub WriteModRM(rm As ModRM)
OutputByte (rm.Mod * &H40) Or (rm.reg * &H8) Or rm.rm
If rm.DispSize <> BitsUnknown Then OutputBytes rm.Disp, rm.DispSize
End Sub


Private Sub InstructionOutOpCode(udtInstr As ASMInstruction)
Dim i As Long

With Instructions(udtInstr.OpCodeIndex)
For i = 0 To .OpCodeLen - 1
OutputByte .OpCode(i)
Next
End With
End Sub


Private Sub InstructionOutPrefixes(udtInstr As ASMInstruction)
With Instructions(udtInstr.OpCodeIndex)
If (.Prefixes And PrefixFlgOperandSizeOverride) Then _
OutputByte PREFIX_OPERAND_SIZE_OVERRIDE
If (.Prefixes And PrefixFlgAddressSizeOverride) Then _
OutputByte PREFIX_ADDRESS_SIZE_OVERRIDE
If (.Prefixes And PrefixFlgBranchNotTaken) Then _
OutputByte PREFIX_BRANCH_NOT_TAKEN
If (.Prefixes And PrefixFlgBranchTaken) Then _
OutputByte PREFIX_BRANCH_TAKEN
End With

With udtInstr
If (.flags And PrefixFlgLock) Then _
OutputByte PREFIX_LOCK
If (.flags And PrefixFlgRep) Then _
OutputByte PREFIX_REP
If (.flags And PrefixFlgRepne) Then _
OutputByte PREFIX_REPNE
End With

Select Case udtInstr.Segment
Case SegCs: OutputByte PREFIX_SEGMENT_CS
Case SegDs: OutputByte PREFIX_SEGMENT_DS
Case SegEs: OutputByte PREFIX_SEGMENT_ES
Case SegFs: OutputByte PREFIX_SEGMENT_FS
Case SegGs: OutputByte PREFIX_SEGMENT_GS
Case SegSs: OutputByte PREFIX_SEGMENT_SS
End Select
End Sub


Private Sub OutputMem(ByVal Ptr As Long, ByVal bytes As Long)
If m_lngOutPos + bytes > m_lngOutSize Then
'Err.Raise 123456, , "Nicht genügend Platz in Ausgabearray"
End If

CopyMemory m_btOutput(m_lngOutPos), ByVal Ptr, bytes
m_lngOutPos = m_lngOutPos + bytes
End Sub


Private Sub OutputJumpTo(ByVal lngVal As Long)
If lngVal >= m_lngOutSize Then
'Err.Raise 123456, , "Neue Position außerhalb von Ausgabearray"
End If

m_lngOutPos = lngVal
End Sub


Private Property Get OutputPosition() As Long
OutputPosition = m_lngOutPos
End Property


Private Sub OutputBytes(ByVal value As Long, ByVal Size As ParamSize)
Select Case Size
Case Bits8: OutputByte value
Case Bits16: OutputInteger value
Case Bits32: OutputLong value
Case Else: Err.Raise 123456, , "Ungültige Größe"
End Select
End Sub


Private Sub OutputByte(ByVal value As Long)
If value < 0 Then
m_btOutput(m_lngOutPos) = CByte(value + 256) ' Signed Byte
Else
m_btOutput(m_lngOutPos) = CByte(value)
End If

m_lngOutPos = m_lngOutPos + 1
End Sub


' !#! Unterstützt keine Unsigned Ints !#!
Private Sub OutputInteger(ByVal value As Long)
CopyMemory m_btOutput(m_lngOutPos), value, 2
m_lngOutPos = m_lngOutPos + 2
End Sub


' !#! Unterstützt keine Unsigned Ints !#!
Private Sub OutputLong(ByVal value As Long)
CopyMemory m_btOutput(m_lngOutPos), value, 4
m_lngOutPos = m_lngOutPos + 4
End Sub


Private Function ParsePointers() As Boolean
Dim i As Long
Dim j As Long

For i = 0 To m_lngInstrCount - 1
For j = 0 To m_udtInstrs(i).ArgCount - 1
With m_udtInstrs(i).Args(j)
If .TType = ParamMem Then
m_lngCurToken = .Pointer.TokenIndex
If Not ParsePointer(.Pointer.Ptr) Then Exit Function
End If
End With
Next
Next

ParsePointers = True
End Function


' Muss nichts mehr validiert werden, wurde schon validiert.
Private Function ParsePointer(Ptr As Pointer) As Boolean
Dim lngSgn As Long
Dim lngTms As Long
Dim lngVal As Long
Dim i As Long
Dim lngReg As Long
Dim blnReg As Boolean

If Not Match(TokenBracketLeft) Then
SetError """["" erwartet", Token.Line, Token.Section
Exit Function
End If

If Match(TokenOpAdd) Then
lngSgn = 1
ElseIf Match(TokenOpSub) Then
lngSgn = -1
Else
lngSgn = 1
End If

Do
lngTms = 1
blnReg = False

Do
Select Case Token.TType
Case TokenRegister:
blnReg = True
lngReg = RegToIdx(RegStrToReg(Token.Content))
Match TokenRegister
Case TokenValue:
lngTms = lngTms * Token.value
Match TokenValue
Case TokenSymbol:
lngTms = lngTms * m_udtLabels(GetLabelIndex(Token.Content)).Offset
Match TokenSymbol
End Select
Loop While Match(TokenOpMul)

If blnReg Then
Ptr.Registers(lngReg) = Ptr.Registers(lngReg) + lngSgn * lngTms
Else
Ptr.Displacement = Ptr.Displacement + lngSgn * lngTms
End If

If Match(TokenOpAdd) Then
lngSgn = 1
ElseIf Match(TokenOpSub) Then
lngSgn = -1
Else
Exit Do
End If
Loop

If Not Match(TokenBracketRight) Then
SetError """]"" erwartet", Token.Line, Token.Section
Else
ParsePointer = True
End If
End Function


Private Function GetInstructionSizes() As Boolean
Dim i As Long
Dim j As Long
Dim k As Long
Dim Size As Long
Dim lngImpSz As Long
Dim blnFoundI As Boolean

For i = 0 To m_lngInstrCount - 1 ' alle Instructions im Quelltext
If m_udtInstrs(i).data.Size <> BitsUnknown Then
With m_udtInstrs(i)
.Size = .data.ValueCount * .data.Size \ 8
End With
Else
blnFoundI = False

For j = 0 To InstructionCount - 1 ' alle bekannten Instructions
If StrComp(m_udtInstrs(i).Mnemonic, Instructions(j).Mnemonic, vbTextCompare) = 0 Then
blnFoundI = True

If CompareInstrs(m_udtInstrs(i), Instructions(j)) Then
' OpCode Länge + alle Präfixe, ModR/M Byte
Size = Instructions(j).OpCodeLen + _
BitCount(Instructions(j).Prefixes Or m_udtInstrs(i).flags) + _
Abs(m_udtInstrs(i).Segment <> SegUnknown) + _
Abs(Instructions(j).ModRM) + _
Abs(Instructions(j).Now3DByte > -1)

' Dazu kommen noch Immediates, Displacement, SIB Byte
If Instructions(j).ParamCount > 0 Then
For k = 0 To Instructions(j).ParamCount - 1
With Instructions(j).Parameters(k)
If Not .Forced Then

Select Case .PType

Case ParamImm, ParamRel:
Size = Size + .Size \ 8 ' Imm

Case ParamMem Or ParamReg, ParamMem:
If Not Instructions(j).ModRM And .PType = ParamMem Then
Size = Size + 4 ' Imm
Else
If m_udtInstrs(i).Args(k).Pointer.HasDisplacement Then
Size = Size + m_udtInstrs(i).Args(k).Pointer.DispSize \ 8
End If

If m_udtInstrs(i).Args(k).Pointer.RegisterCount = 2 Or _
m_udtInstrs(i).Args(k).Pointer.RegisterMultiples Then
Size = Size + 1 ' SIB
End If
End If

End Select

End If
End With
Next
End If

m_udtInstrs(i).OpCodeIndex = j
m_udtInstrs(i).Size = Size
Exit For
End If
End If
Next

If j = InstructionCount Then
If blnFoundI Then
SetError "Ungültige Argumente", m_udtInstrs(i).Line, m_udtInstrs(i).Section
Else
SetError "Unbekannter Befehl: " & m_udtInstrs(i).Mnemonic, m_udtInstrs(i).Line, m_udtInstrs(i).Section
End If

Exit Function
End If
End If
Next

FillInOffsets
If m_blnWritePE Then
m_lngPECodeSize = m_lngOutSize

lngImpSz = GetNeededImportsSize()
If lngImpSz = 0 Then
m_lngOutSize = RoundToMinSize(GetPEHeaderSize()) + _
RoundToMinSize(m_lngPECodeSize) + _
RoundToMinSize(1)
Else
m_lngOutSize = RoundToMinSize(GetPEHeaderSize()) + _
RoundToMinSize(m_lngPECodeSize) + _
RoundToMinSize(lngImpSz)
End If

FillInIAT RoundToSectionSize(GetPEHeaderSize()) + _
RoundToSectionSize(m_lngPECodeSize)
End If

ReDim m_btOutput(m_lngOutSize - 1) As Byte

GetInstructionSizes = True
End Function


' Label- und Instruktionsoffsets berechnen
Private Sub FillInOffsets()
Dim i As Long
Dim j As Long
Dim lngPEOffset As Long

If m_blnWritePE Then
lngPEOffset = RoundToSectionSize(GetPEHeaderSize)
End If

For i = 0 To m_lngInstrCount - 1
m_udtInstrs(i).Offset = m_lngOutSize + m_lngBaseAddress + lngPEOffset
m_lngOutSize = m_lngOutSize + m_udtInstrs(i).Size

If j < m_lngLabelCount Then
If m_udtLabels(j).Instruction = i Then
m_udtLabels(j).Offset = m_udtInstrs(i).Offset
j = j + 1
End If
End If
Next

If j < m_lngLabelCount Then
With m_udtInstrs(m_lngInstrCount - 1)
For j = j To m_lngLabelCount - 1
m_udtLabels(j).Offset = .Offset
Next
End With
End If
End Sub


' Sprungadressen für importierte Funktionen berechnen
Private Sub FillInIAT(ByVal reladdr As Long)
Dim i As Long
Dim j As Long
Dim k As Long
Dim libidx As Long
Dim fncidx As Long

For i = 0 To m_lngInstrCount - 1
For j = 0 To m_udtInstrs(i).ArgCount - 1
If (m_udtInstrs(i).Args(j).TType And ParamExt) Then
libidx = (m_udtInstrs(i).Args(j).SymbolIndex \ &H10000) And &HFFFF&
fncidx = m_udtInstrs(i).Args(j).SymbolIndex And &HFFFF&
m_udtInstrs(i).Args(j).Pointer.Ptr.Displacement = GetExternRelOfFnc(libidx, fncidx, reladdr)
End If
Next
Next
End Sub


' Geparste Instruction mit einer aus dem Instruction Set vergleichen
Private Function CompareInstrs( _
src As ASMInstruction, _
Comp As Instruction _
) As Boolean

Dim i As Long

If src.ArgCount = Comp.ParamCount Then
For i = 0 To src.ArgCount - 1
' Imm und Rel sollen gleichwertig behandelt werden
With Comp.Parameters(i)
If (.PType And src.Args(i).TType) = 0 Then
If Not (.PType = ParamImm And src.Args(i).TType = ParamRel) Then
If Not (.PType = ParamRel And src.Args(i).TType = ParamImm) Then
Exit Function
End If
End If
End If
End With

If Comp.Parameters(i).Forced Then
Select Case Comp.Parameters(i).PType
Case ParamReg:
If src.Args(i).Register <> Comp.Parameters(i).Register Then
Exit Function
End If
Case ParamSTX:
If src.Args(i).FPURegister <> Comp.Parameters(i).FPURegister Then
Exit Function
End If
Case ParamImm:
If src.Args(i).value <> Comp.Parameters(i).value Then
Exit Function
End If
End Select
Else
If Comp.Parameters(i).PType = ParamMem Then
If Not Comp.ModRM Then
If src.Args(i).Pointer.RegisterCount > 0 Then
' Instruktion darf keine Register im Pointer haben,
' weil kein ModR/M Byte vorgesehen ist
Exit Function
End If
End If
ElseIf (Comp.Parameters(i).PType And ParamMM) Then
If IsDefinite(Comp.Parameters(i).MMRegister) Then
If Comp.Parameters(i).MMRegister <> src.Args(i).MMRegister Then
Exit Function
End If
Else
If src.Args(i).TType = ParamMem Then
If (Comp.Parameters(i).PType And ParamMem) = 0 Then
Exit Function
End If
Else
If (Comp.Parameters(i).MMRegister And src.Args(i).MMRegister) = 0 Then
Exit Function
End If
End If
End If
End If
End If

If (Comp.Parameters(i).Size And src.Args(i).Size) = 0 Then
If Comp.Parameters(i).Size <> BitsUnknown Then
Exit Function
End If
End If
Next

CompareInstrs = True
End If
End Function


' Labels sammeln
Private Function FindLabels() As Boolean
Dim i As Long
Dim lngInstrCnt As Long

For i = 1 To m_lngTokenCount - 2
If m_clsTokens(i).TType = TokenSymbol Then
If m_clsTokens(i + 1).TType = TokenOpColon Then
If GetLabelIndex(m_clsTokens(i).Content) > -1 Then
SetError "Nicht eindeutiges Label: " & m_clsTokens(i).Content, m_clsTokens(i).Line, m_clsTokens(i).Section
Exit Function
End If
AddLabel m_clsTokens(i).Content, lngInstrCnt
End If
ElseIf m_clsTokens(i).TType = TokenOperator Then
lngInstrCnt = lngInstrCnt + 1
ElseIf m_clsTokens(i).TType = TokenRawData Then
lngInstrCnt = lngInstrCnt + 1
End If
Next

FindLabels = True
End Function


' Überspringt Labels, da die schon vorher eingelesen wurden.
' Verarbeitet nur Instruktionen.
Private Function ParseInstructions() As Boolean
If Not Match(TokenBeginOfInput) Then
SetError "Unbekannter Fehler während Parserinitialisierung", 0, ""
Else
Do While Token.TType <> TokenEndOfInput
Select Case Token.TType

Case TokenExtern:
If m_blnWritePE Then
Match TokenExtern
If Not ParseExtern() Then Exit Do
Else
SetError "Externs nur im PE Modus erlaubt", Token.Line, Token.Section
Exit Function
End If

Case TokenSymbol:
Match TokenSymbol
If Not Match(TokenOpColon) Then
SetError """:"" nach Label ID erwartet", Token.Line, Token.Section
Exit Do
End If

Case TokenOperator, TokenKeyword:
If Not ParseInstruction Then Exit Do

Case TokenRawData:
If Not ParseRawData Then Exit Do

Case Else:
If Token.TType <> TokenEndOfInstruction Then
SetError "Unerwartetes Symbol: " & Token.Content, Token.Line, Token.Section
Exit Do
End If

End Select

If Not Match(TokenEndOfInstruction) Then
SetError "Unerwartetes Ende", Token.Line, Token.Section
Exit Do
Else
ParseInstructions = Token.TType = TokenEndOfInput
End If
Loop
End If
End Function


Private Function AddExtern(ByVal lib As String, ByVal fnc As String) As Boolean
Dim i As Long
Dim j As Long

AddExtern = True

For i = 0 To m_lngExternCount - 1
If StrComp(m_udtExtern(i).LibName, lib, vbTextCompare) = 0 Then
For j = 0 To m_udtExtern(i).FunctionCount - 1
If StrComp(m_udtExtern(i).Functions(j), fnc, vbTextCompare) = 0 Then
Exit Function
End If
Next

With m_udtExtern(i)
ReDim Preserve .Functions(.FunctionCount) As String
.Functions(.FunctionCount) = fnc
.FunctionCount = .FunctionCount + 1
End With
Exit Function
End If
Next

If i = m_lngExternCount Then
ReDim Preserve m_udtExtern(m_lngExternCount) As ASMExtern

With m_udtExtern(m_lngExternCount)
.LibName = lib

ReDim .Functions(0) As String
.Functions(0) = fnc
.FunctionCount = 1
End With

m_lngExternCount = m_lngExternCount + 1
End If
End Function


Private Function ParseExtern() As Boolean
Dim strLib As String
Dim strFnc As String

If Token.TType <> TokenString Then
SetError "String Identifier für Bibliotheksname erwartet", Token.Line, Token.Section
Exit Function
Else
strLib = Token.Content
Match TokenString

If Not Match(TokenSeparator) Then
SetError "Bibliotheksname und Funktionsname müssen durch ein "","" getrennt sein", Token.Line, Token.Section
Exit Function
Else
If Token.TType <> TokenSymbol Then
SetError "Symbolname der exportierten Funktion erwartet", Token.Line, Token.Section
Exit Function
Else
strFnc = Token.Content
Match TokenSymbol

If GetLabelIndex(strFnc) > -1 Then
SetError "Name nicht eindeutig", Token.Line, Token.Section
Else
ParseExtern = AddExtern(strLib, strFnc)
End If
End If
End If
End If
End Function


Private Function ParseRawData() As Boolean
Dim udtInstr As ASMInstruction
Dim i As Long
Dim lngLen As Long
Dim lngTemp As Long

Select Case UCase$(Token.Content)
Case "DB": udtInstr.data.Size = Bits8
Case "DW": udtInstr.data.Size = Bits16
Case "DD": udtInstr.data.Size = Bits32
End Select
Match TokenRawData

With udtInstr.data
Do
Select Case Token.TType
Case TokenValue:
ReDim Preserve .Values(.ValueCount) As Long
.Values(.ValueCount) = Token.value
.ValueCount = .ValueCount + 1
Match TokenValue

Case TokenString:
lngTemp = .ValueCount

ReDim Preserve .Values(.ValueCount + Len(Token.Content) - 1) As Long
For i = 1 To Len(Token.Content)
.Values(lngTemp + i - 1) = Asc(Mid$(Token.Content, i, 1))
Next

.ValueCount = .ValueCount + Len(Token.Content)
Match TokenString

Case Else:
SetError "Unerwartetes Token: " & Token.Content, udtInstr.Line, udtInstr.Section
Exit Function

End Select
Loop While Match(TokenSeparator)
End With

AddInstruction udtInstr

ParseRawData = True
End Function


Private Function ParseInstruction() As Boolean
Dim udtInstr As ASMInstruction

' Instruktion kann mehrere Schlüsselwörter wie "lock rep" haben
Do While Token.TType = TokenKeyword
Select Case UCase$(Token.Content)
Case "REP": udtInstr.flags = udtInstr.flags Or PrefixFlgRep
Case "REPE": udtInstr.flags = udtInstr.flags Or PrefixFlgRepe
Case "REPZ": udtInstr.flags = udtInstr.flags Or PrefixFlgRepz
Case "REPNE": udtInstr.flags = udtInstr.flags Or PrefixFlgRepne
Case "REPNZ": udtInstr.flags = udtInstr.flags Or PrefixFlgRepnz
Case "LOCK": udtInstr.flags = udtInstr.flags Or PrefixFlgLock
Case Else: SetError "Unbekanntes Schlüsselwort: " & Token.Content, Token.Line, Token.Section
Exit Function
End Select

Match TokenKeyword
Loop

If Token.TType <> TokenOperator Then
SetError "Operator erwartet", Token.Line, Token.Section
Else
udtInstr.Mnemonic = Token.Content
udtInstr.Line = Token.Line
udtInstr.Section = Token.Section

Match TokenOperator

If ParseArguments(udtInstr) Then
AddInstruction udtInstr
ParseInstruction = True
End If
End If
End Function


' Liest bis zu 3 Argumente pro Instruktion ein.
' Erst wird auf Schlüsselwörter geprüft, darauf kann dann
' ein Label, ein numerischer Wert, ein FPU/Segment/Allzweckregister
' oder ein Pointer (mit SIB Unterstützung) folgen.
Private Function ParseArguments(udtInstr As ASMInstruction) As Boolean
Dim lngArgs As Long
Dim lngPtrIdx As Long
Dim blnCont As Boolean

lngPtrIdx = -1

Do
If lngArgs = 3 Then
SetError "Zu viele Argumente", udtInstr.Line, udtInstr.Section
Exit Function
End If

If Token.TType = TokenKeyword Then
If Not ParseKeywords(udtInstr, lngArgs) Then Exit Function
End If

blnCont = False
Select Case Token.TType
Case TokenRegister:
If Not ParseArgumentRegister(udtInstr, udtInstr.Args(lngArgs)) Then Exit Function
Case TokenFPUReg:
If Not ParseArgumentFPUReg(udtInstr, udtInstr.Args(lngArgs)) Then Exit Function
Case TokenMMRegister:
If Not ParseArgumentMMReg(udtInstr, udtInstr.Args(lngArgs)) Then Exit Function
Case TokenSymbol:
If Not ParseArgumentSymbol(udtInstr, udtInstr.Args(lngArgs)) Then Exit Function
Case TokenValue:
If Not ParseArgumentValue(udtInstr, udtInstr.Args(lngArgs)) Then Exit Function
Case TokenBracketLeft:
If Not ParseArgumentPtr(udtInstr, udtInstr.Args(lngArgs)) Then Exit Function
lngPtrIdx = lngArgs
Case TokenSegmentReg:
If Not ParseSegmentReg(udtInstr) Then Exit Function
blnCont = True
Case TokenEndOfInstruction:
Exit Do
Case Else:
SetError "Unberwartetes Symbol: " & Token.Content, udtInstr.Line, udtInstr.Section
Exit Function
End Select

If Not blnCont Then lngArgs = lngArgs + 1
Loop While Match(TokenSeparator) Or blnCont

If lngPtrIdx > -1 Then
If udtInstr.Args(lngPtrIdx).Size = BitsUnknown Then
If lngArgs = 2 Then
If IsDefinite(udtInstr.Args(1 - lngPtrIdx).Size) Or _
(udtInstr.Args(1 - lngPtrIdx).TType And ParamMM) Then
udtInstr.Args(lngPtrIdx).Size = udtInstr.Args(1 - lngPtrIdx).Size
Else
SetError "Unbekannte Zeigergröße", udtInstr.Line, udtInstr.Section
Exit Function
End If
' Else
' SetError "Unbekannte Zeigergröße", udtInstr.Line
' Exit Function
End If
End If
End If

udtInstr.ArgCount = lngArgs
ParseArguments = True
End Function


Private Function ParseArgumentPtr( _
udtInstr As ASMInstruction, _
arg As ASMArgument _
) As Boolean

arg.TType = ParamMem
arg.Pointer.TokenIndex = m_lngCurToken
ParseArgumentPtr = ValidatePointer(udtInstr, arg.Pointer)
End Function


Private Function ParseArgumentValue( _
udtInstr As ASMInstruction, _
arg As ASMArgument _
) As Boolean

arg.TType = ParamImm
arg.value = Token.value

If arg.Size = BitsUnknown Then
arg.Size = SizesForInt(Token.value)
Else
If (arg.Size And SizesForInt(Token.value)) = 0 Then
SetError "Inkompatible Integergrößen", udtInstr.Line, udtInstr.Section
Exit Function
End If
End If

Match TokenValue
ParseArgumentValue = True
End Function


Private Function ParseArgumentSymbol( _
udtInstr As ASMInstruction, _
arg As ASMArgument _
) As Boolean

Dim lngLblIdx As Long
Dim blnExtern As Boolean

lngLblIdx = GetLabelIndex(Token.Content)
If lngLblIdx = -1 Then
lngLblIdx = GetExternIndex(Token.Content)
If lngLblIdx = -1 Then
SetError "Unbekannte Marke: " & Token.Content, udtInstr.Line, udtInstr.Section
Exit Function
Else
blnExtern = True
End If
End If

If blnExtern Then
arg.TType = ParamMem Or ParamExt
arg.SymbolIndex = lngLblIdx
arg.Size = Bits32

arg.Pointer.HasDisplacement = True
arg.Pointer.Ptr.DispSize = Bits32
arg.Pointer.DispSize = Bits32
Else
arg.TType = ParamRel
arg.SymbolIndex = lngLblIdx

If arg.Size = BitsUnknown Then
arg.Size = Bits32 Or Bits16 Or Bits8
End If
End If

Match TokenSymbol
ParseArgumentSymbol = True
End Function


Private Function ParseArgumentMMReg( _
udtInstr As ASMInstruction, _
arg As ASMArgument _
) As Boolean

arg.TType = ParamMM
arg.MMRegister = MMRegStrToNum(Token.Content)

If arg.Size <> BitsUnknown Then
If (arg.Size And (Bits32 Or Bits64 Or Bits80 Or Bits128)) = 0 Then
SetError "Inkompatible Größenangaben", udtInstr.Line, udtInstr.Section
Exit Function
End If
Else
If (arg.MMRegister < XMM0) Then
arg.Size = Bits64
Else
arg.Size = Bits128
End If
End If

Match TokenMMRegister
ParseArgumentMMReg = True
End Function


Private Function ParseArgumentFPUReg( _
udtInstr As ASMInstruction, _
arg As ASMArgument _
) As Boolean

arg.TType = ParamSTX
arg.FPURegister = FPURegStrToNum(Token.Content)

If arg.Size <> BitsUnknown Then
If (arg.Size And (Bits32 Or Bits64 Or Bits80)) = 0 Then
SetError "Inkompatible Größenangaben", udtInstr.Line, udtInstr.Section
Exit Function
End If
Else
arg.Size = Bits32 Or Bits64 Or Bits80
End If

Match TokenFPUReg
ParseArgumentFPUReg = True
End Function


Private Function ParseArgumentRegister( _
udtInstr As ASMInstruction, _
arg As ASMArgument _
) As Boolean

arg.TType = ParamReg
arg.Register = RegStrToReg(Token.Content)

If arg.Size <> BitsUnknown Then
If arg.Size <> RegisterSize(arg.Register) Then
SetError "Inkompatible Größenangaben", udtInstr.Line, udtInstr.Section
Exit Function
End If
Else
arg.Size = RegisterSize(arg.Register)
End If

Match TokenRegister
ParseArgumentRegister = True
End Function


' alle an dieser Stelle zulässigen Schlüsselwörter sind nur Größenangaben,
' deswegen ist nur ein einziges erlaubt. "byte dword" z.B. verursacht einen
' Fehler bei "dword".
Private Function ParseKeywords( _
udtInstr As ASMInstruction, _
argidx As Long _
) As Boolean

Select Case UCase$(Token.Content)
Case "BYTE": udtInstr.Args(argidx).Size = Bits8
Case "WORD": udtInstr.Args(argidx).Size = Bits16
Case "DWORD", "FLOAT": udtInstr.Args(argidx).Size = Bits32
Case "QWORD", "DOUBLE": udtInstr.Args(argidx).Size = Bits64
Case "EXTENDED": udtInstr.Args(argidx).Size = Bits80
Case "DQWORD": udtInstr.Args(argidx).Size = Bits128
Case Else: SetError "An dieser Stelle ungültiges Symbol", udtInstr.Line, udtInstr.Section
Exit Function
End Select

Match TokenKeyword
ParseKeywords = True
End Function


Private Function ValidatePointer( _
udtInstr As ASMInstruction, _
Ptr As PointerInfo _
) As Boolean

If Not Match(TokenBracketLeft) Then
SetError "Erwartet: [", udtInstr.Line, udtInstr.Section
Else
If ValidateExpr(udtInstr, Ptr) Then
If Not Match(TokenBracketRight) Then
SetError """["" erwartet", udtInstr.Line, udtInstr.Section
Else
ValidatePointer = True
End If
End If
End If
End Function


' Expression innerhalb von Brackets auswerten ( "[eax*2+ebp-10]" )
Private Function ValidateExpr( _
udtInstr As ASMInstruction, _
Ptr As PointerInfo _
) As Boolean

Dim lngRegCount(REG_COUNT - 1) As Long
Dim lngUsedRegs(1) As Long
Dim lngDisplacement As Long
Dim lngSign As Long
Dim lngReg As Long
Dim lngTms As Long
Dim i As Long
Dim blnHasSymbols As Boolean
Dim blnHasSymbol As Boolean
Dim blnHasRegister As Boolean

If Match(TokenOpAdd) Then
lngSign = 1
ElseIf Match(TokenOpSub) Then
lngSign = -1
Else
lngSign = 1
End If

Do
lngTms = 1
blnHasSymbol = False
blnHasRegister = False

Do
Select Case Token.TType
Case TokenRegister:
If blnHasRegister Then
SetError "Potenzierung von Registern nicht möglich", udtInstr.Line, udtInstr.Section
Exit Function
End If

If blnHasSymbol Then
SetError "Register*Label ungültig", udtInstr.Line, udtInstr.Section
Exit Function
End If

If RegStrToReg(Token.Content) < RegEAX Then
SetError "Nur 32 Bit Register in Pointer erlaubt", udtInstr.Line, udtInstr.Section
Exit Function
End If

lngReg = RegToIdx(RegStrToReg(Token.Content))
blnHasRegister = True
Match TokenRegister

Case TokenValue:
lngTms = lngTms * Token.value
Match TokenValue

Case TokenSymbol:
If blnHasRegister Then
SetError "Register*Label ungültig", udtInstr.Line, udtInstr.Section
Exit Function
End If

If GetLabelIndex(Token.Content) = -1 Then
SetError "Unbekanntes Symbol: " & Token.Content, udtInstr.Line, udtInstr.Section
Exit Function
End If

blnHasSymbol = True
blnHasSymbols = True
Match TokenSymbol

Case Else:
SetError "In Pointer ungültiges Symbol: " & Token.Content, udtInstr.Line, udtInstr.Section
Exit Function

End Select
Loop While Match(TokenOpMul)

If blnHasRegister Then
lngRegCount(lngReg) = lngRegCount(lngReg) + lngSign * lngTms
Else
lngDisplacement = lngDisplacement + lngSign * lngTms
End If

If Match(TokenOpAdd) Then
lngSign = 1
ElseIf Match(TokenOpSub) Then
lngSign = -1
Else
Exit Do
End If
Loop

For i = 0 To REG_COUNT - 1
If lngRegCount(i) > 0 Then
If lngRegCount(i) > 1 Then
' Register ist vielfaches
Ptr.RegisterMultiples = True
Else
' Bei ESP muss SIB Byte geschrieben werden,
' InstructionOutArgs() macht das auch abhängig von RegisterMultiples,
' also hier einfach vortäuschen.
If IdxToReg(i) = RegESP Then Ptr.RegisterMultiples = True
End If

Ptr.RegisterCount = Ptr.RegisterCount + 1
If Ptr.RegisterCount > 2 Then Exit For
lngUsedRegs(Ptr.RegisterCount - 1) = lngRegCount(i)

ElseIf lngRegCount(i) < 0 Then
SetError "Negatives Register-Vielfaches", udtInstr.Line, udtInstr.Section
Exit Function

End If
Next

If blnHasSymbols Then
Ptr.HasDisplacement = True
Ptr.DispSize = Bits32
Else
If lngDisplacement <> 0 Then
Ptr.HasDisplacement = True
Ptr.DispSize = GetFirstSetBit(SizesForInt(lngDisplacement))
If Ptr.DispSize > Bits8 Then
' Bits16 nicht möglich wegen ModR/M
Ptr.DispSize = Bits32
End If
Else
If lngRegCount(RegToIdx(RegEBP)) > 0 Then
If Ptr.RegisterCount = 1 Then
' EBP kann nur mit Displacement kodiert werden,
' also einfach genulltes 8 Bit Displacement hinzufügen
Ptr.HasDisplacement = True
Ptr.DispSize = Bits8
End If
Else
Ptr.HasDisplacement = False
Ptr.DispSize = BitsUnknown
End If
End If
End If

If Ptr.RegisterCount = 1 Then
If (lngUsedRegs(0) = 4) Or (lngUsedRegs(0) = 8) Then
' Reg*4/8 muss mit SIB kodiert werden,
' es gibt in diesem Fall aber kein Base Reg (ptr.RegisteCount = 1),
' deswegen ist 32 Bit Displacement nötig
Ptr.HasDisplacement = True
Ptr.DispSize = Bits32
End If
End If

If Ptr.RegisterCount > 2 Then
SetError "Mehr als 2 Register pro Pointer nicht erlaubt", udtInstr.Line, udtInstr.Section
Else
Ptr.Ptr.UsedRegisters = Ptr.RegisterCount
Ptr.Ptr.DispSize = Ptr.DispSize
ValidateExpr = True
End If
End Function


Private Function ParseSegmentReg(udtInstr As ASMInstruction) As Boolean
If udtInstr.Segment <> SegUnknown Then
SetError "Pro Instruktion nur eine Änderung des Segments", udtInstr.Line, udtInstr.Section
Else
udtInstr.Segment = SegStrToSeg(Token.Content)
Match TokenSegmentReg

If Match(TokenOpColon) Then
ParseSegmentReg = True
Else
SetError "Doppelpunkt nach Segment Register ewartet", udtInstr.Line, udtInstr.Section
End If
End If
End Function


Private Sub AddInstruction(udtInstr As ASMInstruction)
ReDim Preserve m_udtInstrs(m_lngInstrCount) As ASMInstruction
m_udtInstrs(m_lngInstrCount) = udtInstr
m_lngInstrCount = m_lngInstrCount + 1
End Sub


Private Function GetExternIndex(name As String) As Long
Dim i As Long
Dim j As Long

For i = 0 To m_lngExternCount - 1
For j = 0 To m_udtExtern(i).FunctionCount - 1
If StrComp(m_udtExtern(i).Functions(j), name, vbTextCompare) = 0 Then
GetExternIndex = i * &H10000 Or j
Exit Function
End If
Next
Next

GetExternIndex = -1
End Function


Private Function GetExternRelOfFnc(ByVal libidx As Long, ByVal fncidx As Long, ByVal reladdr As Long) As Long
Dim i As Long
Dim j As Long
Dim sz As Long

For i = 0 To libidx - 1
sz = sz + 4 * (m_udtExtern(i).FunctionCount + 1)
Next
sz = sz + 4 * fncidx

GetExternRelOfFnc = sz + m_lngBaseAddress + reladdr
End Function


Private Function GetILTLibStart(ByVal index As Long) As Long
Dim im As IMAGE_IMPORT_DIRECTORY
Dim sz As Long

sz = GetNeededIATSize() + GetIATLibStart(index)
sz = sz + Len(im) * (m_lngExternCount + 1)

GetILTLibStart = sz
End Function


Private Function GetIATLibStart(ByVal index As Long) As Long
Dim i As Long
Dim sz As Long

For i = 0 To index - 1
sz = sz + 4 * (m_udtExtern(i).FunctionCount + 1)
Next

GetIATLibStart = sz
End Function


Private Function GetNeededIATSize() As Long
Dim i As Long
Dim sz As Long

For i = 0 To m_lngExternCount - 1
sz = sz + 4 * (m_udtExtern(i).FunctionCount + 1)
Next

GetNeededIATSize = sz
End Function


Private Function GetNeededImportsSize() As Long
Dim i As Long
Dim j As Long
Dim sz As Long
Dim im As IMAGE_IMPORT_DIRECTORY

For i = 0 To m_lngExternCount - 1
sz = sz + EvenSize(Len(m_udtExtern(i).LibName) + 1)
sz = sz + Len(im)

For j = 0 To m_udtExtern(i).FunctionCount - 1
sz = sz + EvenSize(Len(m_udtExtern(i).Functions(j)) + 1) + 2
sz = sz + 4 * 2
Next

sz = sz + 4 * 2
Next

If m_lngExternCount > 0 Then
sz = sz + Len(im)
End If

GetNeededImportsSize = sz
End Function


Private Function RoundToSectionSize(ByVal lngVal As Long) As Long
RoundToSectionSize = RoundTo(lngVal, MEM_SECTION_SIZE)
End Function


Private Function RoundToMinSize(ByVal lngVal As Long) As Long
RoundToMinSize = RoundTo(lngVal, FILE_SECTION_SIZE)
End Function


Private Function RoundTo(ByVal lngVal As Long, ByVal lngMult As Long) As Long
If lngVal Mod lngMult Then
RoundTo = lngVal + (lngMult - lngVal Mod lngMult)
Else
RoundTo = lngVal
End If
End Function


Private Function EvenSize(ByVal sz As Long) As Long
EvenSize = sz + (sz Mod 2)
End Function


Private Function HexToByte(ByVal strHex As String) As Byte()
Dim bt() As Byte
Dim i As Long

ReDim bt(Len(strHex) \ 2 - 1) As Byte

For i = 1 To Len(strHex) Step 2
bt((i - 1) \ 2) = CByte("&H" & Mid$(strHex, i, 2))
Next

HexToByte = bt
End Function


Private Function GetLabelIndex(name As String) As Long
Dim i As Long

For i = 0 To m_lngLabelCount - 1
If StrComp(m_udtLabels(i).name, name, vbTextCompare) = 0 Then
GetLabelIndex = i
Exit Function
End If
Next

GetLabelIndex = -1
End Function


Private Sub SetError(ByVal strMsg As String, ByVal lngLine As Long, ByVal Section As String)
m_strLastError = strMsg
m_lngLastErrLine = lngLine
m_strLastErrorSection = Section
End Sub


' Match Funktion für Durchgehen durch Tokens nach TokenizeInput()
Private Function Match(ByVal tp As TokenType) As Boolean
If m_clsTokens(m_lngCurToken).TType = tp Then
m_lngCurToken = m_lngCurToken + 1
Match = True
End If
End Function


' Token Property für Zugriff auf aktuelles Token nach TokenizeInput()
Private Property Get Token() As ASMToken
Set Token = m_clsTokens(m_lngCurToken)
End Property


' Sammelt alle Tokens und führt Vorzeichen und Zahlen zusammen
Private Sub TokenizeInput()
Dim blnInPtr As Boolean
Dim clsMinus As ASMToken

Do
If clsMinus Is Nothing Then
AddToken ScannerToken
End If

If ScannerToken.TType = TokenEndOfInput Then
Exit Do
Else
ScannerGetNextToken
Select Case ScannerToken.TType
Case TokenBracketLeft:
blnInPtr = True
Case TokenBracketRight:
blnInPtr = False
Case TokenOpSub:
If Not blnInPtr Then Set clsMinus = ScannerToken
Case TokenValue:
If Not clsMinus Is Nothing Then
ScannerToken.value = -ScannerToken.value
Set clsMinus = Nothing
End If
Case Else:
If Not clsMinus Is Nothing Then
AddToken clsMinus
Set clsMinus = Nothing
End If
End Select
End If
Loop
End Sub


Private Sub AddLabel(strName As String, ByVal lngInstr As Long)
ReDim Preserve m_udtLabels(m_lngLabelCount) As ASMLabel

With m_udtLabels(m_lngLabelCount)
.name = strName
.Instruction = lngInstr
.Offset = 0
End With

m_lngLabelCount = m_lngLabelCount + 1
End Sub


Private Sub AddToken(ByVal clsTk As ASMToken)
ReDim Preserve m_clsTokens(m_lngTokenCount) As ASMToken
Set m_clsTokens(m_lngTokenCount) = clsTk
m_lngTokenCount = m_lngTokenCount + 1
End Sub


'#########################################################
'#########################################################
' Scanner Funktionen

Private Function ScannerMatch(udeType As TokenType) As Boolean
If m_udtScanner.CurToken.TType = udeType Then
ScannerGetNextToken
ScannerMatch = True
End If
End Function


Private Property Get ScannerToken() As ASMToken
Set ScannerToken = m_udtScanner.CurToken
End Property


Private Sub ScannerInit(Source As String)
With m_udtScanner
.Source = StrConv(Source & vbCrLf, vbFromUnicode)
.Length = UBound(.Source) + 1

.Position = 0
.Line = 1
.LinePos = 0
.NextIsEOI = False
.LastWasEOI = True
.Section = "main"

Set .NextToken = New ASMToken
With .NextToken
.TType = TokenBeginOfInput
.Line = 1
.Position = 0
End With

ScannerGetNextToken
End With
End Sub


Private Sub ScannerGetNextToken()
Dim clsToken As ASMToken

Set clsToken = New ASMToken
Set m_udtScanner.CurToken = m_udtScanner.NextToken

If m_udtScanner.NextIsEOI Then
clsToken.TType = TokenEndOfInstruction
m_udtScanner.NextIsEOI = False
m_udtScanner.LastWasEOI = True
Else
With m_udtScanner
Do While (.Position < .Length) And (clsToken.TType = TokenUnknown)
Select Case .Source(.Position)

Case CHAR_SPACE:
' nichts tun

Case CHAR_CARRIAGE:
clsToken.TType = TokenEndOfInstruction

Case CHAR_VERT_BAR:
.Line = .Line + 1
.LinePos = .LinePos + 1
clsToken.TType = TokenEndOfInstruction

Case CHAR_LINEFEED:
.Line = .Line + 1
.LinePos = .LinePos + 1

Case CHAR_SHARP:
.Section = ""
.Line = 0
.LinePos = 0
.Position = .Position + 1

Do
.Section = .Section & ChrW$(.Source(.Position))
.Position = .Position + 1
Loop While .Source(.Position) <> CHAR_CARRIAGE

.Position = .Position - 1

Case CHAR_SEMICOLON:
Do
.Position = .Position + 1
Loop While .Source(.Position + 1) <> CHAR_CARRIAGE And _
.Source(.Position + 1) <> CHAR_VERT_BAR

Case CHAR_SEPARATOR:
clsToken.TType = TokenSeparator
clsToken.Content = ","

Case CHAR_COLON:
clsToken.TType = TokenOpColon
clsToken.Content = ":"

Case CHAR_PLUS:
clsToken.TType = TokenOpAdd
clsToken.Content = "+"

Case CHAR_MINUS:
clsToken.TType = TokenOpSub
clsToken.Content = "-"

Case CHAR_ASTERISK:
clsToken.TType = TokenOpMul
clsToken.Content = "*"

Case CHAR_BRACKET_L:
clsToken.TType = TokenBracketLeft
clsToken.Content = "["

Case CHAR_BRACKET_R:
clsToken.TType = TokenBracketRight
clsToken.Content = "]"

Case CHAR_NUMBER_0 To CHAR_NUMBER_9:
Do
clsToken.Content = clsToken.Content & ChrW$(.Source(.Position))
.Position = .Position + 1
Loop While IsDigit(.Source(.Position))

clsToken.TType = TokenValue
.Position = .Position - 1

Case CHAR_AMPERSAND:
Select Case ChrW$(.Source(.Position + 1))

Case "H", "O":
clsToken.Content = "&"
.Position = .Position + 1

Do
clsToken.Content = clsToken.Content & ChrW$(.Source(.Position))
.Position = .Position + 1
Loop While IsHexChar(.Source(.Position))

clsToken.TType = TokenValue
.Position = .Position - 1

Case Else:
clsToken.TType = TokenInvalid
clsToken.Content = "&"

End Select

Case CHAR_QUOTE:
.Position = .Position + 1
Do While .Source(.Position) <> CHAR_QUOTE And _
.Source(.Position) <> CHAR_CARRIAGE And _
.Source(.Position) <> CHAR_LINEFEED

clsToken.Content = clsToken.Content & ChrW$(.Source(.Position))
.Position = .Position + 1
Loop
clsToken.TType = TokenString

Case CHAR_ALPHA_UA To CHAR_ALPHA_UZ, CHAR_ALPHA_LA To CHAR_ALPHA_LZ:
Do
clsToken.Content = clsToken.Content & ChrW$(.Source(.Position))
.Position = .Position + 1
Loop While IsAlphaNumeric(.Source(.Position))

If IsRegister(clsToken.Content) Then
clsToken.TType = TokenRegister
ElseIf IsSegmentReg(clsToken.Content) Then
clsToken.TType = TokenSegmentReg
ElseIf IsFPUReg(clsToken.Content) Then
clsToken.TType = TokenFPUReg
ElseIf IsKeyword(clsToken.Content) Then
clsToken.TType = TokenKeyword
ElseIf IsRawDataOp(clsToken.Content) Then
clsToken.TType = TokenRawData
ElseIf IsMMReg(clsToken.Content) Then
clsToken.TType = TokenMMRegister
ElseIf StrComp(clsToken.Content, "extern", vbTextCompare) = 0 Then
clsToken.TType = TokenExtern
Else
clsToken.TType = TokenSymbol
End If

.Position = .Position - 1

Case Else:
clsToken.TType = TokenInvalid
clsToken.Content = ChrW$(.Source(.Position))

End Select

If .Source(.Position) = CHAR_CARRIAGE Then
.LastWasEOI = True
Else
If clsToken.TType <> TokenKeyword And _
clsToken.TType <> TokenSymbol And _
.Source(.Position) <> CHAR_SPACE Then
.LastWasEOI = False
End If
End If

.Position = .Position + 1
Loop

If (clsToken.TType = TokenUnknown) And (.Position = .Length) Then
clsToken.TType = TokenEndOfInput
End If
End With
End If

' ** Ist grade gescanntes Token ein ":", ist vorheriges Token ein Segmentregister
' oder ein Label. In dem Fall muss der ":" von einem Zeilenumbruch
' = Instruktionsende gefolgt werden, also unsichtbaren (m_blnNextIsEOI)
' Umbruch einfügen.
' ** Ist grade gescanntes Token eine Zeichenkette und letztes Token ein
' Zeilenumbruch oder Beginn des Inputstreams, ist grade gescanntes Token
' wahrscheinlich ein Operator. Kann aber auch von einem ":" gefolgt werden
' und dadurch beim nächsten GetNextToken() Call zum Label werden.
' ** Für Zahlen (TokenValue) kann ASMToken.Content eine Dezimalzahl oder in
' VB Notation auch hexadezimale (&H...) oder oktale Werte (&O...) enthalten.
With clsToken
If .TType = TokenOpColon Then
If m_udtScanner.CurToken.TType = TokenOperator Then
m_udtScanner.CurToken.TType = TokenSymbol
m_udtScanner.NextIsEOI = True
m_udtScanner.LastWasEOI = False
End If
ElseIf .TType = TokenSymbol Then
If m_udtScanner.CurToken.TType = TokenEndOfInstruction Or _
m_udtScanner.CurToken.TType = TokenBeginOfInput Or _
m_udtScanner.LastWasEOI Then
.TType = TokenOperator
m_udtScanner.LastWasEOI = False
End If
ElseIf .TType = TokenValue Then
On Error Resume Next
.value = CLng(.Content)
If Err Then .TType = TokenInvalid
On Error GoTo 0
End If

.Line = m_udtScanner.Line
.Section = m_udtScanner.Section
.Position = (m_udtScanner.Position - Len(.Content)) - m_udtScanner.LinePos + 1
End With

Set m_udtScanner.NextToken = clsToken
End Sub


Private Function IsDigit(ByVal bt As Byte) As Boolean
IsDigit = (bt >= CHAR_NUMBER_0) And (bt <= CHAR_NUMBER_9)
End Function


Private Function IsHexChar(ByVal bt As Byte) As Boolean
IsHexChar = ((bt >= CHAR_NUMBER_0) And (bt <= CHAR_NUMBER_9)) Or _
((bt >= CHAR_ALPHA_UA) And (bt <= CHAR_ALPHA_UA + 5)) Or _
((bt >= CHAR_ALPHA_LA) And (bt <= CHAR_ALPHA_LA + 5))
End Function


Private Function IsAlphaNumeric(ByVal bt As Byte) As Boolean
IsAlphaNumeric = ((bt >= CHAR_NUMBER_0) And (bt <= CHAR_NUMBER_9)) Or _
((bt >= CHAR_ALPHA_UA) And (bt <= CHAR_ALPHA_UZ)) Or _
((bt >= CHAR_ALPHA_LA) And (bt <= CHAR_ALPHA_LZ)) Or _
(bt = CHAR_UNDERSCORE)
End Function

CLASS 2