我希望在我的nasm程序中,当用户按下像F1-12这样的特殊按键时,能够接收到一个中断。我只需要在我的主函数开头等待一个功能按键即可。我知道在BIOS中可以使用int 16h
来实现,并返回一个扫描码。但是在Linux下该怎么做呢?
我希望在我的nasm程序中,当用户按下像F1-12这样的特殊按键时,能够接收到一个中断。我只需要在我的主函数开头等待一个功能按键即可。我知道在BIOS中可以使用int 16h
来实现,并返回一个扫描码。但是在Linux下该怎么做呢?
#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;
}
read()
上旋转,使用阻塞式的read
即可!这里只有原始部分是一个好主意。如果你有一个游戏循环,在每一帧或模拟步骤中想要检查按键,那么是的,你需要非阻塞(或使用select
),但这只是一个没有理由的巨大的CPU时间浪费。(就像你的汇编版本的答案一样,你不需要2个ioctl
系统调用,只需执行new = orig
,然后修改它即可。) - Peter Cordesfcntl(0, F_SETFL, O_NONBLOCK)
来使 stdin 非阻塞,因此 read(2)
会一直阻塞,直到有按键输入。编辑以删除答案文本中的错误建议。 - Peter Cordes