正文

鼠标键盘监控{汇编代码,初学者}2007-10-05 13:37:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/lingdlz/29863.html

分享到:

;----------------------------------------------------------------------------------; 鼠标, 键盘和显示设备的汇编语言操作;; 在DOS系统或者命令行中运行 (在 win 下双击即可运行); 运行时跟踪鼠标的移动位置,捕获鼠标和键盘的击键情况; (*)当按下 [ESC] 键时程序退出,其它键,蜂鸣; (*)按下鼠标右键恢复初始显示方式,并发声; (*)按下鼠标左键仅产生噪音; (*)按下键盘上的 F1-F10 切换到不同的显示方式 .; ; 编译器: [MASM] [ 欢迎到群里下载:28011342 ]; (c) by 江南孤峰   Time: 2007--10--3   version: 1.0; **************************************************************************; **** 没有复杂的汇编语法,适合初学者完赏, 目前尚不完善,更新中……; **************************************************************************;---------------------------------------------------------------------------------- .model small ;----------------------------------------------------------------------------------.datamsgWin          db  'Mouse or Keyboard message show as follow: $'msgHlpStar      db  ' ================= INFOMATION ==================$'                db  '      * Press key [ESC] to exit                 $'                db  '      * Hit right mouse key to normal mode      $'                db  '      * Hit left mouse key to make sound        $'                db  '      * Press key F1-F10 to change show mode    $'                db  '  (c) by JiangNanGuFeng    Time: 2007 - 10 - 4  $'                db  '  Email: lingdlz@163.com     QQ: 403324669      $'   msgHlpEnd       db  ' ===============================================$'msgLineLen      dw  $-msgHlpEndwindowEdge      db  '**********************************************************$' msgMouseMove    db  'Mouse message : mouse move new pos: $'msgMouseLeft    db  'Mouse message : hit left key $'msgMouseRight   db  'Mouse message : hit right key $'msgKeyBd        db  'Keyboard message: hit key, code [$'msgStart        db  'Press any key to start ......$'msgEnd          db  'Press any key to exit ......$' showMode        db  03h,04h,06h,09h,0dh,0eh,0fh,10h,11h,13h,'$'begMode         dw  000fh       ; 最初的显示方式currentMode     dw  6           ; 当前显示方式索引值,初始值对应 begModemsgModePrompt   db  'Mode Info :$'msgMode         db  'AL=03 WIDTH=80 HIGHT=25 COLOR=16 MODE=text      $'                db  'AL=04 WIDTH=320 HIGHT=200 COLOR=4 MODE=graph    $'                db  'AL=06 WIDTH=640 HIGHT=200 COLOR=w/b MODE=text   $'                db  'AL=09 WIDTH=320 HIGHT=200 COLOR=16 MODE=graph\MC$'                db  'AL=0d WIDTH=320 HIGHT=200 COLOR=16 MODE=graph\EV$'                db  'AL=0e WIDTH=640 HIGHT=200 COLOR=16 MODE=graph\EV$'                db  'AL=0f WIDTH=640 HIGHT=350 COLOR=sig MODE=text\EV$'                db  'AL=10 WIDTH=640 HIGHT=350 COLOR=16 MODE=graph\EV$'                db  'AL=11 WIDTH=640 HIGHT=480 COLOR=w/b MODE=text   $'                db  'AL=13 WIDTH=320 HIGHT=200 COLOR=256 MODE=graph\E$';--------------------------------------------------------------------------------; msgMode 说明:AL 设置该显示方式时的调用参数; WIDTH/HIGHT 表示屏幕像素或者;               字符行列数; COLOR 表示颜色数, 其中w/b表示黑白,sig 单色;;               MODE: text 表示文本模式, graph 图形模式, MC: MCGA,E: EGA, V: VGA;-------------------------------------------------------------------------------- soundFreq       dw  31,61,122,144,419,817,840,911                dw  62,144,446,799,819,1104,1715,2411soundFreqSize   db  $-soundFreq ; 音符频率,键盘击键时发声 newLine         db  13,10,'$'savStat         dw  0       ; 保存鼠标击键情况savPosX         dw  22      ; 鼠标的X坐标, 22 是初始位置savPosY         dw  62      ; 鼠标的Y坐标, 62 是初始位置keyBdIn         dw  ?       ; 保存最新的键盘按键isScroll        db  0       ; 窗口是否需要上滚,0 否,1 是scroLine        db  ?       ; 窗口滚动时,卷入行的属性countColumn     db  ?       ; 当前显示方式的字符列数winTopRow       dw  0c08h   ; 窗口部分的最上边winBottomRow    dw  1408h   ; 窗口部分的最下边,[04]最后会改为字符列数 rlt_asc         db  10 dup(?)temp_asc        db  10 dup(?) ;----------------------------------------------------------------------------------.codemain    proc    farstar:   mov ax,@data    mov ds,ax    mov ax,begMode          ; 初始化显示方式    int 10h    call    InitScreen      ; 初始化屏幕    call    LocateScroll    ; 定位光标,或者滚动窗口    Lea dx,msgStart         ; 第一条消息    call    PrintStr    call    WaitHitKey      ; 等待用户按键  again:  call    CheckKeyBd  ; 检查鼠标消息,即是否有击键    cmp ax,4                ; 击键[ESC],退出程序    jz  mainOver    cmp ax,2                ; 显示方式切换    jnz testMouse    call    SwitchMode      ; 切换显示方式testMouse:    call    CheckMouse      ; 检查鼠标状态,是否发生变化    cmp al,0    jz  again               ; 鼠标状态没有改变    cmp al,3    jz  mouseMove           ; 移动    call    MakeSound       ; 单击了鼠标,发噪音    cmp al,1                ; 鼠标情况    jz  hitLef              ; 左击    cmp al,2            jz  hitRig              ; 右击    hitLef: call    LocateScroll; 左击处理,这里可以调用某些函数    lea dx,msgMouseLeft    call    PrintStr    jmp again hitRig: call    ResetMode   ; 恢复至最初的显示状态    jmp againmouseMove:                  ; 鼠标移动    call    LocateScroll    lea dx,msgMouseMove    call    PrintStr    mov dl,'('    call    PrintChar    mov ax,savPosX          ; 水平位置    call    BinToHex        ; 以十六进制形式打印出来    mov dl,','    call    PrintChar    mov ax,savPosY          ; 垂直位置    call    BinToHex    mov dl,')'    call    PrintChar    jmp againmainOver:       call    HideMouse       ; 隐藏鼠标    call    LocateScroll    ; 重定位光标,并根据需要将窗口下滚一行      lea dx,msgEnd           ; 提示信息    call    PrintStr    call    WaitHitKey      ; 等待用户按键    mov ax,0003h            ; 恢复至DOS默认的显示模式    int 10h    mov ax,4c00h    int 21hmain    endp ;---------------------------------------------------------; 初始化屏幕;---------------------------------------------------------InitScreen  proc    near    call    HideCursor      ; 隐藏光标  [无效] ??    call    ShowProMsg      ; 打印程序的有关信息    call    ShowFramWin     ; 打印屏幕小窗口    call    ShowScrMode     ; 打印当前显示方式的有关信息    mov ah,08h              ; 读光标位置的字符和属性    mov bh,00h    int 10h         mov scroLine,al         ; 保存字符属性,作为窗卷入行属性    mov ah,0fh              ; 取当前显示方式    int 10h    cmp al,03h    jnz NotNormalDos        ; 测试是否是DOS默认的显示模式    mov al,07h              ; 普通卷入行属性 DOS    mov scroLine,al         ; 卷入行属性NotNormalDos:    mov countColumn,ah      ; 保存字符列数    mov dx,winTopRow        ; winTopRow 是标题所在行    inc dh    call    LocateCursor    ; 光标定位到窗口上边缘    mov al,0    mov isScroll,al         ; 恢复滚动标记    call    InitMouse       ; 初始化鼠标    call    ShowMouse       ; 显示鼠标, 大部分模式下默认不能显示    retInitScreen  endp ;---------------------------------------------------------; 重定位光标,并根据需要将窗口下滚一行;---------------------------------------------------------LocateScroll    proc    near    cmp isScroll,1          ; 滚动标记已经设置    jz  LocScroll       mov ah,03h              ; 读当前光标位置            mov bh,00h              ; 页号,0    int 10h    mov cx,winBottomRow    dec ch                  ; 修正    cmp dh,ch               ; 是否到达窗口底部    jb  LocAddRow           ; 增加行号    mov al,1    mov isScroll,1      jmp LocScroll           ; 下滚一行LocAddRow:    mov cx,winTopRow    add cl,4                ; 修正,也就是缩进 4 格    mov dl,cl    inc dh                  ; 行号增 1    call    LocateCursor    jmp LocScrOverLocScroll:    mov ax,0701h            ; ah 功能号,al 滚动行数    mov bh,scroLine         ; 卷入行属性,普通    mov cx,winTopRow        ; 窗口左上角    add ch,2                ; 内容滚动区修正    mov dx,winBottomRow     ; 窗口右下角    dec dh                  ; 修正    mov dl,countColumn      ; 字符列数    int 10h    mov dx,winTopRow        ; 重定位光标到窗口顶部    add dh,2    add dl,4    call    LocateCursorLocScrOver:    retLocateScroll    endp ;---------------------------------------------------------; 检查是否有键盘击键情况,若有,则输出对应键的字符码和扫; 描码, 若所击键为 [ESC],则 ax 设置为 4, 如果是显示方式; 切换热键,则 ax 设置为 2;---------------------------------------------------------CheckKeyBd  proc    near    mov ah,01h    int 16h                 ; 取键盘缓冲区状态    jz  CHKBEND             ; 键盘无按键    mov keyBdIn,ax          ; 保存 ax 中的内容     push    ax    mov al,ah               ; 按键发声,扫描码取模后作为索引    xor ah,ah    div soundFreqSize    xor bh,bh    mov bl,ah               ; 取扫描码除soundFreqSize 后的余数    mov di,soundFreq[bx]    mov cx,0afffh   ; 延迟    call    GenMakeSound        pop ax     call    IsModeChange    ; 测试是否是显示方式切换的 "热键"    cmp ax,2    jz  CHKBEND             ; 是显示方式切换 "热键"    call    LocateScroll    ; 重定位光标,并根据需要将窗口下滚一行    call    PrintKeyCode    ; 以十六进制形式输出键盘码    mov ax,keyBdIn          ; 测试是否是 [ESC] 键    cmp ax,011bh            ; 011bh 是ESC的按键码    jnz CHKBEND    mov ax,4CHKBEND:retCheckKeyBd  endp ;---------------------------------------------------------; 设置光标位置,页号皆为 0, DH/DL 已经相应存了 行/列 [SAFE];---------------------------------------------------------LocateCursor    proc    near    push    bx    push    ax    mov bh,00h    mov ah,02h    int 10h    pop ax    pop bx    retLocateCursor    endp ;---------------------------------------------------------; 切换显示方式, 切换之后,重新运行所有初始化操作;---------------------------------------------------------SwitchMode  proc    near    mov bx,keyBdIn    sub bx,3b00h            ; 3b00h 是F1的按键码    mov bl,bh    mov bh,0                ; 清0,使 bx 成为索引    mov al,byte ptr showMode[bx]    mov ah,00h    int 10h    mov currentMode,bx      ; 设置索引    call    InitScreen    call    LocateScroll    ; 光标处理,窗口下滚    call    PrintKeyCode    ; 输出按键码    retSwitchMode  endp ;---------------------------------------------------------; 检查鼠标状态,是否发生变化( 移动,或者击键 ); 如果是击键则 ax 置为 1(左击)或者 2(右击); 如果是移动则将新位置存入 savPosX,savPosY, ax 置为 3; 如果鼠标状态没有发生变化 ax 置为 0;---------------------------------------------------------CheckMouse  proc    near    mov ax,0003h            ; 读取鼠标状态    int 33h    cmp cx,savPosX          ; 是否移动了鼠标    jnz CKMOV    cmp dx,savPosY    jnz CKMOV    cmp bx,savStat          ; 测试是否有鼠标按键    jz  NOCHG               ; 没有鼠标按键    mov savStat,bx    cmp bx,1                ; 左击    jz  CKHITL    cmp bx,2                ; 右击    jz  CKHITRNOCHG:  mov ax,0            ; 没有鼠标按键    jmp CKOVERCKMOV:  mov ax,3            ; 鼠标移动,保存新位置    mov savPosX,cx    mov savPosY,dx    jmp CKOVERCKHITL: mov ax,1            ; 左击捕获    jmp CKOVERCKHITR: mov ax,2            ; 右击捕获CKOVER: retCheckMouse  endp ;---------------------------------------------------------; 设为DOS普通的显示模式;---------------------------------------------------------ResetMode   proc    near    mov al,03h              ; DOS下的普通模式    mov ah,00h              ; 恢复开始的显示方式    int 10h    mov ax,0    mov currentMode,ax      ; 当前显示方式索引    call    InitScreen    call    LocateScroll        lea dx,msgMouseRight    call    PrintStr    retResetMode   endp   ;---------------------------------------------------------; 声音制作,单击鼠标;---------------------------------------------------------MakeSound   proc    near    mov dx,0MkSAgain:    mov bx,0    MkSNext:    mov di,soundFreq[bx]    mov cx,04fh    call    GenMakeSound    inc bl    cmp bl,soundFreqSize    jb  MkSNext    inc dx    cmp dx,0fh    jnz MkSAgain    retMakeSound   endp ;---------------------------------------------------------; 与CPU工作频率无关的延迟, 延迟时间 (cx*15.08 微秒) [BOOK:391];---------------------------------------------------------GenWait     proc    nearinGenWait:    in  al,61h    and al,10h    cmp al,ah    je  inGenWait    mov ah,al    loop    inGenWait    retGenWait     endp ;---------------------------------------------------------; 利用8253/8254/8255产生指定频率声音的通用发声程序; 指定频率 Di (19-65535Hz) [BOOK:Pg389];  CX 持续时间 (cx*15.08 微秒) [BOOK:391]   [SAFE];---------------------------------------------------------GenMakeSound    proc    near    push    dx    push    di    push    ax    mov al,0b6h             ; 初始化8253/8254的计数器2    out 43h,al    mov dx,12h      mov ax,348ch    div di                  ; 根据频率计算计数值 42h    out 42h,al    mov al,ah    out 42h,al              ; 计数值送端口 42h,以建立声音频率    in  al,61h              ; 61h为8255(a)输出端口    mov ah,al               ; 保存当前值    or  al,03h          out 61h,al              ; 打开声音开关    call    GenWait         ; 与CPU工作频率无关的延迟    mov al,ah               ; 恢复 61h 端口状态    out 61h,al    pop ax    pop di    pop dx    retGenMakeSound    endp ;---------------------------------------------------------; 隐藏光标,该函数无效,不知道什么原因 ????;---------------------------------------------------------HideCursor  proc    near    mov cx,0ffffh           ; ch 第4位为1时光标被隐藏    mov ah,01h              ; 设置光标类型    int 10h     retHideCursor  endp ;---------------------------------------------------------; 等待按键;---------------------------------------------------------WaitHitKey  proc    near    mov ah,00h              ; 等待按键    int 16h    retWaitHitKey  endp ;---------------------------------------------------------; 在屏幕特定位置显示帮助信息;---------------------------------------------------------ShowProMsg  proc    near    lea si,msgHlpEnd    mov bx,0    mov cx,010ah            ; 用于设置光标位置CH/CL , 行/列SSMsgNext:    inc ch                  ; 重设光标位置,行号增一    mov dx,cx    call    LocateCursor    lea dx,msgHlpStar[bx]    call    PrintStr    cmp dx,si    jnb SSMsgOver    add bx,msgLineLen    jmp SSMsgNextSSMsgOver:    retShowProMsg  endp ;---------------------------------------------------------; 打印屏幕上小窗口的框架;---------------------------------------------------------ShowFramWin proc    near    mov dx,winTopRow        ; 窗口标题文字    call    LocateCursor    lea dx,msgWin    call    PrintStr    mov dx,winTopRow        inc dh                  ; 窗口顶部边界    call    LocateCursor    lea dx,windowEdge    call    PrintStr    mov dx,winBottomRow     ; 窗口底部边界    call    LocateCursor    lea dx,windowEdge    call    PrintStr    retShowFramWin endp ;---------------------------------------------------------; 在屏幕小窗口的下部,打印当前显示模式信息;---------------------------------------------------------ShowScrMode proc    near    mov dx,winBottomRow    add dh,2    add dl,2    call    LocateCursor    ; 重设光标位置    lea dx,msgModePrompt    call    PrintStr    mov ax,currentMode    mul msgLineLen    mov bx,ax    lea dx,msgMode[bx]    call    PrintStrShowScrMode endp ;---------------------------------------------------------; 设置光标位置,新位置在DX中,DH/DL=行/列, BH 页号;---------------------------------------------------------SetCursor   proc    near    mov ah,02h    int 10h    retSetCursor   endp    ;---------------------------------------------------------; 打印键盘的击键信息(按键码)其中存于 keyBdIn 变量中;---------------------------------------------------------PrintKeyCode    proc    near    lea dx,msgKeyBd         ; 打印十六进制的按键码    call    PrintStr    mov ax,keyBdIn    call    BinToHex        ; 转为十六进制ASCLL码形式输出到屏幕    mov dl,']'              ; 分割符    call    PrintChar    mov dl,' '    call    PrintChar    mov ah,0ch              ; 调用DOS中断,清空键盘缓冲区    int 21h    mov dx,keyBdIn          ; 打印字符    call    PrintChar    retPrintKeyCode    endp ;---------------------------------------------------------; 将 ax 中的二进制转为 十六进制 ASCALL 码输出到屏幕; 如果需要以小写形式输出则将 bx 设置为 4    [SAFE];---------------------------------------------------------BinToHex    proc    near    push    dx              ; 保存寄存器    push    cx    push    bx    push    ax    mov cx,0404h            ; ch 控制循环次数,cl控制移位数    cmp bx,4    jz  bhLowerCase     mov bh,07h              ; 大写形式输出      jmp bhNextbhLowerCase:    mov bh,27h              ; 小写形式输出bhNext: rol ax,cl    mov bl,al    and bl,0fh    add bl,30h    cmp bl,3ah    jb  bhPrint    add bl,07hbhPrint:    mov dl,bl    push    ax    mov ah,02h    int 21h    dec ch    pop ax    jnz bhNext      pop ax                  ; 恢复寄存器    pop bx    pop cx    pop dx      retBinToHex    endp ;---------------------------------------------------------; 测试键盘按键是否是显示方式切换的 "热键" (F1-F10); 键码存于keyBdIn 中。 若是则 ax 置为 2;---------------------------------------------------------IsModeChange    proc    near    mov bx,3a00h            ; 初始化,3b00h 是 F1    mov ax,keyBdInIsHotF: inc bh    cmp ax,bx    jz  IsHotKey            ; 是 热键 F1-F10     cmp bx,4400h            ; 4400h 是 F10    jz  IsMCOver    jmp IsHotFIsHotKey:    mov ax,2IsMCOver:    retIsModeChange    endp ;---------------------------------------------------------; 屏幕打印字符,字符已经存入 dl 中;---------------------------------------------------------PrintChar   proc    near    mov ah,02h    int 21h    retPrintChar   endp ;---------------------------------------------------------; 屏幕打印字符串,字符串偏移地址已经存入 dx 中;---------------------------------------------------------PrintStr    proc    near    mov ah,09h    int 21h    retPrintStr    endp ;---------------------------------------------------------; 鼠标初始化;---------------------------------------------------------InitMouse   proc    near    mov ax,0000h            ; 鼠标复位    int 33h    call    InitPos         ; 初始化鼠标位置    retInitMouse   endp ;---------------------------------------------------------; 显示鼠标;---------------------------------------------------------ShowMouse   proc    near    mov ax,0001h    int 33h    retShowMouse   endp ;---------------------------------------------------------; 隐藏鼠标;---------------------------------------------------------HideMouse   proc    near    mov ax,0002h    int 33h    retHideMouse   endp ;---------------------------------------------------------; 初始化鼠标位置;---------------------------------------------------------InitPos     proc    near    mov ax,0004h    mov cx,42               ; 水平位置    mov dx,18               ; 垂直位置    int 33h    retInitPos     endp;----------------------------------------------------------------------------------        end star  

阅读(7094) | 评论(1)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

loading...
您需要登录后才能评论,请 登录 或者 注册