Kleines Stack Problem



  • Hallo,
    ich versuche mir gerade etwas Assembler anzueignen und komme leider nicht mehr weiter.
    Erst einmal mein Code:

    section .text
    
    extern printf
    global main
    
    main:
    	mov eax, 1
    	cmp eax, 2
    	je eax2
    
    eax1:
    	push msg;
    	call printf
    	jmp exit
    
    eax2:	
    	push msg2;
    	call printf
    	jmp exit
    
    exit:
    	mov eax, 1
    	mov ebx, 0
    	int 80h
    
    section .data
    	msg db 'Zahl ist 1',0xa
    	msg2 db 'Zahl ist 2',0xa
    

    Schiebe ich eine 2 ins EAX funktioniert es so wie es soll. Hingegen bei einer 1 erhalte ich folgende Ausgabe:
    Zahl ist 1
    Zahl ist 2

    Ich nehme an dass es irgendwie am Stack liegt, da ja alles drauf liegt. Ich müsste also irgendwie noch eine Länge mitgeben.
    Vielleicht liege ich da aber auch falsch.

    Für einen kleinen Tipp wäre ich sehr dankbar.

    Viele Grüße
    Thosten



  • eclere schrieb:

    msg db 'Zahl ist 1',0xa
    	msg2 db 'Zahl ist 2',0xa
    

    printf erwatet einen null-terminierten String. Ersetze also die beiden 0xa durch ein schlichtes 0. Dass es bei msg2 geklappt hat, war reiner Zufall.

    viele grüße
    ralph



  • Außerdem musst du beachten dass printf die cdecl Callingconvention nutzt. d.h. du musst die Parameter die du übergibst danach wieder abräumen.



  • Hallo,
    ich habe es gleich probiert. Leider erhalte ich dann überhaupt keine Ausgabe.

    Falls noch interessant hier meine nasm Anweisung:
    nasm -f elf zahl.asm

    Was die cdecl Callingconvention angeht, so muss ich gestehen davon habe ich noch nie gehört und muss erst einmal nachlesen...

    Viele Grüße
    Thorsten

    rkhb schrieb:

    eclere schrieb:

    msg db 'Zahl ist 1',0xa
    	msg2 db 'Zahl ist 2',0xa
    

    printf erwatet einen null-terminierten String. Ersetze also die beiden 0xa durch ein schlichtes 0. Dass es bei msg2 geklappt hat, war reiner Zufall.

    viele grüße
    ralph



  • eclere schrieb:

    ich habe es gleich probiert. Leider erhalte ich dann überhaupt keine Ausgabe

    Tatsächlich 😡 . Der Ausgabepuffer zickt, wenn kein Zeilenvorschub (LF) angegeben wird. Es gibt zwei Möglichkeiten:

    1. NASM erlaubt Strings mit \\n. Allerdings muss der String dann in accent graves (`) eingeschlossen werden:
    msg db `Zahl ist 1\n`,0
    

    oder mit normalen Anführungszeichen oder Apostrophen (" oder ')

    msg db "Zahl ist 1",10,0
    
    1. Du flushst den Ausgabepuffer (bzw. alle Puffer), bevor das Programm endet:
    ...
    extern printf, fflush
    ...
    exit:
        push 0
        call fflush
        add esp, 4
    
        mov eax, 1
        mov ebx, 0
        int 80h
    

    eclere schrieb:

    Falls noch interessant hier meine nasm Anweisung:
    nasm -f elf zahl.asm

    Ja natürlich! Wichtig wäre auch die Kommandozeile, mit der gelinkt wird.

    eclere schrieb:

    Was die cdecl Callingconvention angeht, so muss ich gestehen davon habe ich noch nie gehört und muss erst einmal nachlesen...

    Für Dich erst einmal wichtig sind zwei Sachen: "was gepusht wird, muss auch gepopt werden" (cdecl - add esp,4 oben tut das Gleiche) und "32-bit geht völlig anders als 64-bit".

    viele grüße
    ralph



  • Hallo ralph,

    vielen Dank. Nun klappt es.
    Viele Grüße
    Thorsten


Anmelden zum Antworten