60h和64h端口问题,求解!!

时间:2021-08-16 15:23:04
测试环境:win7,IntelCPU中VMWare虚拟机里,虚拟机操作系统:32位XP。
请问高人下面的代码为什么不能达到从8042微处理器修改按键信息的效果?
刚开始自学汇编不久,已经认真看完了王爽的《汇编语言》,但在写下面的汇编代码时,不能达到预期效果,特发帖求解惑!


;------------------------------主程序说明--------------------------------------
;[程序说明]
;[程序结果]
;[总结经验]
;------------------------------------------------------------------------------------------
data segment

data ends


stack segment

stack ends


code segment
assume cs:code,ds:data,ss:stack

;------------------------------主程序开始------------------------------

main:
xor ax,ax

s1: in al,64h
and al,00000010b
cmp al,0

jne s1 ;状态寄存器bit1如果不为0就跳转.


mov al,60h
out 64h,al ;下面通过60h端口写入的数据将送到控制寄存器
mov al,46h
out 60h,al ;即01000110b,bit0位为0,表示关闭键盘中断,bit1为1表示允许鼠标中断
;打开时将01000111b送入控制寄存器即可.


s2: in al,64h ;再次获得状态寄存器的数据
and al,00000001b
cmp al,1 ;bit0如果为1,说明有输出缓冲器中有数据

jne s2 ;bit0如果不为1,就轮询

in al,60h
mov bl,al

mov al,60h
out 64h,al
mov al,47h
out 60h,al ;打开键盘中断,以便让硬件自动产生中断信号

s3: in al,64h
and al,00000010b
cmp al,0

jne s3


mov al,0d2h
out 64h,al ;接下来向60h端口写入的数据要放到输出缓冲器中,

s4: in al,64h
and al,00000010b
cmp al,0

jne s4
;,,,,如果中断允许,将产生一个中断
mov al,1eh ;不管按的是什么键,都作A键处理,试验性数据
out 60h,al ;因为中断已经打开,将产生一个硬中断


nop

mov ah,0
int 16h

mov di,0b800h
mov es,di
mov di,160*10+40*2
mov es:[di],al
add di,6
mov al,ah
mov ah,0
call outHax_Ex

jmp s1

mov ah,7h ;选择中断处理程序的第7号子程序
int 21h ;调用DOS提供的第21号中断处理程序.
;暂停,以便查看结果

mov ah,4ch ;选择中断处理程序的第4ch号子程序
int 21h ;调用DOS提供的第21号中断处理程序
;退出本程序,返回DOS(即返回操作系统)

;****************函数说明****************
;[函数功能] 以十六进制字符输出寄存器AX中的内容
;[函数参数] AX 待输出的数据
; ES 显存段地址
; DI 显存位置指针
;[函数返回] AX 不变
; ES 不变
; DI 随便输出的内容改变
;[注意事项]
;[前提函数]
;****************函数开始****************
tableEx db '0123456789ABCDEF'

outHax_Ex: push ax
push bx
push cx
push dx
push es

mov bx,es
cmp bx,0b800h
je outHax_Ex0
mov bx,0b800h
mov es,bx ;如果未设置显存,则先设置显存

outHax_Ex0: mov dl,al ;备份AX的低字节
mov cx,2

outHax_Ex1:
push cx
mov al,ah ;复制AX的高字节
mov cl,4
shr ah,cl ;高字节右移4位
and al,00001111b ;低字节取最右边4位

mov bh,0
mov bl,ah
mov bl,tableEx[bx]
mov es:[di],bl
add di,2

mov bl,al
mov bl,tableEx[bx]
mov es:[di],bl
add di,2

mov ah,dl

pop cx
loop outHax_Ex1

pop es
pop dx
pop cx
pop bx
pop ax
ret
;****************函数结束****************


;****************函数说明****************
;[函数功能] 以十六进制字符输出寄存器AX中的内容
;[函数参数] AX 待输出的数据
; ES 显存段地址
; DI 显存位置指针
;[函数返回] AX 不变
; ES 不变
; DI 不变
;[注意事项]
;[前提函数]
;****************函数开始****************
table db '0123456789ABCDEF'

outHax: push ax
push bx
push cx
push dx
push es
push di

mov di,160*10+2*3

mov bx,es
cmp bx,0b800h
je outHax0
mov bx,0b800h
mov es,bx ;如果未设置显存,则先设置显存

outHax0: mov dl,al ;备份AX的低字节
mov cx,2

outHax1:
push cx
mov al,ah ;复制AX的高字节
mov cl,4
shr ah,cl ;高字节右移4位
and al,00001111b ;低字节取最右边4位

mov bh,0
mov bl,ah
mov bl,table[bx]
mov es:[di],bl
add di,2

mov bl,al
mov bl,table[bx]
mov es:[di],bl
add di,2

mov ah,dl

pop cx
loop outHax1

pop di
pop es
pop dx
pop cx
pop bx
pop ax
ret
;****************函数结束****************
code ends
end main
;------------------------------主程序结束------------------------------

1 个解决方案

#1


这种代码要在true dos下运行,不能在Nt下运行,因为系统有保护。

#1


这种代码要在true dos下运行,不能在Nt下运行,因为系统有保护。