我目前正在开发一个项目,我应该向用户显示一个菜单,以便他可以与其交互,并且我正在使用带有 emu8086 的虚拟机。我试图让当我单击菜单上的文本(例如“sair”选项(退出))时,它会退出到操作系统,从而关闭程序。我目前正在尝试编写该函数,但它似乎工作得并不艰难,它没有给我任何错误:
multi-segment executable file template.
data segment
votar db "Votar",13,10,"$"
gerir db "Gerir",13,10,"$"
creditos db "Creditos",13,10,"$"
sair db "Sair",13,10,"$"
teste db "Teste",13,10,"$"
votarX db 38
votarY db 04
gerirX db 38
gerirY db 08
creditosX db 38
creditosY db 12
sairX db 38
sairY db 16
clickX dw 00
clickY dw 00
ends
stack segment
dw 128 dup(0)
ends
code segment
start:
; set segment registers:
mov ax, data
mov ds, ax
mov es, ax
; wait for any key....
;mov ah, 1
;int 21h
;print Menu
call printVotar
call printGerir
call printCreditos
call printSair
call initMouse
waitForClick:
call buttonStatus
jnc waitForClick
call clickLocation
jmp waitForClick
mov ax, 4c00h ; exit to operating system.
int 21h
;****FUNCTIONS****
printf proc
mov ah,09h
int 21h
ret
endp
moveCursor proc
mov ah,02h
mov bh, 0
int 10h
ret
endp
printVotar proc
mov dl,votarX
mov dh,votarY
call moveCursor
mov dx,offset votar
call printf
ret
endp
printGerir proc
mov dl,gerirX
mov dh,gerirY
call moveCursor
mov dx,offset gerir
call printf
ret
endp
printCreditos proc
mov dl,creditosX
mov dh,creditosY
call moveCursor
mov dx,offset creditos
call printf
ret
endp
printSair proc
mov dl,sairX
mov dh,sairY
call moveCursor
mov dx,offset sair
call printf
ret
endp
initMouse proc
mov ax,00h
int 33h
cmp ax,0FFFFh
je showMouse
cmp ax,0000h
je hideMouse
ret
showMouse:
push ax
mov ax,01h
int 33h
pop ax
ret
hideMouse:
push ax
mov ax,02h
int 33h
pop ax
ret
endp
buttonStatus proc
mov ax,03h
int 33h
test bx,01h
jnz noClick
mov clickX,cx;X mouse position
mov clickY,dx;Y mouse position
ret
noClick:
ret
endp
clickLocation proc;Why not working?!
push cx
push dx
mov cx,clickX
mov dx,clickY
mov al,votarY
cmp dl,al
jne locationGerir
mov al,VotarX
cmp cl,al
jl locationGerir
add al,5
cmp cl,al
jg locationGerir
mov dx,offset teste
call printf
ret
locationGerir:
mov al,gerirY
cmp dl,al
jne locationCreditos
mov al,gerirX
cmp cl,al
jl locationCreditos
add al,5
cmp cl,al
jg locationCreditos
mov dx,offset teste
call printf
ret
locationCreditos:
mov al,creditosY
cmp dl,al
jne locationSair
mov al,creditosX
cmp cl,al
jl locationSair
add al,7
cmp cl,al
jg locationSair
mov dx,offset teste
call printf
ret
locationSair:
mov al,sairY
cmp dl,al
jne endLocation
mov al,sairX
cmp cl,al
jl endLocation
add al,5
cmp cl,al
jg endLocation
mov ax, 4c00h ; exit to operating system.
int 21h
endLocation:
pop dx
pop cx
ret
endp
ends
end start ; set entry point and stop the assembler.
test bx,01h
jnz noClick
正在做与您需要的相反!如果设置了 BX 的最低位,则意味着有 is 左键单击。
此外,该服务以图形方式返回鼠标位置,CX 范围为 0 到 639,DX 范围为 0 到 199。
因此,如果您在默认的 80x25 文本屏幕上工作,则需要将这些 CX 和 DX 数字转换为列和行值。只需除以 8 即可。
; IN () OUT (CF) MOD (ax,bx,cx,dx)
buttonStatus proc
mov ax, 03h
int 33h ; -> BX CX DX
test bx, 01h
jz noClick ; CF=0
mov ax, cx
mov cl, 3
shr ax, cl
mov clickX, ax ; Column mouse position
shr dx, cl
mov clickY, dx ; Row mouse position
stc
noClick:
ret
endp
clickLocation过程忘记删除压入堆栈的CX和DX值(以防打印“teste”),但它不起作用的主要原因是clickX和中的坐标clicky 与用于消息的列和行不符。
clickLocation proc;Why not working?!
push cx
push dx
mov cx, clickX
mov dx, clickY
cmp dl, votarY
jne locationGerir
mov al, VotarX
cmp cl, al
jb locationGerir
add al, 4 <<<< always 1 less than the number of characters
cmp cl, al
ja locationGerir
mov dx, offset teste
call printf
JMP endLocation <<<< can't be just RET
locationGerir:
...
endLocation:
pop dx
pop cx
ret
endp