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

我在ubuntu下使用nasm.顺便说一下,我需要从用户键盘获取单个输入字符(比如一个程序要求你输入y / n?)所以当按下键并且没有按下输入时我需要读取输入的字符.我google了很多,但我发现的所有内容都与这一行(int 21h)有关,导致“Segmentation Fault”.请帮我弄清楚如何获得单个字符或如何克服这个分段错误.
它可以通过装配来完成,但这并不容易.你不能使用int 21h,这是一个DOS系统调用,它在 Linux下不可用.

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

要在Linux上禁用规范模式,请使用ioctl系统调用将IOCTL(IO ControL)发送到STDIN.我假设您知道如何从汇编程序进行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(NOT ICANON).并将结果存储回c_lflag字段.

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

如果一切顺利,终端现在处于非规范模式.您可以通过设置规范标志(通过ORing c_lflag与ICANON)并再次调用TCSETS ioctl来恢复规范模式.在退出之前始终恢复规范模式

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

相关文章

目录前言一、创建Hadoop用户二、更新apt和安装Vim编辑器三、...
原文连接:https://www.cnblogs.com/yasmi/p/5192694.html ...
电脑重启后,打开VirtualBox,发现一直用的虚拟机莫名的消失...
参见:https://blog.csdn.net/weixin_38883338/article/deta...
Ubuntu 18.04 LTS 已切换到 Netplan 来配置网络接口。Netpla...
介绍每个 Web 服务都可以通过特定的 URL 在 Internet 上访问...