This is the code I am playing with right now:
# file-name: test.s
# 64-bit GNU as source code.
.global main
.section .text
main:
lea message, %rdi
push %rdi
call puts
lea message, %rdi
push %rdi
call printf
push $0
call _exit
.section .data
message: .asciz "Hello, World!"
Compilation instructions: gcc test.s -o test
Revision 1:
.global main
.section .text
main:
lea message, %rdi
call puts
lea message, %rdi
call printf
mov $0, %rdi
call _exit
.section .data
message: .asciz "Hello, World!"
Final Revision (Works):
.global main
.section .text
main:
lea message, %rdi
call puts
mov $0, %rax
lea message, %rdi
call printf
# flush stdout buffer.
mov $0, %rdi
call fflush
# put newline to offset PS1 prompt when the program ends.
# - ironically, doing this makes the flush above redundant and can be removed.
# - The call to fflush is retained for display and
# to keep the block self contained.
mov $'\n', %rdi
call putchar
mov $0, %rdi
call _exit
.section .data
message: .asciz "Hello, World!"
I am struggling to understand why the call to puts succeeds but the call to printf results in a Segmentation fault.
Can somebody explain this behavior and how printf is intended to be called?
Thanks ahead of time.
Summary:
- printf obtains the printing string from %rdi and the number of additional arguments in %rax's lower DWORD.
- printf results cannot be seen until a newline is put into stdout, or fflush(0) is called.