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);
}
?>
IntCode
Donnerstag, 15. Dezember 2011
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
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
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
' 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
Abonnieren
Posts (Atom)