Registriert seit: 8. Mär 2017
Ort: Köln
157 Beiträge
Delphi 12 Athens
|
AW: Assembler-Rätsel
7. Apr 2020, 13:52
Hallo,
mittlerweile habe ich das gelöst, indem ich den hier gefundenen Original PosEx-Code von Aleksandr Sharahov ein wenig modifiziert habe. Die Änderungen umfassen zusätzlichen Code zur Prüfung des neuen Parameters 'Limit' und die Änderung des 'Notausganges' ab dem Label @NIL. Dort ersetze ich das 'ret' durch einen Sprung zum Funktions-Ende, um den vom Compiler generierten Austritts-Code zu benutzen, der den zusätzlichen Parameter berücksichtigt.
Delphi-Quellcode:
function PosInLimits( const SubStr, Str: RawByteString; Offset: Integer = 1; limit: Integer = 0): Integer;
asm
test eax, eax
jz @ Nil
test edx, edx
jz @ Nil
dec ecx
jl @ Nil
push esi
push ebx
mov esi, [edx-4] //Length(Str)
//*************************************************************** Zusätzlicher Code
mov ebx, limit // limit holen
test ebx, ebx // Limit = 0?
jz @IgnoreLimit // limit ignorieren
cmp ebx, esi // limit >= Length(Str)?
jge @IgnoreLimit // limit ignorieren
mov esi, ebx // limit übernehmen anstelle von Length(Str)
@IgnoreLimit:
// ************************************************************** Ende zusätzlicher Code
mov ebx, [eax-4] //Length(Substr)
sub esi, ecx //effective length of Str (= length(str) - offset)
add edx, ecx //addr of the first AnsiChar at starting position
cmp esi, ebx
jl @Past //jump if EffectiveLength(Str)<Length(Substr)
test ebx, ebx
jle @Past //jump if Length(Substr)<=0
add esp, -12
add ebx, -1 //Length(Substr)-1
add esi, edx //addr of the terminator
add edx, ebx //addr of the last AnsiChar at starting position
mov [esp+8], esi //save addr of the terminator
add eax, ebx //addr of the last AnsiChar of Substr
sub ecx, edx //-@Str[Length(Substr)]
neg ebx //-(Length(Substr)-1)
mov [esp+4], ecx //save -@Str[Length(Substr)]
mov [esp], ebx //save -(Length(Substr)-1)
movzx ecx, byte ptr [eax] //the last AnsiChar of Substr
@Loop:
cmp cl, [edx]
jz @Test0
@AfterTest0:
cmp cl, [edx+1]
jz @TestT
@AfterTestT:
add edx, 4
cmp edx, [esp+8]
jb @Continue
@EndLoop:
add edx, -2
cmp edx, [esp+8]
jb @Loop
@Exit:
add esp, 12
@Past:
pop ebx
pop esi
@ Nil:
xor eax, eax
jmp @done // *************************** Modifiziert
@Continue:
cmp cl, [edx-2]
jz @Test2
cmp cl, [edx-1]
jnz @Loop
@Test1:
add edx, 1
@Test2:
add edx, -2
@Test0:
add edx, -1
@TestT:
mov esi, [esp]
test esi, esi
jz @Found
@AnsiString:
movzx ebx, word ptr [esi+eax]
cmp bx, word ptr [esi+edx+1]
jnz @AfterTestT
cmp esi, -2
jge @Found
movzx ebx, word ptr [esi+eax+2]
cmp bx, word ptr [esi+edx+3]
jnz @AfterTestT
add esi, 4
jl @AnsiString
@Found:
mov eax, [esp+4]
add edx, 2
cmp edx, [esp+8]
ja @Exit
add esp, 12
add eax, edx
pop ebx
pop esi
@done:
end;
Das Ganze funktioniert anscheinend wie gewünscht. Leider bin ich nicht der große Assembler-Meister, so dass mich die Sorge umtreibt, dass ich doch irgendetwas übersehen habe, was mir irgendwann auf die Füße fällt. Vielleicht könnte irgendein hier mitlesender Assembler-Experte mal einen Blick darauf werfen.
Außerdem eine grundsätzliche Frage: Unter welchen Bedingungen darf ich den Sharahov - Code überhaupt in meinem Programm verwenden? Da ich nicht vorhabe, das Programm oder gar die Quellcodes weiterzugeben, könnte mir das eigentlich völlig wurscht sein. Aber es interessiert mich eben, und die Informationen, die über die verschiedenen Lizenzmodelle im Netz zu finden sind, lassen mich eher ratlos zurück. Kann mir das mal jemand kurz & knackig erläutern?
Gruß LP
|