2011-12-14 6 views
6

Ho recentemente letto questo articolo sull'utilizzo di printf e scanf in assemblea:Printf senza ritorno a capo in assemblea

Meaning of intfmt: db "%d", 10, 0 in assembly

In particolare si dice "In printf, il ritorno a capo stampa una nuova riga e poi (se l'output è in modalità buffer di linea, che probabilmente è), svuota il buffer di output interno in modo che tu possa effettivamente vedere il risultato, quindi quando rimuovi il 10, non c'è flush e non vedi l'output. "

Tuttavia, non so cosa fare se non desidero una nuova riga dopo il mio output nel mio file di assembly. Ecco un file di test semplice che ho scritto per provare a stampare senza una nuova riga:

extern printf 


LINUX  equ  80H  ; interupt number for entering Linux kernel 
EXIT   equ  60  ; Linux system call 1 i.e. exit() 




section .data 
    int_output_format: db "%ld", 0 


segment .text 
    global main 


main: 
    mov r8, 10 
    push rdi 
    push rsi 
    push r10 
    push r9 
    mov rsi, r8 
    mov rdi, int_output_format 
    xor rax, rax 
    call printf 
    pop r9 
    pop r10 
    pop rsi 
    pop rdi 
    call os_return  ; return to operating system 


os_return: 
    mov rax, EXIT  ; Linux system call 1 i.e. exit() 
    mov rdi, 0  ; Error code 0 i.e. no errors 
    syscall  ; Interrupt Linux kernel 64-bit 

ma come l'articolo che ho letto suggerisce stdout non viene lavata. Stavo pensando che forse avrei dovuto in qualche modo svuotare dopo aver prodotto il numero? Ma non sono davvero sicuro.

Sto utilizzando il linguaggio assembly NASM.

Grazie in anticipo!

risposta

3

La risposta corretta per la mia domanda è come suggerisce BasileStarynkevitch in un commento sopra. avevo bisogno di aggiungere nel mio codice:

extern fflush 
... 
xor rax, rax 
call fflush 
... 
3

Chiamare fflush(stdout); per visualizzare cosa è attualmente presente nei buffer.

+0

Penso che sia la sintassi C? Sto cercando come chiamarlo in assemblea. –

+0

Per lo standard C, 'stdout' è una macro che si espande in un'espressione di tipo' FILE * '. Non so come sia definito nel tuo compilatore. È necessario estrarre il valore da 'stdio.h'. –

+3

E puoi chiamare 'fflush (NULL)' che è più facile nel codice assembly, forse 'xor% eax,% eax; chiama fflush' –

3

In FASM

push [_iob] 
call [fflush] 

Per NASM popolare

extern fflush 
extern stdout 
... 
push dword [stdout] 
call fflush 
add esp, 4 
etc... 
+0

Come realizzeresti questo in NASM? È lo stesso? –

1

L'altra possibilità sarebbe quella di rimuovere il buffer linea di default del torrente stdout. Qui il C chiama per farlo. La traduzione all'assemblaggio è da considerarsi come esercizio, poiché non penso che abbia senso eseguire file/stream I/O in ASM, il costo/beneficio è tremendamente sbagliato.

setvbuf(stdout, NULL, _IONBF, 0); 

In questo modo ogni printf (e fputs, putc, puts ecc ...) avrebbe un implicito fflush