如何为汇编语言编写的菜单实现鼠标点击选择功能?
实现鼠标点击菜单选项的汇编逻辑方案
问题背景
你已编写DOS环境下的菜单数据段,需求是实现鼠标点击1-6选项的交互,点击对应选项后触发后续输入请求,当前核心瓶颈为鼠标交互逻辑的构建。
你的现有菜单代码(已修正语法错误):
data segment menu db "Please select a choice:" db "1. J",13,10 db "2. C",13,10 db "3. G",13,10 db "4. T" ,13,10 db "5. C",13,10 db "6. E",13,10,'$' ends
核心实现步骤
1. 初始化鼠标驱动
DOS下通过INT 33H功能0初始化鼠标,同时检测系统是否支持鼠标:
mov ax, 0000h int 33h ; AX返回状态:1=支持鼠标,0=不支持 cmp ax, 0 je no_mouse ; 无鼠标支持的降级处理分支(比如提示用键盘选择)
2. 显示菜单并标记选项坐标
默认VGA 80x25文本模式下,每个字符占8×16像素,假设菜单从第2行(行号从0开始)、第0列开始显示:
- "1. J" 对应行3,列0-3
- "2. C" 对应行4,列0-3
- 以此类推,每个选项独占一行,列范围固定为0-3
先调用DOS中断显示菜单:
mov ah, 09h lea dx, menu int 21h ; 输出字符串到屏幕
3. 循环检测鼠标左键点击
用INT 33H功能3实时获取鼠标状态与坐标,循环等待左键按下:
mouse_loop: mov ax, 0003h int 33h ; BX=按键状态(bit0置1表示左键按下),CX=X像素坐标,DX=Y像素坐标 test bx, 0001h ; 检测左键是否触发 jz mouse_loop ; 未点击则继续循环 ; 将像素坐标转换为文本模式的行列号 mov ax, cx ; CX是X像素坐标,转列号(每个字符宽8像素) mov bl, 8 div bl ; AL=列号,AH=剩余像素(可忽略) mov col, al mov ax, dx ; DX是Y像素坐标,转行号(每个字符高16像素) mov bl, 16 div bl ; AL=行号,AH=剩余像素(可忽略) mov row, al
4. 判断点击的目标选项
根据转换后的行号匹配对应选项:
cmp row, 3 je option_1 ; 匹配"1. J" cmp row, 4 je option_2 ; 匹配"2. C" cmp row, 5 je option_3 ; 匹配"3. G" cmp row, 6 je option_4 ; 匹配"4. T" cmp row, 7 je option_5 ; 匹配"5. C" cmp row, 8 je option_6 ; 匹配"6. E" jmp mouse_loop ; 未点中选项,回到循环等待下一次点击
5. 处理选中选项的后续逻辑
以选项1为例,实现点击后的输入请求流程:
option_1: ; 清除鼠标按键状态,避免重复触发 mov ax, 0000h int 33h ; 提示用户输入 mov ah, 09h lea dx, input_prompt int 21h ; 读取用户输入(使用DOS 0AH中断) mov ah, 0Ah lea dx, input_buf int 21h ; 此处编写输入后的业务处理逻辑 jmp mouse_loop ; 处理完成后回到菜单循环 ; option_2到option_6可参照上述逻辑实现
6. 补充数据段定义
需在data段中添加输入提示与缓冲区:
data segment menu db "Please select a choice:" db "1. J",13,10 db "2. C",13,10 db "3. G",13,10 db "4. T" ,13,10 db "5. C",13,10 db "6. E",13,10,'$' input_prompt db 13,10,"Enter your input: $" input_buf db 20,0,20 dup(0) ; 最多接收19个字符的输入缓冲区 row db ? col db ? ends
关键注意事项
- 坐标转换需匹配实际使用的文本模式(如CGA为8×8像素,需调整除数)
- 处理完选项后必须重置鼠标状态,防止单次点击触发多次响应
- 需保留无鼠标支持的降级方案,保证兼容性
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

