Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Can';不能在程序集中调用'putchar'_C_Assembly_X86 - Fatal编程技术网

Can';不能在程序集中调用'putchar'

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,并且在终止程

我正在尝试使用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,并且在终止程序之前没有刷新
stdout
的缓冲区。这个问题是一个更大的潜在问题的症状,即您没有正确初始化和取消初始化libc。在每个使用libc的程序中,您应该:

  • 让libc在启动时进行自身初始化,使其初始化代码为
    \u start
    并调用您的
    main
    函数
  • 不要通过
    syscall
    指令执行原始系统调用,而是使用libc提供的包装器
  • 通过调用
    exit
    或从
    main
  • 使用C编译器驱动程序
    cc
    链接程序,而不是直接调用链接编辑器,正确链接所有libc代码

  • 一旦你有了更多的经验,你可能会偏离这些建议,但这样做可能会产生你可能没有意识到的微妙后果,因此,现在最好遵循这些规则。

    您看不到任何输出,因为libc的IO包执行缓冲IO,并且在终止程序之前,您不会刷新stdout的缓冲区。这个问题是一个更大的潜在问题的症状,即您没有正确初始化和取消初始化libc。在每个使用libc的程序中,您应该:

  • 让libc在启动时进行自身初始化,使其初始化代码为
    \u start
    并调用您的
    main
    函数
  • 不要通过
    syscall
    指令执行原始系统调用,而是使用libc提供的包装器
  • 通过调用
    exit
    或从
    main
  • 使用C编译器驱动程序
    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系统调用的包装器?