Printf without newline in assembly

2019-06-19 09:07发布

问题:

I've recently read this article on using printf and scanf in assembly:

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

In particular it says "In printf, the newline prints a newline and then (if the output is in line buffered mode, which it probably is), flushes the internal output buffer so you can actually see the result. So when you remove the 10, there's no flush and you don't see the output."

However I do not know what to do if I do not want a newline after my output in my assembly file. Here's a simple test file I've written to try printing without a newline:

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

but as the article I've read suggests stdout isn't being flushed. I was thinking perhaps I need to somehow flush after I output the number? But I'm really not sure.

I am using the NASM assembly language.

Thanks in advance!

回答1:

Call fflush(stdout); to display what's currently sitting in the buffers.



回答2:

In FASM

push [_iob]
call [fflush] 

For NASM folk

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


回答3:

The correct answer for my question is as BasileStarynkevitch suggests in a comment above. I needed to add into my code:

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


回答4:

The other possibility would be to remove the default line buffering of the stdoutstream. Here the C call to do that. Translation to assembly let as exercice, as I don't think it makes even sense to do file/stream I/O in ASM, the cost/benefit is tremendously wrong.

setvbuf(stdout, NULL, _IONBF, 0);

This way every printf (and fputs, putc, puts etc...) would have an implicit fflush