Seite 1 von 1

Hilfe bei Asm-Optimierung gesucht

Verfasst: 27.01.2007 18:15
von Thorium
So wiedermal ne Assembler-Anfängergeschichte von mir. Also ich hab einen Differenzialpatcher in PureBasic geschrieben. Die Patchroutine hab ich dann mit meinen Anfängerkenntnisen nach Assembler übersetzt, als Lernübung.

Die Sache funktioniert auch allerdings ist der Asm-Code langsamer als der Purebasic-Code. Kann mir da vieleicht einer auf die sprünge helfen was ich da falsch gemacht hab?

PureBasic-Code

Code: Alles auswählen

Procedure PatchMemory(OldFile.l,OldFileLen,NewFile.l,DiffInfo.l)
  Define.b ChangeType
  Define.l i,ChangeCnt,NewFileLen,OldFPos,NewFLen,ChangeOffset,ChangeLen,InitNewFile
  
  InitNewFile = NewFile
  NewFileLen = PeekL(DiffInfo)
  ChangeCnt = PeekL(DiffInfo + 4)
  DiffInfo = DiffInfo + 8
  
  For i = 1 To ChangeCnt
  
    ChangeType = PeekB(DiffInfo)
    ChangeOffset = PeekL(DiffInfo + 1)
    ChangeLen = PeekL(DiffInfo + 5)
    DiffInfo = DiffInfo + 9
    
    Select ChangeType
    
      Case #PatchReplace
        CopyMemory(OldFile + OldFPos,NewFile,ChangeOffset - OldFPos)
        NewFile = NewFile + ChangeOffset - OldFPos
        CopyMemory(DiffInfo,NewFile,ChangeLen)
        DiffInfo = DiffInfo + ChangeLen
        NewFile = NewFile + ChangeLen
        OldFPos = ChangeOffset + ChangeLen
        
      Case #PatchCut
        CopyMemory(OldFile + OldFPos,NewFile,ChangeOffset - OldFPos)
        NewFile = NewFile + ChangeOffset - OldFPos
        OldFPos = ChangeOffset + ChangeLen
        
      Case #PatchPaste
        CopyMemory(OldFile + OldFPos,NewFile,ChangeOffset - OldFPos)
        NewFile = NewFile + ChangeOffset - OldFPos
        CopyMemory(DiffInfo,NewFile,ChangeLen)
        DiffInfo = DiffInfo + ChangeLen
        NewFile = NewFile + ChangeLen
        OldFPos = ChangeOffset   
    
    EndSelect
    
  Next

EndProcedure
Assembler-Code

Code: Alles auswählen

Procedure PatchMemory(OldFile.l,OldFileLen,NewFile.l,DiffInfo.l)
  Define.l i,NewFileLen,OldFPos,NewFLen,InitNewFile,Count

  ;eax = OldFPos
  ;ecx = Arbeitsregister
  ;edx = DiffInfo
  ;ebx = ChangeOffset
  ;ebp = ChangeLen
  ;esi = OldFile
  ;edi = NewFile

  !mov edx,[p.v_DiffInfo]
  !mov esi,[p.v_OldFile]
  !mov edi,[p.v_NewFile]
  
  !mov [p.v_InitNewFile],edi
  !mov eax,[edx]
  !mov [p.v_NewFileLen],eax
  !mov eax,[edx+4]
  !add edx,8
  
  !mov [p.v_i],eax
  !PatchLoopStart:
  
    !mov eax,[p.v_OldFPos]
    !mov cl,[edx]
    !mov ebx,[edx+1]
    !mov ebp,[edx+5]
    !add edx,9
    
    !cmp cl,1
    !je PatchReplace
    !cmp cl,2
    !je PatchCut
    !jmp PatchPaste
    
    !PatchReplace:
      ;unveränderte Daten kopieren
      !mov ecx,ebx
      !sub ecx,eax
      !call CopyMem
      ;veränderte Daten kopieren
      !mov ecx,ebp
      !push esi
      !mov esi,edx
      !call CopyMem
      !pop esi
      ;Berechnungen
      !add esi,ebp
      !add edx,ebp
      !mov eax,ebx
      !add eax,ebp
      !jmp CaseEnd
    
    !PatchCut:
      ;unveränderte Daten kopieren
      !mov ecx,ebx
      !sub ecx,eax
      !call CopyMem
      ;Berechnungen
      !add esi,ebp
      !mov eax,ebx
      !add eax,ebp
      !jmp CaseEnd
    
    !PatchPaste:
      ;unveränderte Daten kopieren
      !mov ecx,ebx
      !sub ecx,eax
      !call CopyMem
      ;einzufügende Daten kopieren
      !mov ecx,ebp
      !push esi
      !mov esi,edx
      !call CopyMem
      !pop esi
      ;Berechnungen
      !add edx,ebp
      !mov eax,ebx
      !jmp CaseEnd

      !CopyMem:
      !push ecx
      !shr ecx,2
      !rep movsd
      !pop ecx
      !and ecx,3
      !rep movsb
      !ret
    
    !CaseEnd:
    !mov [p.v_OldFPos],eax
  
  !mov ecx,[p.v_i]
  !dec ecx
  !mov [p.v_i],ecx
  !cmp ecx,0
  !jne PatchLoopStart
EndProcedure

Verfasst: 15.02.2007 16:30
von brotkasten-deluxe
recht einfach erklärt : schau in den source vom dem pb-code und vergleiche beide ;)

bzw. dann kannst du es dir selber erklären :)

Verfasst: 15.02.2007 23:05
von Thorium
brotkasten-deluxe hat geschrieben:recht einfach erklärt : schau in den source vom dem pb-code und vergleiche beide ;)

bzw. dann kannst du es dir selber erklären :)
Kannst du das etwas konkretisieren? Ich glaub ich seh vor lauter Bäumen den Wald net. ^^

Verfasst: 16.02.2007 00:00
von Leonhard
Also so schaut das im PureBasic-Assembler-Ausgabe aus:

Code: Alles auswählen

; :
; #PatchReplace = 1
; #PatchCut = 2
; #PatchPaste = 3
; 
; Procedure PatchMemory(OldFile.l,OldFileLen,NewFile.l,DiffInfo.l) 
Macro MP0{
_Procedure0:
  PUSH   ebx
  PS0=44
  SUB    esp,36
  MOV    eax,esp
  MOV    edx,eax
  ADD    edx,36
_ClearLoop0:
  MOV    dword [eax],0
  ADD    eax,4
  CMP    eax,edx
  JNE   _ClearLoop0                                                                                                              
; Define.b ChangeType 
; Define.l i,ChangeCnt,NewFileLen,OldFPos,NewFLen,ChangeOffset,ChangeLen,InitNewFile 
; 
; InitNewFile = NewFile 
  MOV    eax,dword [esp+PS0+8]
  MOV    dword [esp+32],eax
; NewFileLen = PeekL(DiffInfo) 
  MOV    eax,dword [esp+PS0+12]
  CALL   PB_PeekL
  MOV    dword [esp+12],eax
; ChangeCnt = PeekL(DiffInfo + 4) 
  MOV    ebx,dword [esp+PS0+12]
  ADD    ebx,4
  MOV    eax,ebx
  CALL   PB_PeekL
  MOV    dword [esp+8],eax
; DiffInfo = DiffInfo + 8 
  ADD    dword [esp+PS0+12],8
; 
; For i = 1 To ChangeCnt 
  MOV    dword [esp+4],1
_For1:
  MOV    eax,dword [esp+8]
  CMP    eax,dword [esp+4]
  JL    _Next2
; 
; ChangeType = PeekB(DiffInfo) 
  MOV    eax,dword [esp+PS0+12]
  CALL   PB_PeekB
  MOV    byte [esp],al
; ChangeOffset = PeekL(DiffInfo + 1) 
  MOV    ebx,dword [esp+PS0+12]
  INC    ebx
  MOV    eax,ebx
  CALL   PB_PeekL
  MOV    dword [esp+24],eax
; ChangeLen = PeekL(DiffInfo + 5) 
  MOV    ebx,dword [esp+PS0+12]
  ADD    ebx,5
  MOV    eax,ebx
  CALL   PB_PeekL
  MOV    dword [esp+28],eax
; DiffInfo = DiffInfo + 9 
  ADD    dword [esp+PS0+12],9
; 
; Select ChangeType 
  MOVSX  ebx,byte [esp]
  PUSH   ebx
; 
; Case #PatchReplace 
  MOV    ebx,1
  CMP    ebx,[esp]
  JNE   _Case1
; CopyMemory(OldFile + OldFPos,NewFile,ChangeOffset - OldFPos) 
  MOV    ebx,dword [esp+28]
  SUB    ebx,dword [esp+20]
  PUSH   ebx
  PUSH   dword [esp+PS0+16]
  MOV    ebx,dword [esp+PS0+12]
  ADD    ebx,dword [esp+28]
  PUSH   ebx
  CALL  _PB_CopyMemory@12
; NewFile = NewFile + ChangeOffset - OldFPos 
  MOV    ebx,dword [esp+PS0+12]
  ADD    ebx,dword [esp+28]
  SUB    ebx,dword [esp+20]
  MOV    dword [esp+PS0+12],ebx
; CopyMemory(DiffInfo,NewFile,ChangeLen) 
  PUSH   dword [esp+32]
  PUSH   dword [esp+PS0+16]
  PUSH   dword [esp+PS0+24]
  CALL  _PB_CopyMemory@12
; DiffInfo = DiffInfo + ChangeLen 
  MOV    ebx,dword [esp+PS0+16]
  ADD    ebx,dword [esp+32]
  MOV    dword [esp+PS0+16],ebx
; NewFile = NewFile + ChangeLen 
  MOV    ebx,dword [esp+PS0+12]
  ADD    ebx,dword [esp+32]
  MOV    dword [esp+PS0+12],ebx
; OldFPos = ChangeOffset + ChangeLen 
  MOV    ebx,dword [esp+28]
  ADD    ebx,dword [esp+32]
  MOV    dword [esp+20],ebx
; 
; Case #PatchCut 
  JMP   _EndSelect1
_Case1:
  MOV    ebx,2
  CMP    ebx,[esp]
  JNE   _Case2
; CopyMemory(OldFile + OldFPos,NewFile,ChangeOffset - OldFPos) 
  MOV    ebx,dword [esp+28]
  SUB    ebx,dword [esp+20]
  PUSH   ebx
  PUSH   dword [esp+PS0+16]
  MOV    ebx,dword [esp+PS0+12]
  ADD    ebx,dword [esp+28]
  PUSH   ebx
  CALL  _PB_CopyMemory@12
; NewFile = NewFile + ChangeOffset - OldFPos 
  MOV    ebx,dword [esp+PS0+12]
  ADD    ebx,dword [esp+28]
  SUB    ebx,dword [esp+20]
  MOV    dword [esp+PS0+12],ebx
; OldFPos = ChangeOffset + ChangeLen 
  MOV    ebx,dword [esp+28]
  ADD    ebx,dword [esp+32]
  MOV    dword [esp+20],ebx
; 
; Case #PatchPaste 
  JMP   _EndSelect1
_Case2:
  MOV    ebx,3
  CMP    ebx,[esp]
  JNE   _Case3
; CopyMemory(OldFile + OldFPos,NewFile,ChangeOffset - OldFPos) 
  MOV    ebx,dword [esp+28]
  SUB    ebx,dword [esp+20]
  PUSH   ebx
  PUSH   dword [esp+PS0+16]
  MOV    ebx,dword [esp+PS0+12]
  ADD    ebx,dword [esp+28]
  PUSH   ebx
  CALL  _PB_CopyMemory@12
; NewFile = NewFile + ChangeOffset - OldFPos 
  MOV    ebx,dword [esp+PS0+12]
  ADD    ebx,dword [esp+28]
  SUB    ebx,dword [esp+20]
  MOV    dword [esp+PS0+12],ebx
; CopyMemory(DiffInfo,NewFile,ChangeLen) 
  PUSH   dword [esp+32]
  PUSH   dword [esp+PS0+16]
  PUSH   dword [esp+PS0+24]
  CALL  _PB_CopyMemory@12
; DiffInfo = DiffInfo + ChangeLen 
  MOV    ebx,dword [esp+PS0+16]
  ADD    ebx,dword [esp+32]
  MOV    dword [esp+PS0+16],ebx
; NewFile = NewFile + ChangeLen 
  MOV    ebx,dword [esp+PS0+12]
  ADD    ebx,dword [esp+32]
  MOV    dword [esp+PS0+12],ebx
; OldFPos = ChangeOffset    
  MOV    eax,dword [esp+28]
  MOV    dword [esp+20],eax
; 
; EndSelect 
_Case3:
_EndSelect1:
  POP    eax
; 
; Next 
_NextContinue2:
  INC    dword [esp+4]
  JMP   _For1
_Next2:
; 
; EndProcedure 
  XOR    eax,eax
_EndProcedure1:
  ADD    esp,36
  POP    ebx
  RET    16
}