Can';不能在程序集中调用'putchar'
我正在尝试使用C标准库中的Can';不能在程序集中调用'putchar',c,assembly,x86,C,Assembly,X86,我正在尝试使用C标准库中的putchar函数。这看起来很简单——你传入一个int,它把字符写到stdout。然而,当我编译并运行这个程序时,什么都没有发生 # This doesn't work: .section .text .globl _start _start: mov $0x41, %dil call putchar mov $60, %rax syscall 您看不到任何输出,因为libc的IO包执行缓冲IO,并且在终止程
putchar
函数。这看起来很简单——你传入一个int,它把字符写到stdout。然而,当我编译并运行这个程序时,什么都没有发生
# This doesn't work:
.section .text
.globl _start
_start:
mov $0x41, %dil
call putchar
mov $60, %rax
syscall
您看不到任何输出,因为libc的IO包执行缓冲IO,并且在终止程序之前没有刷新
stdout
的缓冲区。这个问题是一个更大的潜在问题的症状,即您没有正确初始化和取消初始化libc。在每个使用libc的程序中,您应该:
\u start
并调用您的main
函数syscall
指令执行原始系统调用,而是使用libc提供的包装器exit
或从main
cc
链接程序,而不是直接调用链接编辑器,正确链接所有libc代码一旦你有了更多的经验,你可能会偏离这些建议,但这样做可能会产生你可能没有意识到的微妙后果,因此,现在最好遵循这些规则。您看不到任何输出,因为libc的IO包执行缓冲IO,并且在终止程序之前,您不会刷新stdout的缓冲区。这个问题是一个更大的潜在问题的症状,即您没有正确初始化和取消初始化libc。在每个使用libc的程序中,您应该:
\u start
并调用您的main
函数syscall
指令执行原始系统调用,而是使用libc提供的包装器exit
或从main
cc
链接程序,而不是直接调用链接编辑器,正确链接所有libc代码一旦您有了更多的经验,您可能会偏离这些建议,但这样做可能会产生您可能没有意识到的微妙后果,因此现在最好只遵循这些规则。这是因为您的程序既不能正确初始化libc,也不能正确取消初始化它,因此在退出时不会刷新缓冲区。要解决此问题,请从
main
(而不是\u start
)启动程序,通过C编译器链接,并通过从main
返回或调用exit
@fuz Ahh来终止程序,ok。因此,将退出行为从系统调用更改为callexit
,似乎使它起到了作用。为什么会发生这种情况?这是因为libc没有缓冲的I/O。在退出时,输出缓冲区由函数exit
刷新。如果不调用exit
或手动刷新输出缓冲区,则不会刷新它们。也就是说,仅仅调用exit
是不够的!除非您也正确初始化libc(通过让程序从main
启动,并让C编译器提供\u start
来初始化libc),否则如果您使用任何libc函数,都可能会发生奇怪的事情。如果您使用libc,您应该尽量不要直接调用任何系统调用。请改用libc函数!另一方面,如果您放弃使用putchar
,您可以使用write
,它不需要任何initialization@AnttiHaapalawait是write
只是sys\u write系统调用的包装器?这是因为您的程序既不能正确初始化libc,也不能正确地去初始化它,因此,不会在退出时刷新缓冲区。要解决此问题,请从main
(而不是\u start
)启动程序,通过C编译器链接,并通过从main
返回或调用exit
@fuz Ahh来终止程序,ok。因此,将退出行为从系统调用更改为callexit
,似乎使它起到了作用。为什么会发生这种情况?这是因为libc没有缓冲的I/O。在退出时,输出缓冲区由函数exit
刷新。如果不调用exit
或手动刷新输出缓冲区,则不会刷新它们。也就是说,仅仅调用exit
是不够的!除非您也正确初始化libc(通过让程序从main
启动,并让C编译器提供\u start
来初始化libc),否则如果您使用任何libc函数,都可能会发生奇怪的事情。如果您使用libc,您应该尽量不要直接调用任何系统调用。请改用libc函数!另一方面,如果您放弃使用putchar
,您可以使用write
,它不需要任何initialization@AnttiHaapalawait是write
只是sys\u write系统调用的包装器?