Assembly TASM中的虚拟键盘 我知道这是一个很长的拍摄,但我陷入了一个学校组装项目的中间,而我对编程很陌生,我很难在代码中找到问题。

Assembly TASM中的虚拟键盘 我知道这是一个很长的拍摄,但我陷入了一个学校组装项目的中间,而我对编程很陌生,我很难在代码中找到问题。,assembly,x86-16,tasm,dosbox,Assembly,X86 16,Tasm,Dosbox,我正在尝试制作一个虚拟(屏幕上)键盘。每个按钮的位置值在两个数组中找到,一个用于按钮中心的X值,另一个用于Y 示例阵列键盘的顶行: x_arr dw 13,37,61,85,109,133,157,181,205,229 y_arr dw 113,113,113,113,113,113,113,113,113,113 计算机等待用户单击鼠标,并使用算法查找是否按下了按钮或按下了哪个按钮,然后将该按钮与每个字母的ascii值数组相匹配: letter_arr db 81,87,68,82,84,

我正在尝试制作一个虚拟(屏幕上)键盘。每个按钮的位置值在两个数组中找到,一个用于按钮中心的X值,另一个用于Y

示例阵列键盘的顶行:

x_arr dw 13,37,61,85,109,133,157,181,205,229
y_arr dw 113,113,113,113,113,113,113,113,113,113
计算机等待用户单击鼠标,并使用算法查找是否按下了按钮或按下了哪个按钮,然后将该按钮与每个字母的ascii值数组相匹配:

letter_arr db 81,87,68,82,84,89,85,73,79,80 ;QWERTYUIOP
我的程序似乎不起作用。我将添加完整的代码和键盘本身的图片

如果有点乱,对不起。提前谢谢

这是您的主程序循环。因为它们是过程,所以人们希望getMouseClick、checkMouseButton、checkX和checkY在
调用下的指令处返回

只有getMouseClick的行为类似于下降过程

但是:

a。checkMouseButton跳回mouseLoop和doLoop。
BcheckX跳回mouseLoop,甚至认为它弹出了
CX
,实际上它正在弹出返回地址
CcheckY跳回mouselop和writeler

这些跳转都不会从堆栈中删除返回地址和被推送的
CX

你需要重新考虑这个问题



您知道,
loop
已经递减
CX
寄存器。为什么要有单独的
dec cx
说明?

请将您的代码作为代码包含在代码部分中。还包括带有图像按钮的图像。编码风格建议:使用ASCII字符文字而不是数字常量,这样就不需要注释了。e、 g.
letter\u arr db“QWERTYUIOP”
letter\u arr db“Q”、“W”、“e”可能更容易检查像素颜色,而不是location@Slai我如何区分每个按钮?没错,我没想到。可能颜色的深浅不同,但从屏幕截图上看,颜色范围可能不够大,以至于不明显。当程序准备返回堆栈上的顶部元素时,需要返回地址
ret
将为您弹出它。如果你在手术过程中推东西,你需要事先把它弹出。您的过程不应该像checkX那样尝试删除调用方在堆栈上推送的内容。因此,您是说跳过ret命令会使堆栈混乱?如果过程需要调用方在堆栈上放置一个值,您可以使用以下方法获取它:
proc checkX
push bp
mov bp,sp
mov cx[bp+4];CX推入鼠标操作
…一个混乱的堆栈。就是这样!
IDEAL
MODEL small
STACK 0f500h
;---------------
MAX_BMP_WIDTH = 320
MAX_BMP_HEIGHT = 200
SMALL_BMP_HEIGHT = 40
SMALL_BMP_WIDTH = 40

DATASEG

    ;------Image related data------
    OneBmpLine db MAX_BMP_WIDTH dup (0)  ;One Color line read buffer
    ScreenLineMax db MAX_BMP_WIDTH dup (0)  ;One Color line read buffer
    FileHandle dw ?
    Header db 54 dup(0)
    Palette db 400h dup (0)
    SmallPicName db 'keyboar1.bmp',0
    BmpFileErrorMsg db 'Error At Opening Bmp File .', 0dh, 0ah,'$'
    ErrorFile db 0
    BB db "BB..",'$'     
    BmpLeft dw ?
    BmpTop dw ?
    BmpColSize dw ?
    BmpRowSize dw ?
    ;-----Program related data-----
    mouse_click dw ?
    letter_arr db 81,87,68,82,84,89,85,73,79,80         ;array containing ascii values of letters
    x_arr dw 13,37,61,85,109,133,157,181,205,229        ;array containing x value of center of buttons representing letters in letter_arr
    y_arr dw 113,113,113,113,113,113,113,113,113,113    ;array containing y value of center of buttons representing letters in letter_arr
    mouse_last_button dw 0  ;holds the value of last mouse button clicked
    mouse_button dw 1       ;holds the value of mouse button clicked

CODESEG

;================PROCEDURES================
;-----------------
proc OpenShowBmp near
    push cx
    push bx
    call OpenBmpFile
    cmp [ErrorFile],1
    je @@ExitProc
    call ReadBmpHeader
    ; from  here assume bx is global param with file handle. 
    call ReadBmpPalette
    call CopyBmpPalette
    call ShowBMP 
    call CloseBmpFile
@@ExitProc:
    pop bx
    pop cx
    ret
endp OpenShowBmp    
;-----------------
proc OpenBmpFile    near                         
;input dx filename to open  
    mov ah, 3Dh
    xor al, al
    int 21h
    jc @@ErrorAtOpen
    mov [FileHandle], ax
    jmp @@ExitProc  
@@ErrorAtOpen:
    mov [ErrorFile],1
@@ExitProc: 
    ret
endp OpenBmpFile

proc CloseBmpFile near
    mov ah,3Eh
    mov bx, [FileHandle]
    int 21h
    ret
endp CloseBmpFile
;-----------------
proc ReadBmpHeader  near                    
; Read 54 bytes the Header  
    push cx
    push dx

    mov ah,3fh
    mov bx, [FileHandle]
    mov cx,54
    mov dx,offset Header
    int 21h

    pop dx
    pop cx
    ret
endp ReadBmpHeader
;-----------------
proc ReadBmpPalette near
; Read BMP file color palette, 256 colors * 4 bytes (400h)
; 4 bytes for each color BGR + null)            
    push cx
    push dx

    mov ah,3fh
    mov cx,400h
    mov dx,offset Palette
    int 21h

    pop dx
    pop cx

    ret
endp ReadBmpPalette
;-----------------
proc CopyBmpPalette near                    
; Will move out to screen memory the colors
; video ports are 3C8h for number of first color
; and 3C9h for all rest                                 
    push cx
    push dx

    mov si,offset Palette
    mov cx,256
    mov dx,3C8h
    mov al,0  ; black first                         
    out dx,al ;3C8h
    inc dx    ;3C9h
CopyNextColor:
    mov al,[si+2]       ; Red               
    shr al,2            ; divide by 4 Max (cos max is 63 and we have here max 255 ) (loosing color resolution).             
    out dx,al                       
    mov al,[si+1]       ; Green.                
    shr al,2            
    out dx,al                           
    mov al,[si]         ; Blue.             
    shr al,2            
    out dx,al                           
    add si,4            ; Point to next color.  (4 bytes for each color BGR + null)             

    loop CopyNextColor

    pop dx
    pop cx

    ret
endp CopyBmpPalette
;-----------------
proc ShowBMP 
; BMP graphics are saved upside-down.
; Read the graphic line by line (BmpRowSize lines in VGA format),
; displaying the lines from bottom to top.
    push cx

    mov ax, 0A000h
    mov es, ax

    mov cx,[BmpRowSize]

    mov ax,[BmpColSize] ; row size must dived by 4 so if it less we must calculate the extra padding bytes
    xor dx,dx
    mov si,4
    div si
    mov bp,dx

    mov dx,[BmpLeft]

@@NextLine:
    push cx
    push dx

    mov di,cx  ; Current Row at the small bmp (each time -1)
    add di,[BmpTop] ; add the Y on entire screen

    ; next 5 lines  di will be  = cx*320 + dx , point to the correct screen line
    mov cx,di
    shl cx,6
    shl di,8
    add di,cx
    add di,dx

    ; small Read one line
    mov ah,3fh
    mov cx,[BmpColSize]  
    add cx,bp  ; extra  bytes to each row must be divided by 4
    mov dx,offset ScreenLineMax
    int 21h
    ; Copy one line into video memory
    cld ; Clear direction flag, for movsb
    mov cx,[BmpColSize]  
    mov si,offset ScreenLineMax
    rep movsb ; Copy line to the screen

    pop dx
    pop cx

    loop @@NextLine

    pop cx
    ret
endp ShowBMP
;-----------------
proc setGraphic
    ;sets graphic mode
    mov ax, 13h
    int 10h
    ret
endp setGraphic
;-----------------
proc initMouse
    ;initializes mouse
    mov ax, 0
    int 33h ;resets mouse

    mov ax, 1
    int 33h ;shows pointer
    ret
endp initMouse
;-----------------
proc initImage
    ;imports keyboard bitmap
    mov [BmpLeft],0
    mov [BmpTop],0
    mov [BmpColSize], 320
    mov [BmpRowSize] ,200
    mov dx,offset SmallPicName
    call OpenShowBmp
    ret
endp initImage
;-----------------
proc getMouseClick
    mov ax, [mouse_button] ;stores te value of the last state of the mouse
    mov [mouse_last_button], ax

    mov ax, 03h
    int 33h ;gets mouse information

    mov [mouse_button], bx ;saves the click inforamtion
    shr cx, 1 ;halves the x position value since the interrupt returns double
    ret
endp getMouseClick
;-----------------
proc checkMouseButton
    mov ax, [mouse_button]      ;waits for the user to click left mouse button
    cmp ax, 1
    jne mouseLoop

    cmp ax, [mouse_last_button] ;if button pressed before is the same as the current one,
    jne mouseLoop               ;skip the letter printing
    jmp doLoop
    ret
endp checkMouseButton
;-----------------
proc checkX 
    mov ax,cx   ;saves the x value of the click for later
    pop cx  ;pops the current value of counter to cx
    push ax
    mov si, offset x_arr
    add si,cx
    mov ax, [si]    ;moves the value at x array at index number cx (counter) to ax

    ;add ax, 9  ;checks if the click was inside a button range on x axis (9 pixels left and right of the center)
    pop cx
    cmp cx, ax
    ja mouseLoop

    mov ax, [si]
    sub ax, 9
    cmp cx, ax
    jb mouseLoop
endp checkX
;-----------------
proc checkY
    mov si, offset y_arr
    add si,cx
    mov ax, [si]

    sub ax, 9   ;checks if the click was inside a button range on y axis (9 pixels above and below the center)
    cmp dx, ax
    jb mouseLoop

    mov ax, [si]
    add ax, 9
    cmp dx, ax
    ja writeLetter
    ret
endp checkY
;-----------------
proc printLetter
    mov si, offset letter_arr   ;prints the letter whose ascii value matches the x and y values found previously
    add si,cx
    mov dl, [si]
    mov ah, 2h
    int 21h
    ret
endp printLetter
;-----------------
;================PROCEDURES================

start:
    mov ax,@data
    mov ds,ax

    call setGraphic ;sets graphic mode
    call initMouse ;initializes mouse
    call initImage  ;displays keyboard image

    mov cx, 10 ;iterates over all of the buttons in the keyboard until one matches a clicks location
mouseLoop:
    push cx
    call getMouseClick
    call checkMouseButton
    call checkX
    call checkY
    pop cx
    dec cx
    loop mouseLoop

writeLetter:
    call printLetter

doLoop: 
    mov cx,10 
    jmp mouseLoop

exit:
    mov ax, 4c00h
    int 21h
END start
 mov cx, 10 ;iterates over all of the buttons in the keyboard until one matches a clicks location
mouseLoop:
 push cx
 call getMouseClick
 call checkMouseButton
 call checkX
 call checkY
 pop cx
 dec cx
 loop mouseLoop
writeLetter:
 call printLetter
doLoop: 
 mov cx,10 
 jmp mouseLoop
dec cx
loop mouseLoop