gpt4 book ai didi

linux - 如何在 ubuntu 下使用 nasm(程序集)从键盘读取单个字符输入?

转载 作者:太空宇宙 更新时间:2023-11-03 16:46:40 25 4
gpt4 key购买 nike

我在 ubuntu 下使用 nasm。顺便说一下,我需要从用户键盘获取单个输入字符(比如当程序要求您输入 y/n 时?),因此当按下按键而不按回车键时,我需要读取输入的字符。我用谷歌搜索了很多,但我发现的所有内容都以某种方式与这条线 (int 21h) 相关,这导致了“Segmentation Fault”。请帮我弄清楚如何获取单个字符或如何克服这个段错误。

最佳答案

可以通过汇编完成,但这并不容易。不能使用 int 21h,这是一个 DOS 系统调用,在 Linux 下不可用。

要在类 UNIX 操作系统(例如 Linux)下从终端获取字符,您可以从 STDIN(文件编号 0)读取。通常,read 系统调用将阻塞,直到用户按下回车键。这称为规范模式。要在不等待用户按下 enter 的情况下读取单个字符,您必须首先禁用规范模式。当然,如果您稍后想在程序退出之前进行线路输入,则必须重新启用它。

要在 Linux 上禁用规范模式,您可以使用 ioctl 系统调用向 STDIN 发送一个 IOCTL (IO ControL)。我假设您知道如何从汇编程序进行 Linux 系统调用。

ioctl 系统调用具有三个参数。第一个是将命令发送到的文件 (STDIN),第二个是 IOCTL 编号,第三个通常是指向数据结构的指针。 ioctl 成功时返回 0,失败时返回负错误代码。

您需要的第一个 IOCTL 是 TCGETS(编号 0x5401),它在 termios 结构中获取当前终端参数。第三个参数是指向 termios 结构的指针。从内核源码来看,termios结构定义为:

struct termios {
tcflag_t c_iflag; /* input mode flags */
tcflag_t c_oflag; /* output mode flags */
tcflag_t c_cflag; /* control mode flags */
tcflag_t c_lflag; /* local mode flags */
cc_t c_line; /* line discipline */
cc_t c_cc[NCCS]; /* control characters */
};

其中 tcflag_t 是 32 位长,cc_t 是一个字节长,NCCS 目前定义为 19。请参阅 NASM 手册,了解如何方便地为这样的结构定义和保留空间。

因此,一旦获得当前的 termios,就需要清除规范标志。该标志位于 c_lflag 字段中,掩码为 ICANON (0x00000002)。要清除它,请计算 c_lflag AND(不是 ICANON)。并将结果存储回 c_lflag 字段。

现在您需要通知内核您对 termios 结构的更改。使用 TCSETS(编号 0x5402)ioctl,第三个参数设置您的 termios 结构的地址。

如果一切顺利,终端现在处于非规范模式。您可以通过设置规范标志(通过将 c_lflag 与 ICANON 进行 OR 运算)并再次调用 TCSETS ioctl 来恢复规范模式。 总是在退出前恢复规范模式

正如我所说,这并不容易。

关于linux - 如何在 ubuntu 下使用 nasm(程序集)从键盘读取单个字符输入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3305005/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com