Rücksprungadresse fehlt



  • Hallo,

    ich habe folgende Delphi-Funktion:

    function StrCharIdx(const str: String; const chr: Char; const num: Integer = 0): Integer; assembler;
      asm
        { str -> eax
          chr -> dl
          num -> ecx }
    
        {----- call StrLen -----}
        push   ebp
        mov	   ebp, esp
    
        push   ebx		// save ebx
        push   ecx		// save and ecx
    
        mov	   ebx, eax	// store str in ebx
    
        call   StrLen
        pop	   ecx 		// pop num
        mov	   ecx, eax  	// result (length of string) to ecx
    
        mov	   eax, ebx	// str address back to eax
    
        pop	   ebx		// nothing to do with ebx anymore
        mov	   ebx, ecx	// num to ebx
    
        pop	   ebp
        mov	   esp, ebp
        {----- finish -----}
    
        push   edi
    
        mov	   edi, eax	// address of str
        mov	   al,  dl		// prepare al to compare
    
        mov	   edx, ecx	// length of str to edx
    
        cld				// clear direction flag
        repnz scasb
    
        pop    edi
    
        jcxz   @@not_fnd
        jmp	   @@fnd
    
      @@not_fnd:
        or 	  edx, -1		// return -1 if not found
    
      @@fnd:
       sub	  edx, ecx              // length of hole string - offset of index
        mov   eax, edx		// return result
      end; (* of StrCharIdx *)
    (* -------------------------------------------------------------------------- *)
    

    Sie funktioniert wunderbar, nur dass Sie am Ende die Exception:
    Fehler beim Lesen von Adresse 0x00000000
    schmeißt.

    Auch nach mehrmaligem Durchschauen, erkenne ich den Fehler nicht.



  • function StrCharIdx(const str: String; const chr: Char; const num: Integer = 0): Integer; assembler;
      asm
        { str -> eax
          chr -> dl
          num -> ecx }
    
        {----- call StrLen -----}
        push   ebp          // das ganze Gebastel am Stack hier ist AFAIK komplett ueberfluessig
        mov	   ebp, esp
    
        push   ebx		// save ebx
        push   ecx		// save and ecx
    
        mov	   ebx, eax	// store str in ebx
    
        call   StrLen
        pop	   ecx 		// pop num
        mov	   ecx, eax  	// result (length of string) to ecx
    
        mov	   eax, ebx	// str address back to eax
    
        pop	   ebx		// nothing to do with ebx anymore
        mov	   ebx, ecx	// num to ebx
    
        pop	   ebp          // und noch besser...:
        mov	   esp, ebp     // *kabumm* - nach dieser Zeile ist der Stack hinueber
        {----- finish -----}
    
        push   edi
    
        mov	   edi, eax	// address of str
        mov	   al,  dl		// prepare al to compare
    
        mov	   edx, ecx	// length of str to edx
    
        cld				// clear direction flag
        repnz scasb
    
        pop    edi
    
        jcxz   @@not_fnd
        jmp	   @@fnd
    
      @@not_fnd:
        or 	  edx, -1		// return -1 if not found
    
      @@fnd:
       sub	  edx, ecx              // length of hole string - offset of index
        mov   eax, edx		// return result
      end; (* of StrCharIdx *)
    (* -------------------------------------------------------------------------- *)
    

    Allgemein solltest du dich mal genauer mit den Pascal-Call-Modellen befassen und unnoetiges Gebastel am Steck vermeiden.



  • Nobuo T schrieb:

    Allgemein solltest du dich mal genauer mit den Pascal-Call-Modellen befassen und unnoetiges Gebastel am Steck vermeiden.

    Ja, du hast recht. Um den Stack brauch ich mich hier wohl nicht kümmern. Ich hatte längere Zeit nichts mher mit dem Inline Assembler von Delphi gemacht und hatte irgendwie in Erinnerung, dass er sich nicht selber um den Stack kümmert.

    Dass vorher zu testen, wäre natürlich eine Idee gewesen ... Danke


Log in to reply