[C/asm] ungewöhnlich grosser string argv[1]



  • Mosche an alle:

    Es gibt mal wieder etwas das ich mir nicht selbst erklären kann:D :
    Wenn ich aus meinem C code

    #include <stdio.h>
    #include <string.h>
    
    int strlen_f(char*);
    
    int main(int argc, char** argv)
    {
    	int erg = strlen_f(argv[1]);
    
    	printf("%i", erg);
    	printf("\n");
    
    	return 0;
    }
    

    ...das erste argument (argv[1]) an eine Assembler funktion übergebe, die die länge des Strings berechnen soll, erhalte ich eine mir unerklärlich hohe zahl.
    Bei z.b "test" als erstes argument, lautet die Ausgabe : 1579
    Hier der ASM code der mit dem C programm gelinkt wird:

    .globl strlen_f
    
    .type strlen_f, @function
    strlen_f:
    
    	enter $0, $0
    
    	movl $-3, %eax		    #counter
    	movl 8(%ebp), %ebx	#catch parameter
    
    	leave
    .lo:
    	inc %eax
    	inc %ebx		     #search for term byte(0)	
    	cmp $0, (%ebx)		#if found: jmp ret
    	jne .lo
    
    ret:
    	ret			         #ret strlen
    

    Bei der Übergabe eines in main() declarierten cStrings funktioniert alles so wie es sollte.
    Nur bei der übergabe eines arguments bekomme ich eine Falsche ausgabe.

    Bin für jede Erklärung dankbar 🙂

    Gruss darrel


  • Mod

    enter/leave ist hier reichlich überflüssig, du prüfst erst ab dem zweiten Zeichen und wieso fängt dein counter bei -3 statt 0 an?
    Das Hauptproblem dürfte allerdings darin bestehen, dass deine Funktion ebx verändert, bei cdecl-Konvention darf eine Funktion nur eax,ecx und edx verändern.



  • camper schrieb:

    enter/leave ist hier reichlich überflüssig, du prüfst erst ab dem zweiten Zeichen und wieso fängt dein counter bei -3 statt 0 an?
    Das Hauptproblem dürfte allerdings darin bestehen, dass deine Funktion ebx verändert, bei cdecl-Konvention darf eine Funktion nur eax,ecx und edx verändern.

    danke erstmal für die schnelle Antwort.

    Ich habe jetzt enter/leave entfernt, den counter auf 0 gesetzt, ebx mit edx getauscht und den vergleich an den anfang der schleife gesetzt

    .type strlen_f, @function
    strlen_f:
    
    	movl 4(%esp), %edx
    	movl $0, %eax		
    
    lo:		
    	cmp $0, (%edx)
    	inc %edx
            inc %eax
    	jne lo
    
    ret:
    	ret
    

    ....und bekomme jetzt ein segmention fault 😕


  • Mod

    inc verändert das Zero-Flag. Deine Schleife endet also erst, wenn eax überlauft - dann hast du allerdings bereits den gesamten Speicher durchsucht, der doch teilweise geschützt sein dürfte.



  • camper schrieb:

    inc verändert das Zero-Flag. Deine Schleife endet also erst, wenn eax überlauft - dann hast du allerdings bereits den gesamten Speicher durchsucht, der doch teilweise geschützt sein dürfte.

    Ich habe jetzt "inc" mit "addl $1" ersetzt, was ja das selbe ist bis darauf, dass das zero flag gesetzt wird.

    aber ich erhalte immernoch einen segmention fault 😕



  • Die CDECL Calling Convention nicht vergessen

    ; prologue
    push ebp
    mov ebp,esp

    ; code

    ; epilogue
    pop ebp
    ret


  • Mod

    Darrel schrieb:

    camper schrieb:

    inc verändert das Zero-Flag. Deine Schleife endet also erst, wenn eax überlauft - dann hast du allerdings bereits den gesamten Speicher durchsucht, der doch teilweise geschützt sein dürfte.

    Ich habe jetzt "inc" mit "addl $1" ersetzt, was ja das selbe ist bis darauf, dass das zero flag gesetzt wird.

    aber ich erhalte immernoch einen segmention fault 😕

    inc beeinflusst alle normalen Flags außer carry. add beeinflusst zusätzlich das carry-Flag. mit jne prüfst du den Status, des zero-flags - dessen Inhalt hängt aber nunmal vom ergebnis der letzten Operation ab, die dieses Flag verändert, und das ist bei dir inc, und inc durch add zu ersetzen, bringt natürlich überhaupt nichts.

    Was du möchtest, ist das Ergebnis des Vergleichs als Sprungbedingung zu nutzen - dann musst du durch entsprechende Anordnung der Befehle folglich dafür sorgen, dass sich das Flag zwischen Vergleich und Sprung nicht mehr ändern kann. Es gibt noch die Möglichkeit, zum Inkrementieren lea einzusetzen, lea beeinflusst keine Flags. Das ist aber nicht unbedingt sinnvoll.

    .type strlen_f, @function
    strlen_f:
    
        movl 4(%esp), %eax
    
    lo:
        incl eax
        cmpb $0, -1(%eax)
        jne lo
    
        subl 4(%esp), %eax
        dec eax
    
        ret
    

    könnte zum Beispiel funktionieren.



  • Vielen dank für die Aufklärung !

    Jetzt ist mir alles um einiges klarer


Anmelden zum Antworten