微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在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来恢复规范模式.在退出之前始终恢复规范模式

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

原文地址:https://www.jb51.cc/ubuntu/347356.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐