当我在 system_read 中断、汇编方面按下 Enter 按钮时究竟发生了什么?

What exactly happens when I hit the Enter button in terms of system_read interrupt, assembly?

我有这个代码:

section .bss
    buff    resb 1
readfromkeyboard:
    mov     eax,3       ;specify system read
    mov     ebx,0       ;specify standard in -> keyboard
    mov     ecx,buff    ;where to store what is read
    mov     edx,1       ;read 1 byte
    int     0x80        ;tell linux to do everything above

    mov     eax,4       ;sys_write
    mov     ebx,1       ;Standard output
    mov     ecx,buff    ;what to print          
    mov     edx,1       ;how long to print
    int     0x80        ;tell linux to do everything above

效果很好。

当我启动该过程时,终端中的光标将开始闪烁,我可以自由输入字符。此时我可以随意输入任意数量的字符,除非我点击 "ENTER" 将读取 1 个字节并将其打印在终端中。

我的问题是,当我输入字符并按下 Enter 时内部发生了什么。所以我在键盘上按下 'a',然后说 'c',此时此数据存储在哪里?它们是否已经在我的代码中由 'buff' 寻址的内存 space 中?为什么当我按 Enter 时 Linux 会读取?

如果您要求 1 个字节,那么输入函数将永远不会在 buff 的内存中存储任何额外的字节。 Linux 只会将 a 存储在 buff 但肯定不会存储 c

从输入到应用还有很长的路要走:

  • 硬件
  • 驱动层
  • 控制台层
  • 阅读功能

其中某处发生了行的处理,我认为它是在控制台层。在那里您可以输入按行处理的数据。

如果一个应用程序出现并读取,它会获得它所要求的尽可能多的字符,剩下的字符将保留用于下一次读取调用。

如果还有 none 剩余,它将等到下一行完成 - 或者如果用户按下 ^D,这意味着终止当前的 read() 调用。如果之前没有输入数据,read() returns 0,表示EOF。在所有其他情况下,read() returns 到目前为止读取的字节数。

linux 终端驱动程序正在读取字符并将它们缓冲在自己的内存中 space。因为您的终端处于 'line' 模式,所以此缓冲会一直持续到 ENTER 键结束一行。此时数据可以传输到您提供的缓冲区中。您只请求了 1 个字符,所以这就是您得到的字符,其余字符位于终端驱动程序的内存中,供您下一次读取请求使用。

@glglgl 在那里有一个很好的答案,但这里有一个更直接的答案:其他字符位于读取输入缓冲区中等待处理。

既然你在这里似乎是在谈论Linux,那么内核有一个专门为此预留的缓冲区,它是在注册字符设备时创建的。如果你真的想深入研究这个,我强烈建议 this article。到达那里后,搜索 vfs_read 并开始阅读。写的真好!