8086汇编获取鼠标点击位置像素颜色值结果异常问题
故障根因
读取像素值错误的核心原因共2项,坐标校准逻辑本身无问题:
- 读像素操作未提前隐藏鼠标光标。
int 33h的光标显示功能会直接将光标图形写入当前显示显存,此时调用int 10h ah=0Dh读取到的是鼠标光标的像素值,而非预先绘制的色块颜色,这是该类场景下的最常见错误。 - 点击判定逻辑不严谨。现有逻辑仅判断
bx != 0就触发读操作,未专门校验左键按下状态,会将右键点击、驱动返回的异常状态误判为有效点击,读取到无关位置的像素值。
320水平分辨率下将鼠标返回的CX值逻辑右移1位的校准逻辑、DX值直接使用的逻辑都是正确的,不需要修改。
修复方法
- 修正点击判定逻辑,仅响应左键点击事件
- 调用读像素中断前先隐藏鼠标,避免光标像素干扰,读值完成后可按需重新显示光标
修正后的核心代码段如下:
proc playerTurn mov ax, 0h ;Reset mouse int 33h mov ax, 1h ;Display mouse to user int 33h click: mov ax, 3h ; 读取鼠标状态 int 33h test bx, 1 ; 校验左键是否按下(对应bx第0位为1) jz click ; 左键未按下则继续轮询 ;CX holds column coordinate, 0-629, must divide by 2 because graphic is 320 ;DX holds row coordinate 0-199 shr cx, 1 ; divide cx by 2 mov bh, 0 ; page number = 0 mov ax, 2h ; 调用鼠标中断隐藏光标,消除光标对像素的覆盖 int 33h mov ah, 0Dh ; get color from current CX DX and store value in AL int 10h mov ax, 1h ; 读完像素后重新显示鼠标,不影响后续交互 int 33h cmp randomNum, 49 je checkBlue cmp randomNum, 50 je checkGreen cmp randomNum, 51 je checkRed cmp randomNum, 52 je checkYellow jmp wrong checkBlue: cmp al, 69h jne wrong call pressBlue jmp endTurn checkGreen: cmp al, 79h jne wrong call pressGreen jmp endTurn checkRed: cmp al, 70h jne wrong call pressRed jmp endTurn checkYellow: cmp al, 74h jne wrong call pressYellow jmp endTurn wrong: mov dx, offset wrongColor mov ah, 09h int 21h endTurn: ret playerTurn endp
注意事项
- 代码中比对的颜色值
69h/79h/70h/74h只要和你实际绘制四个色块时使用的色值一致,就不需要调整,隐藏光标后即可读到正确的原始像素值。 - 所有直接读取显存、调用BIOS读像素接口的操作,都需要提前隐藏鼠标光标,只要光标处于显示状态,其覆盖区域的原始像素都会被临时替换为光标图形,读值必然出错。
内容的提问来源于stack exchange,提问作者dudex198
相关产品推荐
相关产品推荐

