我是汇编的初学者(使用nasm)。我正在通过大学课程学习装配。
我正在尝试了解sys_read linux系统调用时的行为。具体来说, sys_read在读取新行或换行符时会停止。根据我所教的,这是事实。这online tutorial article也肯定了事实/主张。
当sys_read检测到换行符时,控件返回程序,用户输入位于您在ECX中传递的内存地址。
我检查了linux程序员的sys_read调用手册(通过“man 2 read”)。它没有提到它应该的行为,对吗?
read()尝试从文件描述符fd读取计数字节数 从buf开始进入缓冲区。
在支持搜索的文件上,读操作开始于 文件偏移量,文件偏移量增加字节数 读。如果文件偏移量处于或超过文件末尾,则不会有字节 read,read()返回零。
如果count为零,read()可能会检测到下面描述的错误。在 没有任何错误,或者如果read()没有检查错误,a read()的计数为0,返回零,没有其他影响。
如果count大于SSIZE_MAX,则结果未指定。
所以我的问题是,为什么会发生这种行为? Linux内核中的规范是否应该发生这种情况还是其他内容的结果?
答案 0 :(得分:9)
这是因为你正在阅读POSIX tty in canonical mode(在你按返回“提交”行之前退格工作;这些都是由内核的tty驱动程序处理的)。查找POSIX tty语义/ stty / ioctl。如果您运行./a.out < input.txt
,则不会看到此行为。
请注意,如果你点击control-d(EOF tty控制序列),TTY上的read()
将返回没有换行符。
假设read()
读取整行对于玩具程序是可以的,但是不开始假设任何需要健壮的东西,即使你已经检查过你从TTY读到。我忘记了如果用户将多行文本粘贴到终端模拟器中会发生什么。很可能它们最终都在一个read()
缓冲区中。
另请参阅my answer on a question about small read()
s leaving unread data on the terminal:如果在一行上输入的字符多于read()
缓冲区大小,则至少需要再读取一次系统调用来清除输入。
正如您所指出的,read(2)
libc函数只是sys_read
的一个薄包装器。这个问题的答案实际上与汇编语言无关,对C语言(或任何其他语言)的系统编程也是如此。
进一步阅读:
stty(1)
手册页:您可以在哪里更改哪个控制角色可以做什么。答案 1 :(得分:4)
这不是read()
系统调用的属性,而是终端驱动程序termios
的属性。在默认配置中,termios会缓冲输入的字符(即您键入的内容),直到您按 Enter ,然后整行将被发送到从终端读取的程序。这是为了方便起见,因此您可以在发送之前编辑该行。
正如Peter Cordes所说,当从其他类型的文件(如常规文件)中读取时,这种行为不存在,并且可以通过配置termios来关闭。
教程说的是垃圾,请忽略它。