如何在 Linux 上使用系统调用等待按键中断?

2023-11-30

我希望当用户在我的程序中按下特殊按键(如 F1-12)时接收中断,该程序是用 nasm 编写的。我只需要在主函数开始时等待函数按键即可。我知道这可以通过 BIOS 实现int 16h,它返回一个扫描码。我怎样才能在Linux下做到这一点?


所需的代码相当复杂;我最终弄清楚了如何使用原始 ioctl、读取和写入来检查 C 中的 F1。如果您熟悉汇编和 Linux 系统调用,那么 nasm 的翻译应该很简单。

这并不完全是您想要的,因为它只检查 F1,而不检查其余的。 F1的序列是0x1b、0x4f、0x50。您可以使用以下命令找到其他序列od -t x1并按下 键。例如,F2 为 0x1b、0x4f、0x51。

基本思想是,我们获取当前的终端属性,将它们更新为原始属性(cfmakeraw),然后将它们设置回来。 ioctl 系统调用用于此目的。

在处于原始模式的终端上,read()将获取用户输入的任何字符,这与“cooked”模式不同,在“cooked”模式中,内核使用退格键和 control-u 进行行编辑,直到用户通过按 Enter 或 control-d (EOF) 提交该行。

#include <unistd.h>
#include <sys/ioctl.h>
#include <termios.h>

struct ktermios {
    tcflag_t c_iflag;
    tcflag_t c_oflag;
    tcflag_t c_cflag;
    tcflag_t c_lflag;
    cc_t c_line;
    cc_t c_cc[19];
};

int getch() {
    unsigned char c;
    read(0, &c, sizeof(c));
    return c;
}

int main(int argc, char *argv[]) {
    struct ktermios orig, new;
    ioctl(0, TCGETS, &orig);
    ioctl(0, TCGETS, &new);   // or more simply  new = orig;

    // from cfmakeraw documentation
    new.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
    new.c_oflag &= ~OPOST;
    new.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
    new.c_cflag &= ~(CSIZE | PARENB);
    new.c_cflag |= CS8;

    ioctl(0, TCSETS, &new);

    while (1) {
        if (getch() == 0x1b && getch() == 0x4f && getch() == 0x50) {
            break;
        }
    }

    write(1, "Got F1!\n", 8);
    ioctl(0, TCSETS, &orig);    // restore original settings before exiting!
    return 0;
}

我基于这个这个答案,这非常有帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Linux 上使用系统调用等待按键中断? 的相关文章

  • LC3 LEA指令和存储的值

    我对这个问题感到困惑 指令后寄存器0中存储的值是多少 LEA R0 A 被处决了吗 为什么答案是x370C 我认为应该将A的地址加载到R0中 如果是这样我们怎么知道地址 有人可以帮忙吗 非常感谢 ORIG X3700 LEA R0 A LD
  • 仅打印“docker-container ls -la”输出中的“Names”列

    发出时docker container ls la命令 输出如下所示 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a67f0c2b1769 busybox tail f dev
  • 如何在 Linux 中编写文本模式 GUI? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 当我编写脚本 程序时 我经常想弹出一个简单的文本 gui 来提示输入 我该怎么做 例如 来自 Shel
  • 长多字节 NOP:通常理解的宏或其他符号

    x86 和 x86 64 处理器不仅具有单字节 这不是什么大秘密NOP指令 还包括各种类型的多字节类 NOP 指令 这些是我设法找到的 AMD 推荐 参考 AMD 系列 15h 处理器的 AMD 软件优化指南 文档 47414 http s
  • gdb查找行号的内存地址

    假设我已将 gdb 附加到一个进程 并且在其内存布局中有一个文件和行号 我想要其内存地址 如何获取文件x中第n行的内存地址 这是在 Linux x86 上 gdb info line test c 56 Line 56 of test c
  • 从类模板参数为 asm 生成唯一的字符串文字

    我有一个非常特殊的情况 我需要为类模板中声明的变量生成唯一的汇编程序名称 我需要该名称对于类模板的每个实例都是唯一的 并且我需要将其传递给asm关键字 see here https gcc gnu org onlinedocs gcc 12
  • 从 Python 调用 PARI/GP

    我想打电话PARI GP http pari math u bordeaux fr dochtml gpman html仅从Python计算函数nextprime n 对于不同的n是我定义的 不幸的是我无法得到帕里蟒蛇 http code
  • Linux中的定时器类

    我需要一个计时器来以相对较低的分辨率执行回调 在 Linux 中实现此类 C 计时器类的最佳方法是什么 有我可以使用的库吗 如果您在框架 Glib Qt Wx 内编写 那么您已经拥有一个具有定时回调功能的事件循环 我认为情况并非如此 如果您
  • 无法使用 wget 在 CentOS 机器上安装 oracle jdk

    我想在CentOS上安装oracle java jdk 8 我无法安装 java jdk 因为当我尝试使用命令安装 java jdk 时 root ADARSH PROD1 wget no cookies no check certific
  • 32 位到 64 位内联汇编移植

    我有一段 C 代码 在 GNU Linux 环境下用 g 编译 它加载一个函数指针 它如何执行并不重要 使用一些内联汇编将一些参数推送到堆栈上 然后调用该函数 代码如下 unsigned long stack 1 23 33 43 save
  • 两种情况或 if 哪个更快? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我必须制作一个 非常 轻的脚本 它将接受用户的选项并调用脚本中的函数来执行一些任务 现在我可以使用 IF 和 CASE 选项 但我想知道两
  • PHP 从命令行启动 gui 程序,但 apache 不启动

    首先 我阅读了有类似问题的人的一些帖子 但所有答案都没有超出导出 DISPLAY 0 0 和 xauth cookies 这是我的问题 提前感谢您的宝贵时间 我开发了一个小库 它使用 OpenGL 和 GLSL 渲染货架 过去几天我将它包装
  • 如何将目录及其子目录中的所有 PDF 文件复制到一个位置?

    如何全部复制PDF文件从目录及其子目录到单个目录 实际上还有更多的文件 并且深度有些任意 假设四个目录的最大深度是公平的 我想这些文件需要重命名 如果a pdf例如 位于多个目录中 因为我会adding https ebooks stack
  • C#驱动开发?

    在我一头扎进 C 之前 我一直认为 C 或 C 最适合在 Windows 上开发驱动程序 我不喜欢在 NET 机器上开发驱动程序的想法 但 NET 似乎是 MS 应用程序开发的方向 所以我现在想知道 人们正在使用 C 来开发驱动程序吗 您是
  • CentOS:无法安装 Chromium 浏览器

    我正在尝试在 centOS 6 i 中安装 chromium 以 root 用户身份运行以下命令 cd etc yum repos d wget http repos fedorapeople org repos spot chromium
  • NPTL 和 POSIX 线程有什么区别?

    NPTL 和 POSIX 线程之间的基本区别是什么 这两者是如何演变的 POSIX 线程 pthread 不是一个实现 它是几个函数的 API 规范 纸上的标准 英文 其名称以pthread 以及定义在
  • 安装J语言的JQt IDE,出现错误

    我一直按照这里的说明进行操作 http code jsoftware com wiki System Installation Linux http code jsoftware com wiki System Installation L
  • 如何在shell中输出返回码?

    我正在尝试通过调用自定义 shell 脚本sh bin sh c myscript sh gt log txt 2 gt 1 echo 该命令的输出是创建的后台进程的 PID 我想指导 bin sh保存返回码myscript sh到某个文件
  • 在 Linux 上使用多处理时,TKinter 窗口不会出现

    我想生成另一个进程来异步显示错误消息 同时应用程序的其余部分继续 我正在使用multiprocessingPython 2 6 中的模块来创建进程 我试图用以下命令显示窗口TKinter 这段代码在Windows上运行良好 但在Linux上
  • 汇编器8086将32位数字除以16位数字

    我尝试将 32 位数字除以 16 位数字 例如 10000000h 除以 2000h 根据我尝试做的设计除以 右 4 位数字除以除数 然后左 4 位数字除以除数 这是我的代码 DATA num dd 10000000h divisor dw

随机推荐

  • PCIe 总线上的写入是原子的吗?

    我是 PCIe 的新手 所以这可能是一个愚蠢的问题 这似乎是询问有关 PCIe 接口的相当基本的信息 但我无法找到答案 因此我猜测我缺少一些使答案显而易见的信息 我有一个系统 其中有一个 ARM 处理器 主机 通过 PCIe 设备 与 Xi
  • 在 C# 中读取 Excel 文件时出现问题

    我正在使用此代码读取带有 OLEDB 连接的 Excel 文件 var connectionString string Format Provider Microsoft Jet OLEDB 4 0 data source 0 Extend
  • 获取聚合中嵌套数组的总和

    好吧 我有一个似乎无法解决的问题 我有一个这样的文档 playerId 43345jhiuy3498jh4358yu345j leaderboardId 5b165ca15399c020e3f17a75 data type Eclectic
  • .NET 安装包有时无法完全删除以前的版本

    我使用 VS2008 安装包分发我的应用程序 通常效果很好 当我创建应用程序的新版本时 我会进入并增加Version安装包上的属性并验证RemovePreviousVersions属性设置为 True 这在大多数情况下都工作得很好 我只是运
  • 将位图保存到 MemoryStream 时发生 GDI+ 异常

    我在 Windows 窗体应用程序中遇到问题 当我保存到 MemoryStream 时 Bitmap Save 失败 该问题似乎只间歇性地发生在一台机器上 到目前为止 而坏消息是在客户站点上 我无法在机器上进行调试 但我得到了堆栈跟踪 将问
  • Android NDK 和渲染到动态壁纸

    我只是在寻找开始学习 NDK 的机会 并考虑到一个特定的项目 我想从 NDK 端不断渲染变化的位图 以便能够在动态壁纸中显示它 因此我在这里讨论的不是渲染到 OpenGL 纹理 而是渲染到位图 我用谷歌搜索了一下 发现有一个选项可以直接操作
  • 如何在 ES6 类中创建“公共静态字段”?

    我正在创建一个 Javascript 类 我想要一个像 Java 中那样的公共静态字段 这是相关代码 export default class Agent CIRCLE 1 SQUARE 2 这是我得到的错误 line 2 col 11 C
  • XPath 中 .// 和 //* 有什么区别?

    通过 Firebug 查找相对 XPath 时 它会创建类似 id Passwd 如果我们在开头不使用点它的含义会怎么样 只需添加 在 Xpath 中 它突出显示 各种页面元素 代表什么 以下是 Gmail 密码字段的 XPath 有什么意
  • 如何使用 Retrofit 2.0 解析 XML 响应?

    您好 我是 Android 编程新手 我已经浏览了一些有关如何使用改造解析 XML 响应的链接 并且我尝试了下面的 XML 如图所示 我需要在 POJO 类中做任何必要的更改吗 但我在 Logcat 中收到 NullPointer 异常 当
  • NullPointerException 使用模拟上下文创建 AppCompatImageView

    我收到了NullPointerException当我尝试创建一个AppCompatImageView带着嘲笑Context在测试中 与正常人做同样的事情ImageView works 本次测试通过 import android conten
  • 在 Azure Front Door 后面设置多个 Web 应用程序的正确方法是什么?

    我有 3 个后端池 1 个是 API 2 个是 Web 应用程序 我已在 Azure Front Door 中设置路由以路由到正确的区域 但如何修改 Web 应用程序以对所有链接使用 Front Door URL 而无需手动对它们进行硬编码
  • C++“命名空间范围”

    C 规范 http www open std org jtc1 sc22 wg21 docs papers 2011 n3242 pdf 第 7 5 4 节 指出 链接规范只能出现在名称空间范围内 命名空间范围 到底是什么意思 这是否意味着
  • 在容器外部定义 jta 数据源

    我们的应用程序当前使用在 JBossstandalone xml 中定义的数据源 基本上我们需要在应用程序中而不是在容器中定义它一段时间 我们当前的设置是 应用程序上下文 xml
  • 如何使用 scanf \ fscanf 读取一行并解析为变量?

    我正在尝试读取每行使用以下格式构建的文本文件 字符 字符 整数 i e 啊啊啊 dfdsd 23 bbbasdaa ddd 100 我想使用 fscanf 从文件中读取一行 并自动将该行解析为变量 string1 string2 intA
  • 更改已编译可执行文件的 .NET Framework 目标

    由于 Windows 8 默认情况下不包含 NET 2 3 5 我想将一些 NET 2 0 编译的可执行文件转换为 NET 4 5 而无需使用 VS 2012 重新编译它们 是否有用于此任务的实用程序 您只需创建或修改 app config
  • 带有图像和文本的 HTML 标题 - 将文本与底部对齐?

    我正在用 CSS 编写 HTML 页面 在页面顶部 我想显示带有图像和文本的标题 图像位于文本左侧 图像大小为 64 x 64 像素 我希望文本较大 除了我想将文本对齐在底部之外 我几乎可以做所有事情 但是 无论我做什么 我似乎都无法让文本
  • SQL Server - 仅将字段内容过滤为数字

    如何复制字段的值 但仅复制其数字 我正在创建一个用于全文搜索的计算列 并且我想将电话号码字段 为 varchar 中的值复制到其中 但不使用其格式 仅数字 在我的计算列公式中执行此操作的命令是什么 谢谢你 您将必须编写一个用户定义的函数来执
  • 如何向 clang-format 添加功能?

    Clang 有助于让每个人诚实地了解公司的编码标准 但它并不能完全覆盖所有情况 并且会做出 IMO 错误的选择 而不是忽略某些情况 例如 来自另一篇有类似问题的帖子 z1 sqrt x x y y 被 clang format 破坏 成 z
  • 如何在 iOS Objective-c 的 UICollectionView 中创建无限滚动

    如何在我的应用程序中创建无限滚动UICollectionView 附截图 Now my NSArray is NSArray nameArr NSArray arrayWithObjects 0 1 2 3 4 nil 我想在完成数组后在
  • 如何在 Linux 上使用系统调用等待按键中断?

    我希望当用户在我的程序中按下特殊按键 如 F1 12 时接收中断 该程序是用 nasm 编写的 我只需要在主函数开始时等待函数按键即可 我知道这可以通过 BIOS 实现int 16h 它返回一个扫描码 我怎样才能在Linux下做到这一点 所