VbInlineAsm




Beschreibung

VB-Inline-ASM ist ein Plugin für Visual Basic 6 welches es ermöglicht ASM-Code direkt in Visual Basic einzugeben. Dies funktioniert so, dass der ASM-Code als Kommentar deaktiviert in den VB-Code eingegeben wird. Beim Kompilieren fängt ein Hook den ASM vom VB-Compiler ab, sucht nach den auskommentierten ASM-Codes, reaktiviert diese und deaktiviert gleichzeitig VB-Code der ersatzweise eingefügt werden kann. Der modifizierte ASM-Code wird dann vom MASM-Compiler (welcher auf dem System ebenfalls installiert sein muß) in den endgültigen Binärcode kompiliert.
Über diesen Trick ist es möglich ASM doch in VB einzubinden, obwohl VB selbst diese Möglichkeit nicht bietet. Der Nachteil ist dabei offensichtlich, dass Debugging für ASM-Codes im VB-Editor nicht möglich ist, Fehler führen meistens zu einem harten Absturz des Programms. Der Programmierer muß also genau wissen was er macht und der eingefügte ASM-Code muß fehlerfrei sein. Der ASM-Code sollte also am besten zuerst in einem ASM-Compiler entwickelt werden und erst dann wenn dieser fehlerfrei funktioniert, in bestehende VB-Codes integriert werden.
Damit Debugging der VB-Codes möglich ist, müssen die Codes doppelt geschrieben werden, einmal in VB und einmal in ASM. Dies bietet auch die Möglichkeit Geschwindigkeitsvergleiche und Code-Tests durchzuführen.
VB löscht normalerweise die ASM-Codes beim Kompilieren, mit VB-Inline-ASM ist es möglich, den von VB kompilerten ASM-Code zu analysieren und möglicherweise auch zu optimieren. Oder man kann ihn verwenden um zu lernen wie VB zu ASM wird.

Hinweis
VB-Inline-ASM funktioniert natürlich nur mit kompiliertem ASM-Code (System-Code, Native-Code), nicht mit P-Code. (P-Code, Primitiv-Code ist kein echter Maschinen-Code sondern nur eine in Binärform umgewandelter VB-Code der von einem Interpreter ausgeführt wird. Dies muß in den Compileroptionen eingestellt sein.)

VB-Inline-ASM basiert auf einem Code der auf Planet-Source-Code veröffentliche wurde, aber mittlerweile da nicht mehr zu finden ist. VBFibre da ist der Original-Code noch verfügbar.
:!: Das hier veröffentlichte AddIn wurde verbessert und ist nicht mehr identisch mit dem Original.

Das Programm ist Freeware und liegt im Download.

Installation

Ab der Version 0.15 hat VbInlineAsm nun ein Installer.

WICHTIG:
Das Add-In wird nun in das "Programme" Verzeichnis installiert. Falls eine ältere Versionen noch im "..\VB98\Wizards\" liegt, müssen alle Dateien von VbInlineAsm Manuell entfernt werden. Dazu müssen alle Visual-Basic Instanzen beendet werden, und wenn eigene Templates erstellt wurden, müssen diese nach der Installation ins neue "VbInlineAsm-Templates" Verzeichnis verschoben werden.
oder
VbInlineAsm_Deinstaller_Version_0.01_bis_0.14.exe Löscht alle VbInlineAsm-Dateien aus dem Verseichnis
"..\VB98\Wizards\"
"..\VB98\Wizards\VbInlineAsm-Templates\"
"..\VB98\Wizards\VbInlineAsm\"
"..\VB98\Wizards\VbInlineAsm\VbInlineAsm-Templates\"


  1. MASM oder MASM CodingCrew downloaden und Installieren. (zB. in C:\MASM32\)
  2. Alle Visual-Basic Instanzen beenden
  3. (Alte VbInlineAsm Version aus "..\VB98\Wizards\" entfernen, wenn vorhanden)
  4. VbInLineAsm_Installer.exe ausführen
  5. Add-In in Visual-Basic aktiviert, unter Menü -> Add-Ins -> AddIn-Manager -> VbInlineAsm , Laden
  • Danach taucht ein neues Icon auf der Symbolleiste und ein Eintrag im Menü Add-Ins auf, über diese können die Einstellungen von VbInlineAsm geändert werden. In den Optionen kann das Umleiten und Bearbeiten des ASM-Codes aktiviert oder deaktiviert werden.
  • Konfiguration anpassen, Pfad für MASM eintragen (zB. C:\MASM32\BIN\ML.exe)
  • Mit dem Projekt VbInlineAsm Test kann VbInlineAsm getestet werden.
  • Im Template-Verzeichnis können Codes als TXT gespeichert werden die im VB-Editor über Kontektmenü oder Optionen in den Code eingefügt werden können. (..\VbInlineAsm\Templates\*.txt)
  • Bei einer Kompilierung mit VbInlineAsm werden alle Dateien im Verzeichnis des Projekts in "\..Projekt..\_VbInlineAsm\" gespeichert.



Zum Updaten einer bestehenden Installation ist es nicht notwendig die Alte erst zu deinstallieren, es können die neuen Dateien über die alten installiert werden.


Es können weitere Sprachen installiert werden indem eine Sprachdatei ???.lng erstellt wird die im Verzeichnis "Language" bei VbInLineAsm.dll liegen muß. (??? ist der Platzhalter für den Namen der Sprache in Englisch.) Am besten eine Bestehende Datei kopieren, den Dateinamen anpassen und die Texte ändern. Im Moment werden Deutsch und Englisch unterstützt. Falls Benutzer weitere Sprachen erstellen, werden diese in kommenden Versionen enthalten sein.


Im Bug-Report können Fehler gemeldet werden.

Optionen

OptionBeschreibung
Optionen
InLineAsm AktivAktiviert/Deaktiviert die InlineASM Kompilierung
CFG speichernSpeichert Options-Einstellungen individuell für dieses Projekt
Compiler-HilfeZeigt die Hilfe der Compiler-Programme an
SchliessenVerbirgt das Options-Fenster
Build Optionen
DOS-Konsole AppDOS-Konsolen App Linker-Schalter setzen
Std DllErzeugt DEF-Datei und modifiziert Kommandozeile für Std C++ DLL
Listings für alle ModuleGeneriert VB C2 LST-Listings für alle Dateien
OBJ-Dateien speichernSpeichern OBJ-Dateien ins Listing-Verzeichnis
Compiler PfadPfad für Assembler-Compiler setzten (ML.exe für MASM)
Editor PfadPfad für ein ASM-Editor setzten (NotePad.exe)
Compile Kontrolle
Pause vor dem KompilierenPause vor dem Ausführen des Compilers (zu ASM)
Pause vor dem LinkenPause vor dem Ausführen des Linkers
Cmd-Zeile ändernErmöglicht das Anpassen der KomandoZeile für dem Kompilieren
Linken überspringenOBJ-Dateien werden nicht gelinkt (zu EXE oder DLL)
Debug Optionen
Debug MsgBox anzeigenAlle Debug-Nachrichten zeigen eine MsgBox
DebugLog speichernDebug Nachrichten in DebugLog speichern
Log erzwingenDebugLog Ausgabe für alle Kompilierungen erzwingen
DebugLog löschen vor dem KompilierenLöscht DebugLog vor jeder Kompilierung
Assembler Nachrichten in Log speichernSpeichert Assembler Nachrichten in das DebugLog
Detaillierte MASM und LINK Map-Datei speichernAssembler und Linker Schalter für MAP-Dateien Ausgabe setzen
Allgemeine Optionen
Sprache
Laden beim StartLaden des Add-In beim IDE-Editor Start
Fenster über andereAdd-In Fenster über alle anderen setzen
Code-Beispiele Kontext MenüErmöglicht über Kontext-Menu Beispiel-Codes einzufügen
ComboBox verwendenBenutzt ComboBox für das Kontext-Menu für Templates
Aufräum Optionen
DbgLogAlle Log-Dateien löschen
*.LSTAlle LST-Dateien löschen
*.ASMAlle ASM-Dateien löschen
Log löschenLöscht die LOG-Dateien
Code-Beispiele Templates
EinfügenFügt das ausgewählte Code-Beispiel im Editor ein

Code Aufbau

MarkerBeschreibung
'#ASM_VBVB-Code Variante während der Entwicklungs-Zeit verwendbar, wird bei Kompilierung aus dem Code entfernt und durch ASM ersetzt
'#ASM_STARTALLLöscht den kompletten Code in der Prozedur außerhalb des #ASM_ Blocks (ein ASM_STARTALL in der Prozedur überschreibet alle ASM_START)
'#ASM_STARTBearbeitet den ASM_ Block, aber beläßt Codes außerhalb des ASM_ Blocks
'#ASM_ENDEnde der Ersetzung


Es ist empfohlen ASM_STARTALL zu verwenden um die volle Kontrolle über den Code zu haben. Wird ASM_START verwendet muß unbedingt der Code in der LST-Datei geprüft werden um die Funktion korrekt übersetzt wurde. Der Compiler führt Optimierungen durch die möglicherweise nicht beabsichtigt oder unvorhergesehen sind.

Alle ASM-Codes müssen mit ' auskommentiert werden, da natürlich der VB-Editor mit ASM nichts anfangen kann und Fehler melden würde. Die ASM-Codes werden erst beim kompilieren aktiviert. Deshalb muß ein Programm mit solchen ASM Inline-Codes als native EXE und nicht als P-Code kompiliert werden. Dies kann eingestellt werden über Menü -> Projekt -> Eigenschaften von... -> Kompilieren -> Kompilieren zu System-Code (Native Code).

Tip:
Um herauszufinden wie der eigene ASM Code am besten in die Routinen integriert werden kann, sollten die Codes erst mal in VB kompiliert werden um zu erkennen wie VB den Code in ASM kompiliert. Danach kann dies als Grundlage verwendet werden um die eigenen ASM-Codes einzufügen.
Es können Codes auch kompiliert werden um sie nachträglich zu Verbessern, ohne das der gesamte ASM-Code neu geschrieben werden muß.
Und natürlich können die ASM-Codes die VB erzeugt auch genutzt werden um zu lernen wie aus VB-Codes ASM-Codes werden, oder welche Änderungen bestimmte Compiler Optionen zur Optimierung den ASM-Code verändern.

'#ASM_VB
 
    '<-- VB-Code
 
'#ASM_STARTALL
'
'    ;<-- ASM-Code
'
'#ASM_END

oder

'#ASM_VB
 
    '<-- VB-Code
 
'#ASM_START
'
'    ;<-- ASM-Code
'
'#ASM_END

Beispiel

Public Function ShiftLeftAsm(ByVal Par1 As Long, ByVal Par2 As Long) As Long
'#ASM_VB
 
 
    '<-- VB-Code
    ShiftLeftAsm = (Par1 * 2 ^ Par2)
 
 
'#ASM_STARTALL
'  Par1 EQU[EBP+4]      ; Parameter deklarieren
'  Par2 EQU[EBP+8]
'
'  PUSH EBP             ; Sichert EBP auf Stack
'  MOV EBP, ESP         ; EBP = ESP, um auf den Stack zugreifen und Parameter lesen zu können
'
'  PUSH ECX             ; In Code manipulierte Register auf Stack sichern
'  PUSH EBX             ; In Klassen/Betriebssystem manipulierte Register auf Stack sichern
'  PUSH ESI
'  PUSH EDI
'
'    ;<-- ASM-Code
'    MOV EAX, Par1      ; EAX = Par1
'    MOV ECX, Par2      ; ECX = Par2
'
'    SHL EAX, CL        ; EAX = EAX << CL
'
'  POP EDI              ; Gesicherte Register aus dem Stack lesen
'  POP ESI
'  POP EBX
'  POP ECX
'
'  MOV ESP, EBP         ; ESP = EBP, Gesicherter EBP aus dem Stack lesen
'  POP EBP              ;  (MOV,POP ist viel schneller als LEAVE (ENTER) auf 486 und Pentium)
'
'  RET 8                ; Return mit Resultat auf EAX, der RET Wert muß der Summe der Byte aller Parameter entsprechen ( 8 = 2 * Long(4Byte) )
'#ASM_END
End Function




Erklärung
Par1 EQU[EBP+4]
Par2 EQU[EBP+8]

Deklariert ein Parameterame damit man über diesen einfacher auf den Stack zugreifen kann. Par1 ist dann identisch mit [EBP+4] usw.
Es beginnt mit +4 weil in den ersten 4 Bytes die Rücksprungadresse steht.
Die Stack Elemente haben eine feste Länge, in einem 32-Bit Programm sind dies 4 Byte. Es ist also egal ob über den Stack Byte Integer Long oder Single übergeben werden, es werden immer 4 Byte Pro Parameter verwendet. Ist der Wert größer als 4 Byte zB. bei Double, wird er aus mehreren Elementen zusammengesetzt. Die ungenutzten Bytes bleiben leer.



PUSH EBP
MOV EBP, ESP

EBP wird als Indexregister verwendet da ESP nicht als Indexregister verwendet werden kann. Dazu wird der aktuelle Wert in EBP auf den Stack gesichert und dann EBP = ESP gesetzt.



PUSH ECX
PUSH EBX
PUSH ESI
PUSH EDI

Wenn notwendig können zusätzlich weitere Werte auf den Stack in Registern gesichert werden. EDI ESI EBX sind Register die von Klassen und Windows API Befehlen manipuliert werden. Falls diese wichtige Werte enthalten müssen sie gesichert werden bevor in eine Klasse oder ein API gecallt wird. (Hier eigentlich unnötig)



  MOV EAX, Par1
  MOV ECX, Par2
  SHL EAX, CL

Danach ist die Prozedur bereit für den Code.
EAX ist das Standardregister für Rückgabewerte, das Resultat muß also am Ende in EAX Register stehen.



POP EDI
POP ESI
POP EBX
POP ECX

Nach dem Code müssen alle gesicherten Register in umgekehrter Reihenfolge wie sie auf den Stack geschrieben wurden, wieder von diesem zurück kopiert werden.



MOV ESP, EBP
POP EBP

Danach wird noch ESP EBP rekonstruiert.



RET 8

Return um aus der Prozedur zurück zu springen, der Wert bei RET muß der Summe der Byte aller Parameter entsprechen in 4-Byte Schritten ( 8 = 2 * 4 Byte (2 Long Parameter) )

Assembler über CallWindowProc in VisualBasic

Der Vollständigkeit halber sei noch erwähnt, es gibt auch noch eine andere Möglichkeit Assembler Code in VisualBasic Programme einzubauen, in dem ein ASM-Code zuerst in ein Binärcode compiliert wird, dieser dann als ein Array in das VB-Programm eingebunden wird und im Programmlauf über CallWindowProcA in diesen Code gesprungen wird. CallWindowProcA führt dann den Inhalt des Array aus als wäre es ein normaler Programmocde, da er dieses ja eigentlich auch ist und CallWindowProcA nicht interessierst das an dieser Speicherstelle eigentlich der Inhalt eines Arrays und nicht eines normalen compilierten Codes liegt. Dieser Weg ist aber umständlicher als den Code direkt als Kommentartext in das VB-Programm einzufügen und das Compilieren VbInlineAsm und Masm zu überlassen. Über VbInlineAsm eingefügter Code läßt sich im Editor bearbeiten.
Ein solcher CallWindowProc-Code würde ungefähr so aussehen (Das ist nur ein Pseudocode ohne Funktion):

Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" _
                         (ByRef Adr As Long, ByVal  Par1 As Long, ByVal  Par2 As Long, ByVal  Par3 As Long, ByVal  Par4 As Long) As Long
 
Function TestAsm(ByRef Ptr As Long, ByRef DataLen As Long) As String
  Static ASM(20) As Long
 
    If ASM(0) = 0 Then
        <- Hier der HexCode des ASM-Programms im ASM() Array
        ASM(0) = &H01020304:  ASM(1) = &H....
        ...
        ASM(20) = &H0
    End If
 
 
    ReDim Data(DataLen - 1)
 
    Call CallWindowProc (ASM(0), Ptr, VarPtr(Data(0)), DataLen, 0)
 
End Function
 
...
   Call TestAsm(VarPtr(Scr(0)), UBound(Scr) - LBound(Scr) + 1)

Projekt/VbInlineAsm.txt · Zuletzt geändert: 2010/06/17 07:24 von Runtime-Basic