左键单击 Text Assembly x86

问题描述 投票:0回答:1

我目前正在开发一个项目,我应该向用户显示一个菜单,以便他可以与其交互,并且我正在使用带有 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.
assembly mouse emu8086
1个回答
0
投票

假设已安装鼠标

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
© www.soinside.com 2019 - 2024. All rights reserved.