- Offizieller Beitrag
Meine Assembler-Erfahrungen gehen weiter. Jetzt habe ich mir mal den Umgang mit Strings vorgenommen.
Wie übergibt man Strings von AutoIt an Assembler?
Und wie kann man in Assembler zwei Strings miteinander vergleichen?
So nebenbei ist dann noch eine Assemblerfunktion zum ermitteln der Stringlänge entstanden.
AutoIt
#AutoIt3Wrapper_UseX64=n ; 32Bit-Modus
#include "AssembleIt2\assembleit2_64.au3" ; <- Achtung! Pfad evtl. anpassen!
#Region ASM-Code
#cs StringCompare
Use32 ; 32Bit Modus!
mov esi,[esp+4] ; esi = String1 (Pointer)
mov edi,[esp+8] ; edi = String2 (Pointer)
mov eax,esi ; eax = esi (fuer StringLen)
call StringLen ; die Laenge von String1 ermitteln (Return = ecx = Anzahl der Zeichen)
mov ebx,ecx ; und in ebx merken
mov eax,edi ; eax = edi (fuer StringLen)
call StringLen ; die Laenge von String2 ermitteln (Return = ecx = Anzahl der Zeichen)
cmp ecx,ebx ; die beiden Laengen vergleichen
jae @f ; wenn String2 laenger oder gleich lang, dann ueberspringen
mov ecx,ebx ; ansonsten Stringlaenge von String1 nach ecx
@@:
;~ _ASMDBG_(); debug-gui anzeigen
cld ; Direction-Flag loeschen
repe cmpsb ; die Strings vergleichen (repe = wiederhole so viele Zeichen, wie in ecx vorgegeben)
jb @below ; wenn kleiner, dann springe zu @below
ja @above ; wenn groesser, dann springe zu @above
; ansonsten
mov eax,1 ; wenn String1 = String2, dann eax = 1
ret ; zurueck zu AutoIt
@above:
mov eax,2 ; wenn String1 > String2, dann eax = 2
ret ; zurueck zu AutoIt
@below:
mov eax,0 ; wenn String1 < String2, dann eax = 0
ret ; zurueck zu AutoIt
StringLen:
xor ecx,ecx ; ecx = Counter (auf 0 setzen)
@CountLen: ; Schleife
cmp byte[eax+ecx],0 ; wenn das Nullbyte erreicht wurde
je @CountEnd ; dann Schleife beenden
inc ecx ; ansonsten ecx++
jnz @CountLen ; wenn ungleich 0, dann @CountLen
ret ; wenn kein 0-Byte vorhanden, dann return (ecx = 0)
@CountEnd:
inc ecx ; ecx++ (Nullbyte mitzaehlen)
ret ; return = ecx = Anzahl der Zeichen
#ce
#EndRegion ASM-Code
Global Const $aCompare[] = ['<', '=', '>']
Global $aString[2] = ['Das ist ein Text.1', 'Das ist ein Text.2']
$tStruct1 = _String2Struct($aString[0])
$pStruct1 = DllStructGetPtr($tStruct1)
$tStruct2 = _String2Struct($aString[1])
$pStruct2 = DllStructGetPtr($tStruct2)
;~ $sString1 = DllStructGetData($tStruct1, 1)
;~ ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $sString1 = ' & $sString1 & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
;~ $sString2 = DllStructGetData($tStruct2, 1)
;~ ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $sString2 = ' & $sString2 & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
$ret = _AssembleIt2("dword", "StringCompare", "ptr", $pStruct1, "ptr", $pStruct2)
ConsoleWrite(StringFormat('StringCompare: String1 %s String2\n', $aCompare[$ret]))
$ret = _AssembleIt2("dword", "StringCompare", "ptr", $pStruct2, "ptr", $pStruct1)
ConsoleWrite(StringFormat('StringCompare: String2 %s String1\n', $aCompare[$ret]))
Func _String2Struct($sString)
$sString &= Chr(0)
Local $tStruct = DllStructCreate('char[' & StringLen($sString) & ']')
DllStructSetData($tStruct, 1, $sString)
Return $tStruct
EndFunc
Alles anzeigen