2015-11-25 3 views
9

Ich habe eine einfache NASM Programm geschrieben:Warum kann nicht aus dem Aufruf c Bibliothek printf in asm sein piped zu anderen Programmen?

printtest.asm

section .data 
str_out db "val = %d",10,0 

section .text 

global main 

extern printf 

main: 

    PUSH 5 
    PUSH DWORD str_out 
    CALL printf 
    ADD ESP, 8 
    MOV EAX, 1 
    INT 80h 

Ich Verknüpfung und die Schaffung einer ausführbaren mit den folgenden Befehlen:

nasm -f elf -l printtest.lst printtest.asm 
gcc -o printtest printtest.o 

Wenn verknüpft und ausgeführt wird, das druckt "val = 5" auf die Konsole kein Problem. Soweit mir bekannt ist, schreibt printf standardmäßig auf stdout. Also, warum, wenn ich versuche, dies zu einem anderen Programm zu leiten, scheint das andere Programm keine Eingabe zu bekommen?

Z. B

./printtest | cat 

scheint nichts

Ich bin sicher, ich bin im Grunde Missverständnis, hier etwas zu tun.

Antwort

11

C stdio-Funktionen können standardmäßig gepuffert werden, daher schreibt das Schreiben auf stdout mit printf nicht immer wirklich etwas - manchmal schreibt es einfach in den Puffer und wartet auf einen nachfolgenden Flush. Oft hängt es davon ab, ob ein bestimmter stdio-Stream gepuffert ist oder nicht, ob er mit einem Terminal oder einer Pipe oder einer Datei oder etwas anderem verbunden ist.

Wenn Sie den Exit-Systemaufruf (wie Sie) aufrufen, gehen alle Daten in den Puffern verloren. Wenn Sie stattdessen die Funktion exit der C-Bibliothek aufrufen, werden alle Puffer gelöscht, bevor sie tatsächlich beendet werden.

+0

Sie sind ein Gott unter den Menschen. Vielen Dank! – Jake

+0

Würde '0 zurückgeben?' Von main() das Gleiche erreichen? Nur neugierig (und ich bin nicht in einer Position, wo ich das gerade jetzt kann). – keithmo

+0

Sollte tun. Beachten Sie, dass das Schreiben Ihrer eigenen 'main' in asm und das Aufrufen der C-Bibliothek nicht als sicher gilt - einige C-Implementierungen beruhen auf speziellem Code, der vom Compiler zur' main' hinzugefügt wurde, um die Standardbibliothek ordnungsgemäß zu initialisieren. Linux sollte jedoch in Ordnung sein. –