2015-11-25 20 views
9

Ho scritto un semplice programma NASM:Perché non è possibile stdout dal chiamare la libreria c printf in asm essere convogliato ad altri programmi?

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 

stanno collegando e la creazione di un eseguibile con i seguenti comandi:

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

Quando collegate ed eseguito, questo stampa "val = 5" alla console non presenta problemi. Per quanto ne so, chiamando printf per scritture di default su stdout. Quindi, perché quando provo a collegarlo a un altro programma, l'altro programma sembra non ricevere input?

es

./printtest | cat 

sembra fare nulla

Sono sicuro che io sono fondamentalmente malinteso qualcosa qui.

risposta

11

Le funzioni stdio possono essere bufferizzate per impostazione predefinita, pertanto la scrittura su stdout con printf non genera in realtà nulla, a volte scrive solo nel buffer, in attesa di un flush successivo. Spesso, se un determinato flusso di stdio viene memorizzato nel buffer o meno dipende dal fatto che sia connesso a un terminale oa una pipe o un file o qualcos'altro.

Quando si chiama la chiamata di sistema di uscita (come si fa), tutti i dati ancora presenti nei buffer andranno persi. Se si chiama invece la funzione di libreria C exit, si svuoteranno tutti i buffer prima che si esca effettivamente.

+0

Sei un dio tra gli uomini. Grazie! – Jake

+0

Sarebbe 'return 0;' da main() ottiene la stessa cosa? Solo curioso (e non sono in una posizione in cui posso farlo ora). – keithmo

+0

Dovrebbe fare. Si noti che scrivere il proprio 'main' in asm e quindi chiamare la libreria C non è garantito per essere sicuro - alcune implementazioni C si basano su un codice speciale aggiunto a' main' dal compilatore per inizializzare correttamente la libreria standard. Linux dovrebbe andare bene, comunque. –