0

I have been trying to call printf from x64 asm, but it prints garbage Here is the code:

;print all fib numbers from 0 until 100
global main
extern printf
;printf notes
;mov al 0 is neccesary
;rdi: format string
;rsi, rdx, r8... args
section .text
main:
    mov r8, 0 ;counter
    mov r9, 0 ;nth value
    mov r10, 1;n + 1 value
    mov al, 0
    Loop:
    mov rsi, r9
    mov rdx, r10
    mov rdi, format_str
    call printf
    mov r11, r10
    add r10, r9
    mov r9, r11
    inc r8
    cmp r8, 100
    jl Loop

    mov rax, 60
    mov rdi, 0
    syscall

section .rodata
format_str: db "%3d: %30d\\n", 0

Note the mov al. If it is inside the loop, the program prints garbage. But if it is outside the loop, then the program segfaults.

I compile with gcc and I simply want it to output as it would if it were called from c

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Nocturne
  • 1
  • 2
  • 1
    `printf` returns in EAX, so you need to zero AL inside the loop. [glibc scanf Segmentation faults when called from a function that doesn't align RSP](https://stackoverflow.com/q/51070716) explains why it crashes; [Why does printf still work with RAX lower than the number of FP args in XMM registers?](https://stackoverflow.com/q/71982459) shows the library code that will do 16-byte-aligned stores to the stack with non-zero AL. Also, R8 and R9 are call-clobbered; use RBX or R12 to R15 if you want your loop counters to survive the call. – Peter Cordes Feb 14 '23 at 05:05
  • 1
    Also, you want a literal backslash in your format string, not a newline? That's weird, but inside NASM double quotes, you only need one backslash for that. Only NASM backticks interpolate C-style backslash escapes. See also [Using printf in assembly leads to empty output when piping, but works on the terminal](https://stackoverflow.com/q/38379553) - don't make a raw exit system call after using stdio functions; without a newline, line-buffered stdout will lose the end of the output up to some buffer size. – Peter Cordes Feb 14 '23 at 05:22
  • 1
    I'm assuming NASM since even gcc / GAS in `.intel_syntax noprefix` mode (which can be set via command-line options) couldn't assemble this; GAS uses a different comment character and different directives. – Peter Cordes Feb 14 '23 at 05:23

0 Answers0