Assembly 8086键盘移位标志始终返回0问题求助
Alright, let's break down why your shift/control/alt flags are stuck at 0 when using your custom int9h keylogger. This is a common pitfall when hooking the BIOS keyboard interrupt, and it almost always boils down to how you're interacting with the original BIOS int9h handler or maintaining the keyboard state byte.
Common Causes & Solutions
1. You're Not Calling the Original int9h Handler
The BIOS's native int9h interrupt does more than just read scan codes—it automatically updates the keyboard state byte located at 0040:0017h (this is where int16h ah=2 pulls its data from). If you've replaced int9h with your own code but never invoke the original handler, the BIOS never gets a chance to set those shift/control/alt bits.
Fix: Always call the original int9h handler at the end of your custom routine. Make sure to preserve all registers and flags properly first. Here's a quick assembly example:
; Assume you stored the original int9 vector in `old_int9` (far pointer) pushf ; Save flags to match int9's calling convention call far [old_int9] ; Let BIOS handle state updates and buffer management
2. You're Manually Handling Modifier Keys but Not Updating the State Byte
If you're catching shift/control/alt scan codes in your custom int9h and not updating the 0040:0017h byte yourself, those flags will never change. The original handler does this automatically, but if you're bypassing it for modifier keys, you have to replicate that logic.
Fix: Either let the original int9h handle modifier keys, or manually tweak the state byte:
- For pressed modifiers (e.g., left shift scan code
12h, right shift54h), set the corresponding bit in0040:0017h - For released modifiers (e.g., left shift release
92h, right shift releaseD4h), clear the bit
Example assembly snippet for left shift:
mov ax, 0040h mov es, ax ; Point ES to BIOS data segment cmp al, 12h ; Left shift pressed je set_left_shift cmp al, 92h ; Left shift released je clear_left_shift set_left_shift: or byte ptr es:[0017h], 01h ; Set bit 0 (left shift flag) jmp modifier_done clear_left_shift: and byte ptr es:[0017h], ~01h ; Clear bit 0 modifier_done:
3. Interrupt Vector Replacement Errors
If you didn't properly save the original int9h vector (using int 21h ah=35h), or you're calling the original handler with incorrect register/flag state, it might fail to update the state byte correctly.
Fix: Double-check your vector replacement code:
- Use
int 21h ah=35hto get the original int9 vector before overwriting it - When calling the original handler, ensure you push flags first (
pushf) to mimic a real interrupt call—this is critical for the BIOS handler to work as expected
Quick Tip
For toggle keys like Caps Lock or Num Lock, let the original int9h handle them entirely. These keys flip bits in a separate state byte (0040:0018h), and replicating that logic manually is easy to mess up.
内容的提问来源于stack exchange,提问作者Guy Rif

