Bar*_*rak 5 keyboard x86 assembly
我看过以下主题。
我有兴趣通过 IN / OUT 指令联系键盘并设置各种模式,例如打开大写锁定 LED。到目前为止,我在这样做时遇到了问题。以下链接可能会有所帮助。
我尝试了各种组合,例如
mov al,0EDh ;ED command - Send LED bits. The next byte written to port 60h updates the LEDs on the keyboard.
out 60h,al ;out on port 60h
mov al,00000111b ;led status - all leds on. bits 3-7 = reserved(zero)
out 60h,al ;out on port 60h
Run Code Online (Sandbox Code Playgroud)
我将不胜感激任何帮助。谢谢。
编辑:正如我所说,使用端口 60h 不起作用我在网上搜索了 0040:0017 的用法。其中一个网站指出,第 5、6、7 位包含有关 LED 状态的数据
我尝试使用此代码:
mov al,es:[0017h]
or al,11100000b
mov es:[0017h],al
Run Code Online (Sandbox Code Playgroud)
它也不起作用。
我可能做错了,所以任何人都可以帮助我或向我发送打开所有 3 个 LED 的工作代码吗?
EDIT2:我在安装在 VM 上的 MS-DOS 上运行我的应用程序,代码运行良好。
我的问题是:我怎样才能让它在 MS-DOS 之外工作?
要从在 VM86 模式或保护模式下运行的任务访问 I/O 端口,您需要特殊权限。此特权可以通过以下方式获得:
当访问被拒绝时,会生成 GPF。
Linux 具有 iopl() 和 ioperm() 系统调用,允许具有 CAP_SYS_RAWIO 的进程获取这些权限。因此,在 Linux 上访问键盘 LED 可以这样完成:
#include <stdio.h>
#include <sys/io.h>
int main()
{
int ret;
ret = ioperm(0x60, 0xf, 1);
if (ret < 0) {
perror("ioperm");
return 1;
}
while (inb(0x64) & 0x2);
outb(0xed, 0x60);
while (inb(0x64) & 0x2);
outb(0x07, 0x60);
ioperm(0x60, 0xf, 0);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Windows NTVDM和Linuxosemu使用VM86模式来运行实模式DOS程序。当尝试进行不允许的 I/O 端口访问时,会生成 GPF,并且这些系统可以模拟(或不模拟)I/O 端口访问。osemu 有一个 -k 开关,可以绕过通常的 tty 层并直接访问键盘。使用这个开关你的第一个例子就可以工作了。
现在,要在 Windows 上执行相同的操作,可能需要从在环 0 上运行的驱动程序执行此操作。替代方案可能是使用允许环 3 进程访问 I/O 端口的驱动程序(非常不安全):例如,请参阅ioperm对于 cygwin。