【问题标题】:Why do i need to call syscall write before syscall read to make it accept user input?为什么我需要在系统调用读取之前调用系统调用写入以使其接受用户输入?
【发布时间】:2019-08-26 19:25:37
【问题描述】:

在下面的 x64 汇编程序中,我尝试从命令行读取单个字符,然后将其打印回来。您会注意到,在实际阅读角色之前,我正在执行看似无用的写入操作。

该程序编译,运行时停止,接受一个字符作为输入,按回车键后将写回该字符并退出。如果没有虚假写入,它就不会停止并接受用户输入而只是退出。这是为什么呢?

test.asm:

        global _start

        section .text
_start:
        mov r8, stack

        mov rax, 1  ; syscall write
        mov rdi, 1  ; 
        mov rsi, r8 ; 
        mov rdx, 1  ; Why do I need to do this write
        syscall     ; to make the following read work?

        mov rax, 0  ; syscall read
        mov rdi, 0  ; 
        mov rsi, r8 ; 
        syscall     ; Read a character from the cli.

        mov rax, 1  ; syscall write
        mov rdi, 1  ; 
        mov rsi, r8 ; 
        mov rdx, 1  ; 
        syscall     ; Print the character back to the cli.

        mov rax, 60 ; 
        mov rdi, 0  ; 
        syscall     ; Exit nicely.

        section .bss
stack:  resb 131072

我在 Ubuntu 16.04 上使用 nasm 编译如下:

nasm -f elf64 -o test.o test.asm
ld -m elf_x86_64 -o test test.o
./test

【问题讨论】:

  • 当您尝试不写入时,您是否也将 rdx 设置为 1 (mov rdx, 1)?如果不是,我相信这就是原因。你没有告诉你的系统调用要读多少
  • 这似乎确实是答案!我错过了 read 调用的第四个参数。您知道诸如此类的 x64 系统调用的良好文档吗?
  • Linux内核源代码?
  • 好的,我会将其设置为答案,以便我们关闭它。我通常使用@MichaelPetch 发布的链接。

标签: linux assembly x86-64 nasm


【解决方案1】:

问题在于,当您尝试不进行第一次写入时,您没有将 rdx 设置为 1 和 mov rdx, 1。因此,您没有告诉系统调用要读取多少内容。 在这里你可以看看 syscall table

【讨论】:

    猜你喜欢
    • 2017-04-16
    • 2019-06-06
    • 2021-08-17
    • 2014-11-21
    • 2011-08-01
    • 1970-01-01
    • 2021-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多