我得到了一些代码来分析。此代码在键盘上启用numLock和scrollLock LED。我理解这个代码的大部分,但是我不理解循环部分(0104)。我所知道的是等待输入缓冲区为空。但这有必要吗?没有这部分,代码运行良好。
0100: MOV AL, ED
0102: OUT 60, AL
0104: IN AL, 64
0106: TEST AL, 02
0108: JNZ 0104
010A: MOV AL, 03
010C: OUT 60, AL
发布于 2019-06-10 15:29:14
有关于AT键盘控制器良好的信息在这里。在端口0x60上读取和写入数据时,您可能最感兴趣的状态寄存器(端口0x64)中的位是:
位1:输入缓冲区状态 0:输入缓冲区为空,可以写入。1:输入缓冲区已满,请勿写入。 位0:输出缓冲器状态 0:输出缓冲区为空,请勿读取。1:输出缓冲区满,可以读取。(在PS / 2情况下,位5指示可用数据是来自键盘还是鼠标。)读取端口0x60时,该位清零。
在写入端口0x60之前,必须等到输入缓冲区状态位清零。无法等待可能导致发送到控制器的数据丢失。在从端口0x60读取数据之前,您应该等到输出缓冲区状态位置1,因为这意味着有读取数据。读取不可用的数据将导致从端口读取的任何内容在完全不是数据时被视为数据。
状态寄存器中的输入和输出这些术语乍一看似乎是违反直觉的。这些位的名称来自键盘控制器,而不是PC。控制器上的输出缓冲区是PC上的输入缓冲区,反之亦然。
仿真器和虚拟机似乎更加宽容。如果您希望代码最有可能处理各种真实硬件和仿真器,则需要在继续之前插入等待适当状态的循环。
代码的第一部分将0xED命令1发送到键盘:
0100: MOV AL, ED
0102: OUT 60, AL
此命令记录为:
命令0xED:写入LED 该命令后跟一个表示所需LED设置的字节。位7-3:未使用,0位2:1:CapsLock LED亮起。位1:1:NumLock LED亮起。位0:1:ScrollLock LED亮起。好的时候,两个字节都被确认。如果第二个字节被识别为命令,则该命令被确认并完成。否则返回NACK(并且可能需要键盘启用)。
这部分代码正在等待第1位(输出缓冲区状态)变为0:
0104 IN AL, 64
0106: TEST AL, 02
0108: JNZ 0104
当键盘控制器准备好接收数据时,PC可以自由地将数据写入端口0x60,这就是这段代码的作用:
010A: MOV AL, 03
010C: OUT 60, AL
这是与命令0xED相关联的LED数据。值03 = 00000011。第1位设置为启用NumLock,第1位设置为启用ScrollLock。
https://stackoverflow.com/questions/-100006970
复制相似问题