如何在Assembly中检查CapsLock状态

1 assembly capslock emu8086

我尝试了 BIOS 中断 INT 16h, 02h,但 Emu8086 不支持它。有人可以教我如何直接获取内存位置 0:0417h 或其他支持 BIOS 中断 16h 02h 的汇编器上的 Capslock 状态吗?我已经尝试过 MASM,但进展不顺利。抱歉我的英语不好

fuz*_*fuz 6

大写锁定键的状态可以在地址 处的键盘状态字的40h中找到0040:0017。要访问该位,首先将 BDA 段加载到段寄存器中,然后使用该段寄存器访问内存。语法应该类似于:

        mov     ax, 40h                 ; load segment into AX
        mov     es, ax                  ; so we can move it into ES
        test    byte ptr es:[17h], 40h  ; is caps-lock depressed?
        jnz     caps_pressed

caps_not_pressed:
        ...

caps_pressed:
        ...
Run Code Online (Sandbox Code Playgroud)

  • 更黑客的代码大小优化: `mov bx, 40h` / `mov es, bx` / `test es:[bx-40h+17h], bl` 使用 `[bx+disp8]` 寻址模式 (1额外字节)而不是“[disp16]”(2 个额外字节)。显然,这不太直观,也不太可读,并且只有在您想同时使用该技巧的两部分时才适用于 BX。其他 16 位寻址寄存器(BP、SI、DI)的低字节不能用作部分寄存器,64 位模式除外。 (3认同)
  • 这允许有趣的代码大小优化:“test es:[17h], al”,因为该段与位掩码相同。(顺便说一句,您需要一个带有立即操作数的“byte ptr”。) (2认同)
  • @PeterCordes 谢谢你。我尽力使代码示例尽可能易于理解,因此我避免了这样的恶作剧。 (2认同)
  • 也许我的第一条评论具有误导性。我的意思是:当你有一条带有立即操作数(和内存目标)的指令时,你需要在内存操作数上有一个“byte ptr”。我可以看到它如何被误读为暗示“byte ptr 40h”,但幸运的是,为了我们的理智,MASM 风格的语法要求(我认为)“size ptr”关键字位于内存操作数上。现在看来,这对我来说是正确的。我认为 `[]` 之外的 `es:` 是 MASM / TASM 语法需要段覆盖的地方。 (2认同)