【问题标题】:No output from program written in assembly when piping into hexdump [duplicate]管道到 hexdump 时,用汇编语言编写的程序没有输出 [重复]
【发布时间】:2021-01-19 18:05:22
【问题描述】:

我想知道为什么汇编版本在通过管道传输到 hexdump 时没有显示任何输出?

源代码(printf.c):

#include <stdio.h>

// gcc -o printf printf.c && ./printf

int main() {
    const char *frmt = "%s\n";
    char *msg = "TEST";

    printf(frmt, msg);

    return 0;
}

输出到 STDOUT:

$ ./printf
TEST

管道到hexdump:

$ ./printf | hexdump -v -C
00000000  54 45 53 54 0a                                    |TEST.|
00000005

追踪:

$ strace -ttT -f -e trace="write" ./printf
17:44:33.841789 write(1, "TEST\n", 5TEST
)   = 5 <0.000050>
17:44:33.842320 +++ exited with 0 +++

源代码(printf.nasm):

; nasm -g -f elf64 printf.nasm && ld printf.o -o printf && ./printf

extern printf

global main

section .text
main:
    mov rdi, frmt
    mov rsi, msg
    xor rax, rax
    call printf

    jmp exit

exit:
    mov rax, 60
    xor rdi, rdi
    syscall

section .data
    frmt db "%s", 0xa, 0x0
    msg: db "TEST"
    len:  equ $ - msg

输出到 STDOUT:

$ ./printf
TEST

管道到hexdump(无输出):

$ ./printf | hexdump -v -C

追踪:

$ strace -ttT -f -e trace="write" ./printf
17:46:00.828887 write(1, "TEST\n", 5TEST
)   = 5 <0.000050>
17:46:00.829282 +++ exited with 0 +++

【问题讨论】:

  • 您在msg 上缺少尾随空值?
  • 所有 C 字符串都以 0x0 结尾。您在 frmt 中有它,但在程序集中没有 msg
  • 可能是因为您对 printf 的调用正在被缓冲,并且因为您使用 syscall 退出程序,缓冲区没有被刷新并且输出丢失。不要使用 syscall 退出,而是调用 exit 以确保正确刷新缓冲区并终止进程。
  • @Michael Petch:我同意,我也认为输出是缓冲的。但是,我认为从 main 返回(很像 C 示例所做的那样)同样最终会按预期刷新缓冲区。
  • @ecm: 是的,一个简单的ret 就可以完成,缓冲区将被刷新,进程也将以这种方式终止。 C 运行时两种方式都会在终止进程之前刷新任何缓冲区并进行任何必要的拆除。

标签: c assembly x86-64 nasm


【解决方案1】:

%s 格式用于打印 C 字符串,要求以零字节结尾。您缺少 msg 的空终止符。

section .data
    frmt db "%s", 0xa, 0x0
    msg: db "TEST", 0x0
    len:  equ $ - msg

似乎也不需要len 变量,您从不使用它。

【讨论】:

  • 谢谢,这仍然没有解决问题。
  • 这里的问题是退出系统调用阻止了 C 库缓冲的任何数据(即通过printf)在进程终止之前正确刷新。不要使用 syscall 退出,而是使用 C 库 exit 函数。如果他们使用 sys_write 系统调用来写入,那么字符串就不必被 nul 终止。几乎想知道他们是否曾经有一个版本可以做到这一点。
  • 在这种情况下,exit 的替代方法是简单地使用来自mainret
猜你喜欢
  • 2011-02-08
  • 2016-07-05
  • 1970-01-01
  • 1970-01-01
  • 2014-10-07
  • 2016-09-27
  • 1970-01-01
相关资源
最近更新 更多