Also mittlerweile neige ich dazu fast alles, was grade so machbar und mit angemessenem Aufwand bewältigbar is, in ASM zu machen. So hab ich mal ne kleine passwortlose Ver- und Entschlüsselungsroutine gebastelt und einmal in Rein-PB bzw. einmal in Rein-ASM geschrieben. Nun hat die ASM-Routine für das Verschlüsseln von 200MB Speicher ca. 1 Sekunde benötigt auf meinem 1,8 GHz Sempron-Mobile, während der Rein-PB-Code über ne halbe Minute benötigte.
Code: Alles auswählen
;InternalXOr-Encoding
;Prozessortypen: x386 und höher (verwendet nicht: MMX, SSE, SSE2, SSE3)
Global progress.l
Procedure InternalEnXOr(*MemoryID,Length.l)
;Die gegenüber dem anderen Assemblercode eingerückten Zeilen beziehen sich nur auf
;die Aktualisierung der globalen fortschrittsanzeigenden Variablen, die dann von einem
;den Vorgang überwachenden Thread genutzt werden können, um mit Hilfe der Gesamtlänge
;und der Fortschrittsvariablen eine Fortschrittsanzeige zu ermöglichen.
;Diese Zeilen sind für eine nicht überwachte Verschlüsselung nicht notwendig und können dann
;auskommentiert werden.
!MOV dword eax,[p.v_Length] ;Length in EAX laden
!CMP eax,2 ;EAX mit 2 vergleichen
!JL TooShort_En ;Falls EAX (=Length) kürzer als 2, zu TooShort_En springen
!MOV dword ecx,[p.p_MemoryID] ;Speicheranfangsadresse in ECX speichern
!MOV dword ebx,0 ;Als Positionszeiger EBX verwenden und auf 0 setzen
!INC dword ebx ;Leseposition um 1 erhöhen
!NextEnXOrStep: ;Schleifen-Sprungmarke
!MOV al,[ecx+ebx] ;Wert an der Speicherstelle [ECX+EBX] in AL laden
!MOV ah,[ecx+ebx-1] ;Wert an der Speicherstelle [ECX+EBX-1] in AH laden
!XOR al,ah ;AL mit AH durch XOr verknüpfen und Ergrbnis in AL speichern
!MOV [ecx+ebx],al ;neuen Wert von AL an die Stelle [ECX+EBX] zurückschreiben
!INC dword ebx ;Leseposition EBX um 1 erhöhen
!MOV dword [v_progress],ebx ;Leseposition EBX in der globalen Variable für die Fortschrittsanzeige speichern
!CMP dword ebx,[p.v_Length] ;Leseposition EBX und Speicherlänge vergleichen
!JNE NextEnXOrStep ;Falls nicht gleich (also noch nicht am Ende angekommen), zu NextEnXOrStep zurückspringen
!MOV eax,[p.v_Length] ;ProcedureReturn den Wert von Length übergeben
ProcedureReturn
!TooShort_En: ;Länge war leider zu kurz:
!MOV eax,0 ;ProcedureReturn den Wert 0 (=fehlgeschlagen) übergeben
ProcedureReturn
EndProcedure
Procedure InternalDeXOr(*MemoryID,Length.l)
;Die gegenüber dem anderen Assemblercode eingerückten Zeilen beziehen sich nur auf
;die Aktualisierung der globalen fortschrittsanzeigenden Variablen, die dann von einem
;den Vorgang überwachenden Thread genutzt werden können, um mit Hilfe der Gesamtlänge
;und der Fortschrittsvariablen eine Fortschrittsanzeige zu ermöglichen.
;Diese Zeilen sind für eine nicht überwachte Verschlüsselung nicht notwendig und können dann
;auskommentiert werden.
!MOV dword eax,[p.v_Length] ;Length in EAX laden
!CMP eax,2 ;EAX mit 2 vergleichen
!JL TooShort_De ;Falls EAX (=Length) kürzer als 2, zu TooShort_De springen
!MOV dword ecx,[p.p_MemoryID] ;Speicheranfangsadresse in ECX speichern
!MOV dword ebx,[p.v_Length] ;Als Positionszeiger EBX verwenden und auf Length setzen
!DEC dword ebx ;Leseposition EBX um 1 verringern (letztes Zeichen steht nicht an der Stelle Length, sondern bei Length-1)
!NextDeXOrStep: ;Schleifen-Sprungmarke
!MOV al,[ecx+ebx] ;Wert an der Speicherstelle [ECX+EBX] in AL laden
!MOV ah,[ecx+ebx-1] ;Wert an der Speicherstelle [ECX+EBX-1] in AH laden
!XOR al,ah ;AL mit AH durch XOr verknüpfen und Ergrbnis in AL speichern
!MOV [ecx+ebx],al ;neuen Wert von AL an die Stelle [ECX+EBX] zurückschreiben
!DEC dword ebx ;Leseposition EBX um 1 verringern
!MOV dword eax,[p.v_Length] ;Länge in EAX speichern...
!SUB dword eax,ebx ;...und Leseposition EBX von EAX subtrahieren, um Anzahl der bereits berechneten Zeichen zu erhalten
!MOV [v_progress],eax ;diese dann in der fortschrittsanzeigenden Variablen speichern
!CMP dword ebx,0 ;Leseposition EBX mit 0 vergleichen
!JA NextDeXOrStep ;Falls größer 0(also noch nicht am Ende angekommen) zu NextDeXOrStep zurückspringen
!MOV eax,[p.v_Length] ;ProcedureReturn den Wert von Length übergeben
ProcedureReturn
!TooShort_De: ;Länge war leider zu kurz:
!MOV eax,0 ;ProcedureReturn den Wert 0 (=fehlgeschlagen) übergeben
EndProcedure
Size=200*1024*1024
*mem=AllocateMemory(Size)
Debug "Allocated"
Start=ElapsedMilliseconds()
InternalEnXOr(*mem,Size)
Time=ElapsedMilliseconds()-Start
Debug Time
Debug "EnXOred"
Start=ElapsedMilliseconds()
InternalDeXOr(*mem,Size)
Time=ElapsedMilliseconds()-Start
Debug Time
Debug "DeXOred"
war somit viel schneller als
Code: Alles auswählen
Procedure InternalEnXOr(*MemoryID,Length)
If Length>1
TempByte.b=PeekB(*MemoryID)
For pos=1 To Length -1
TempByte=PeekB(*MemoryID+pos)!TempByte
PokeB(*MemoryID+pos,TempByte)
Next pos
EndIf
EndProcedure
Procedure InternalDeXOr(*MemoryID,Length)
If Length>1
For pos=Length-1 To 1 Step -1
PokeB(*MemoryID+pos,PeekB(*MemoryID+pos)!PeekB(*MemoryID+pos-1))
Next pos
EndIf
EndProcedure
Size=200*1024*1024
*mem=AllocateMemory(Size)
Debug "Allocated"
Start=ElapsedMilliseconds()
InternalEnXOr(*mem,Size)
Time=ElapsedMilliseconds()-Start
Debug Time
Debug "EnXOred"
Start=ElapsedMilliseconds()
InternalDeXOr(*mem,Size)
Time=ElapsedMilliseconds()-Start
Debug Time
Ob daran jedoch jetzt nur die Schleifen oder auch vllt. die Peek/Poke-Befehle dran Schuld sind, weiß ich nicht, da ich das noch nicht speziell getestet hab.