Это код, с которым я играю прямо сейчас:
# 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!"
Инструкции по компиляции: gcc test.s -o test
Версия 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!"
Окончательная редакция (работы):
.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!"
Я изо всех сил пытаюсь понять, почему вызов puts завершается успешно, но вызов printf приводит к ошибке сегментации.
Может ли кто-нибудь объяснить это поведение и как должен вызываться printf?
Спасибо заранее.
Обзор:
- printf получает строку печати из %rdi и количество дополнительных аргументов в нижнем DWORD %rax.
- Результаты printf нельзя увидеть до тех пор, пока в стандартный вывод не будет введена новая строка или не будет вызвана функция fflush(0).
printf
(и других функций, которые принимают переменное количество аргументов) вам нужно загрузить AL с количеством аргументов, которые вы передаете в регистры XMM. В этом случае число будет равно 0. - person Ross Ridge   schedule 14.04.2016%al
, например.mov $0, %al
хотяxor %eax,%eax
в данном случае, вероятно, предпочтительнее. - person Ross Ridge   schedule 14.04.2016