当我在 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
并开始阅读。写的真好!
我有这个代码:
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
并开始阅读。写的真好!