使用宏接受用户输入

Accepting input from user using macro

我正在尝试接受用户在 x68-64 nasm 代码中的输入。 如果我接受 16 个字节(例如 0000000000000001)应该为变量保留多少内存?

 SECTION .bss
    number resb 16 ;16 or 17(16+enter key)?

    %macro read 2  ;is it correct SECTION for defining macro?
    mov rax,00h
    mov rdi,00h ;unsigned int fd. what is correct value for fd?
    mov rsi,%1
    mov rdi,%2
    syscall
    %endmacro

SECTION .text
    read number,16 ;16 should be passed as length or 17 considering enter key?

你的意思是 16 个字节,而不是位。


您正在制作一个调用 read(2) 的宏。有关其功能的详细信息,请参见手册页。它只是从文件描述符中读取字节。如果文件描述符是具有正常终端设置的规范模式(而非原始模式)下的 tty,那么它将被行缓冲。即系统调用将阻塞,直到出现换行符或 EOF (ctrl-d)。或者直到有什么东西提前中断它,使其成为 return -EINTR,因为你是直接调用它而不是使用 glibc 包装函数为你重试中断的系统调用。

参见 stty(1) and termios(3) for the usual standard-library wrapper on top of the appropriate tty ioctlsTL:DR:获取熟化输入以外的任何东西都非常复杂。所以你看不到 "enter key"s,你只看到换行符。

重要的是要注意,如果输入多于您传递给 read(2) 的缓冲区,它只会读取足够的字节来填充缓冲区,其余的仍在等待中。它们不会被丢弃,所以另一个 read 调用会得到它们,而不是下一行的开头。


stdin 在 POSIX 中始终是文件描述符零,因此 rdi=0 是正确的。

不过,第三个参数(大小)进入 rdx。你把它放在 rdi 中,这可能会使你的 read(2) 调用 return 和 -EBADF 因为你的进程不太可能在 fd 16 上打开任何东西。

运行你的程序在strace下看看会发生什么。 (strace ./a.out)


使您的缓冲区与您希望程序一次性接受的最长行一样大。在交互式 tty 上,read(2) 将在一个换行符后 return,除非系统负载过重以至于您的进程在输入第二个换行符之前不会被唤醒。 (例如,作为大糊状物的一部分。)