assembly 组件8086中的键盘输入

7jmck4yq  于 2023-01-13  发布在  其他
关注(0)|答案(4)|浏览(252)

我尝试在程序集8086中创建一个动画,由键盘控制,使用ctrl和shift作为左右键。
我试着看看如何在8086中接收键盘的输入,以及如何找出按下的键是Ctrl还是Shift(一般来说,按下的是哪个键)。
非常感谢!

gijlo24d

gijlo24d1#

你确定你不想用箭头键来左右移动吗?control和shift的问题是它们不会“返回”一个键,而是修改另一个被按下的键。这是在键盘中断处理程序中处理的(9,国际红十字会),你可以“钩住”它。我想在“BIOS数据区”中查找会更容易并观察中断处理程序跟踪控制键和Shift键状态的位置。在我看来,BDA在40h段。键盘状态标志在... 17h和18h?不要相信我的话,因为这些偏移,查一下。拉尔夫·布朗的中断列表。这一切都假设“8086”的意思是,像...古董。:)

nwlqm0z1

nwlqm0z12#

假设您只在BIOS下执行此操作,您可能会发现使用更高级别的BIOS键盘中断更容易-int 0x16 AH=0x01用于一般击键,int 0x16 AH=0x02用于ctrl/shift等。尽管存在许多其它可能性(包括其它INT 0x 16命令和如先前所建议的低级键盘int 0x 09和bios数据区。。我强烈支持Ralf Brown's Interrupt List的推荐-一个极好的资源!

w1e3prcc

w1e3prcc3#

Bios将键存储在一个16个字母的缓冲区中。这意味着如果一个os太慢,每当它读到下一个键击时,它就会从缓冲区中读取。
您可以使用int 16h并将ah设置为02h来将al设置为缓冲区中的下一个字符。但是,如果您要检查缓冲区的状态(是否有键),请查看this.,它基本上深入到ah 02h
既然你问的是箭头键,下面是它们的十六进制代码:

  1. U 0x18
    1.第0x19天
  2. L 0x1B
  3. R 0x1A
s6fujrry

s6fujrry4#

控制移动的常用方法是使用键盘上的箭头键。Shift、Ctrl和Alt键通常用作操作键:想想射击、跳跃、使用小工具等动作。

使用箭头键

在你的主循环中,你检查是否有击键可用。BIOS有CheckKeystroke function 01h用于此。如果它返回零标志集(ZF=1)则没有键等待,你可以继续循环。但是如果零标志被清除(ZF=0),则密钥(至少一个)正在BIOS维护的键盘缓冲区中等待。您必须从缓冲区中删除这个键。如果您没有删除,缓冲区将迅速填充到其最大15个键,您可能会失去对程序的控制。BIOS具有GetKeystroke function 00h以从缓冲区中获取最旧的键,在AL寄存器中返回其ASCII码,在AH寄存器中返回其扫描码。(如果缓冲区为空,此函数将等待按键,但在我们的情况下,这不会发生,因为我们事先检查了按键的可用性)。
我们感兴趣的箭头键由AH寄存器中的扫描码标识:向上= 48 h,向左= 4 Bh,向右=4Dh,向下= 50 h。

使用修饰键

在主循环中,你向BIOS请求键盘标志。如果你不需要区分Left-Ctrl,Left-Alt,Right-Alt,Right-Ctrl键,那么你可以使用BIOS GetKeyboardFlags function 02h,它会在AL寄存器中返回以下项目:

76543210
.......1  Right shift key is depressed
......1.  Left shift key is depressed
.....1..  Either ctrl key is depressed
....1...  Either alt is depressed
...1....  Scroll lock is enabled
..1.....  Num lock is enabled
.1......  Caps lock is enabled
1.......  Insert key is enabled

如果您确实需要区分Left-Ctrl、Left-Alt、Right-Alt、Right-Ctrl键,则可以使用BIOS GetKeyboardFlags function 12h,该BIOS在AH寄存器中返回以下项目:

76543210
.......1  Left ctrl key is depressed
......1.  Left alt key is depressed
.....1..  Right ctrl key is depressed
....1...  Right alt is depressed
...1....  Scroll lock is depressed
..1.....  Num lock is depressed
.1......  Caps lock is depressed
1.......  SysRq key is depressed (Acer reports Insert key)

包含的演示程序显示了一个浮在屏幕底部附近的桨从左到右来回移动。
如果启用了 UseArrows(非零),则按下左箭头或右箭头将更改焊盘的方向。
如果启用了 UseShifts(非零),则按下左移或右移将更改开关的方向。
您可以同时启用 UseArrows 和 * UseShift *。
按Esc键停止程序。

ORG  256              ; Assembled with FASM
  UseShifts = 0
  UseArrows = 1

  mov  ax, 0003h        ; BIOS.SetVideoMode 80x25 text
  int  10h
  mov  dx, 1724h        ; DX is position (36,23)
  xor  bx, bx

MainEx:
  mov  cx, bx           ; CX is direction [-1=Left,0=Right]
Main:
  call Delay

  jcxz .Right
.Left:
  cmp  dl, 2            ; Left border
  ja   .Move
  jmp  .Turn
.Right:
  cmp  dl, 72           ; Right border
  jb   .Move
.Turn:
  not  cx               ; -> CX is new direction
.Move:
  call MovePaddle       ; -> DX is new position
  call MovePaddle       ; -> DX is new position

  IF UseShifts
    mov  ah, 02h          ; BIOS.GetKeyboardFlags
    int  16h              ; -> AL
    test al, 00000011b
    jz   .Neither
    xor  bx, bx
    test al, 00000001b
    jnz  MainEx           ; Set direction=0 on <RIGHT-SHIFT>
    not  bx
    jmp  MainEx           ; Set direction=-1 on <LEFT-SHIFT>
  .Neither:
  END IF

  mov  ah, 01h          ; BIOS.CheckKeystroke
  int  16h              ; -> AX ZF
  jz   Main             ; No key available
  mov  ah, 00h          ; BIOS.GetKeystroke
  int  16h              ; -> AX
  IF UseArrows
    xor  bx, bx
    cmp  ah, 4Dh
    je   MainEx           ; Set direction=0 on <RIGHT-ARROW>
    not  bx
    cmp  ah, 4Bh
    je   MainEx           ; Set direction=-1 on <LEFT-ARROW>
  END IF
  cmp  al, 27
  jne  Main             ; Ignore all other keys except <ESC>
Exit:
  int  20h              ; DOS.TerminateProgram
; ----------------------
; IN () OUT ()
Delay:
  push ds ax
  xor  ax, ax
  mov  ds, ax
  mov  ax, [046Ch]      ; BIOS.TimerTick
.Again:
  cmp  ax, [046Ch]
  je   .Again           ; TimerTick didn't change
  pop  ax ds
  ret
; ----------------------
; IN (cx,dx) OUT (dx)
MovePaddle:
  push ax bx cx
  mov  ax, 0001h        ; Move right .. Wipe at +0, Draw at +1
  jcxz .Wipe
  mov  ax, 05FAh        ; Move left  .. Wipe at +5, Draw at -6
.Wipe:
  push ax               ; (1)
  add  dl, ah           ; AH is {0,5}
  mov  bx, 0007h        ; BH is DisplayPage, BL is Attribute
  mov  ah, 02h          ; BIOS.SetCursorPosition
  int  10h
  mov  cx, 1            ; ReplicationCount (PaddleStep)
  mov  ax, 0920h        ; BIOS.WriteCharacterAndAttribute, AL is Space
  int  10h
.Draw:
  pop  ax               ; (1)
  add  dl, al           ; AL is {1,-6}
  mov  ah, 02h          ; BIOS.SetCursorPosition
  int  10h
  mov  cx, 6            ; ReplicationCount (PaddleLength)
  mov  bl, 0Eh          ; BL is Attribute
  mov  ax, 09DCh        ; BIOS.WriteCharacterAndAttribute, AL is HalfBlock
  int  10h
  pop  cx bx ax
  ret
; ----------------------

相关问题