Die Community zu .NET und Classic VB.
Menü

Visual Basic und Assembler - Seite 5

 von 

Schlußwort
Nächste Seite >>
Kleine Helferlein
<< Vorherige Seite

Beispiel  

Nachfolgend ein Beispiel, das die Verwendung der oben aufgeführten Makros und der Einbindung des Codes in VB verdeutlichen soll.

HEX-Umwandlung

Zwar ist VB in der Lage, Hex-Code zu erzeugen, jedoch nur bis zu 8 Zeichen, da die Funktion auf Longs begrenzt ist. Wer ganze Zeichenketten oder ein Long-Array in HexCode umwandeln möchte, kann dies nur in einem Loop tun. Ein sehr alter recht geschickter ASM-Algorithmus ermöglicht dies in sehr kurzer Zeit unter Verwendung des Befehls DAA (DezimalAnpassung nach Addition zweier binary coded decimals =BCD).

.386            ; Keine "neuen" Pentium-Befehle
.MODEL FLAT        ; 32-Bit-Modus

.CODE            ; Codesection
_run:            ; Programmcode-Beginn

include         stdparas.inc        ; Einfügen der Makros...

; ***********************
src    EQU    <PA1>    ; PA1 = source (Herkunft)
tgt    EQU    <PA2>    ; PA2 = target (Ziel)
cnt    EQU    <PA3>    ; PA3 = count (Anzahl)
; ************************

CHR2HEX    PROC    NEAR    ; Prozedurbeginn

init:    mac    SAVE    ; Einfügen INT3, Sichern der Register
    mov    esi,src    ; SourceIndex <= source
    mov    edi,tgt    ; TargetIndex <= target
    mov    ecx,cnt    ; Counter <= count
chr_loop:    mov    al,[esi]    ; AL = nächstes Byte
    shr    al,4    ; AL = AL / 16 = „high nibble“ )
    add    al,90h    ; AL = AL + 90h
    daa        ; high nibble = Zehner, low nibble=Einer
    adc    al,40h    ; AL = AL + 40h + Carry
    daa        ; high nibble = Zehner, low nibble=Einer
    mov    [edi],al    ; [TargetIndex] <= Ergebnis
    inc    edi    ; TargetIndex += 1
    mov    al,[esi]    ; dasselbe für das „low nibble“
    and    al,0Fh    ; AL = low nibble
    add    al,90h
    daa
    adc    al,40h
    daa
    inc    esi    ; SourceIndex += 1
    mov    [edi],al
    inc    edi
    dec    ecx    ; Counter -= 1
    jnz    chr_loop    ; wenn nicht 0 => nächstes Byte

    stc        ; Carry setzen (True zurückgeben)
    mac    REST    ; Register wiederherstellen

CHR2HEX    ENDP        ; Prozedurende

END    _run        ; Programmende

Die Kombination aus ADD-, ADC- und DAA-Befehlen ist wirklich trickreich und stellt bestimmt eine gute Übung dar, Assemblercode und Flags nachzuvollziehen! Um die Funktion nutzen zu können, bedarf es in VB des folgenden Rahmens:

Option Explicit

Private Declare Function ASM_cdLong Lib "user32" _
    Alias "CallWindowProcA" _
    (ByRef adr As Long, _
     ByVal PA1 As Long, _
     ByVal PA2 As Long, _
     ByVal PA3 As Long, _
     ByVal PA4 As Long) As Long

Function CNV2HEX(ptr As Long, LN As Long) As String
    Static asm(14) As Long

    If asm(0) = 0 Then
        asm(0) = &HEC8B5590:  asm(1) = &H8B575653
        asm(2) = &H7D8B0875:  asm(3) = &H104D8B0C
        asm(4) = &HE8C0068A:  asm(5) = &H27900404
        asm(6) = &H88274014:  asm(7) = &H68A4707
        asm(8) = &H90040F24:  asm(9) = &H27401427
        asm(10) = &H46470788: asm(11) = &HF9E17549
        asm(12) = &H5E5FC01B: asm(13) = &H10C25D5B
        asm(14) = &H0
    End If

    ' ********************************************

    Dim bar() As Byte
    ReDim bar(LN * 2 - 1)
    
    ASM_cdLong asm(0), ptr, VarPtr(bar(0)), LN, 0
    CNV2HEX = StrConv(bar, vbUnicode)
End Function

Im Deklarationsteil wird der Aufruf von CallWindowProc definiert. In diesem Fall als ASM_cdLong, da die Parameter etwas vom Standard abweichen. Dann wird die Funktion CNV2HEX erstellt, die zwei Parameter erwartet: Einen Pointer auf den umzuwandelnden Text, also z.B. StrPtr(MyText), sowie dessen Länge in Bytes.

Sicher wäre es möglich, die Funktion als CHR2HEX o.ä. zu deklarieren. Der Vorteil dieser bloß "formalen" Deklaration liegt in der Flexibilität: Die Funktion konvertiert ebenso Text

Debug.Print CNV2HEX(StrPtr(StrConv(<text>, vbFromUnicode)), Len(<text>))

wie sie ein ganzes Long-Array konvertieren kann:

Debug.Print CNV2HEX(VarPtr(arr(0)), UBound(arr) * 4 + 4)

Für beides ließen sich natürlich weitere VB-Funktionen erstellen, um den Aufruf übersichtlicher zu gestalten. Weitere Beispiele können auf der ActiveVB-Seite in der Rubrik Assembler und VB eingesehen werden.

Nächste Seite >>
Schlußwort
<< Vorherige Seite
Kleine Helferlein