readkey proc TPC-386EX 32 位微机接口实验指导书(教师版) • 37 • mov ah,0feh scan: mov al,ah mov dx,i8255_a ;输出一行线为低 out dx,al mov dx,i8255_b in al,dx ;输入列线状态 or al,0f0h ;高四位置 1,低四位为列线状态 cmp al,0ffh ;此行有键按下码? jne exitkey ;有键按下,退出 rol ah,1 ;没有,检查下一行 jmp scan exitkey: ret readkey endp delay proc push cx mov cx,8000h ;延时 delay1: loop delay1 pop cx ret delay endp keyup proc noup: mov al,ah mov dx,i8255_a out dx,al ;输出行线 mov dx,i8255_b in al,dx ;读入列线 or al,0f0h cmp al,0ffh ;按键释放了码? je exit ;已释放,退出 jmp noup exit: ret keyup endp cmpoffset proc not ah ;行值取反 not al ;列值取反 mov bh,00h mov bl,00h kk: shr ah,1 jc next1 add bh,4h ;一行 4 列 jmp kk
时间: 2023-05-17 19:06:59 浏览: 191
这是一段汇编代码,用于读取键盘输入。readkey proc是一个过程,用于读取键盘输入,delay proc是一个过程,用于延时,keyup proc是一个过程,用于检测键盘是否释放,cmpoffset proc是一个过程,用于比较偏移量。
相关问题
用 emu8086 优化以下代码BIN2HEX PROC PUSH BP MOV BP, SP MOV AX, [BP+4] MOV BX, 1000b MOV CX, 4 LOOP1: ROR AX, 1 ADC BL, BL ADC BL, 0 DEC BX JNZ LOOP1 MOV AH, 0 MOV AL, BL AND AL, 0Fh ADD AL, 30h CMP AL, 39h JBE CHAR1 ADD AL, 7 CHAR1: MOV DL, AL MOV AH, 2 INT 21h MOV AH, 0 MOV AL, BH AND AL, 0Fh ADD AL, 30h CMP AL, 39h JBE CHAR2 ADD AL, 7 CHAR2: MOV DL, AL MOV AH, 2 INT 21h MOV AH, 0 MOV AL, AH AND AL, 0Fh ADD AL, 30h CMP AL, 39h JBE CHAR3 ADD AL, 7 CHAR3: MOV DL, AL MOV AH, 2 INT 21h MOV AH, 0 MOV AL, BL AND AL, 0Fh ADD AL, 30h CMP AL, 39h JBE CHAR4 ADD AL, 7 CHAR4: MOV DL, AL MOV AH, 2 INT 21h POP BP RET 2 BIN2HEX ENDP ORG 100h MOV AX, 1010101010101010b CALL BIN2HEX PUSH AX CALL BIN2HEX ADD SP, 2 MOV AH, 4Ch INT 21h END
首先,可以使用移位运算代替循环中的 ROR 指令,这样可以提高代码的运行效率。另外,可以使用位运算代替 ADC 指令,也可以提高代码的效率。最后,可以使用循环展开的方式,减少跳转指令的使用,进一步提高代码的效率。
下面是优化后的代码:
BIN2HEX PROC
PUSH BP
MOV BP, SP
MOV AX, [BP+4]
MOV BX, 1000b
MOV CX, 4
LOOP1:
SHR AX, 1
RCL BL, 1
RCL BH, 1
DEC CX
JNZ LOOP1
MOV AH, 0
MOV AL, BL
AND AL, 0Fh
ADD AL, 30h
CMP AL, 39h
JBE CHAR1
ADD AL, 7
CHAR1:
MOV DL, AL
MOV AH, 2
INT 21h
MOV AL, BH
AND AL, 0Fh
ADD AL, 30h
CMP AL, 39h
JBE CHAR2
ADD AL, 7
CHAR2:
MOV DL, AL
MOV AH, 2
INT 21h
MOV AL, AH
AND AL, 0Fh
ADD AL, 30h
CMP AL, 39h
JBE CHAR3
ADD AL, 7
CHAR3:
MOV DL, AL
MOV AH, 2
INT 21h
MOV AL, BL
AND AL, 0Fh
ADD AL, 30h
CMP AL, 39h
JBE CHAR4
ADD AL, 7
CHAR4:
MOV DL, AL
MOV AH, 2
INT 21h
POP BP
RET 2
BIN2HEX ENDP
ORG 100h
MOV AX, 1010101010101010b
CALL BIN2HEX
PUSH AX
CALL BIN2HEX
ADD SP, 2
MOV AH, 4Ch
INT 21h
END
这样优化后的代码应该会更快地执行。
代码逐句注释code segment assume cs:code start: mov ax,cs mov ds,ax mov dx,offset int_proc mov ax,2572h int 21h mov dx,21h in al,dx and al,0fbh out dx,al in al,0a1h and al,0fbh out 0a1h,al mov dx,28bh mov al,0b8h out dx,al mov al,09h out dx,al mov bl,8 ll: jmp ll int_proc: mov dx,288h in al,dx mov dl,al mov ah,02h int 21h mov dl,0dh int 21h mov dl,0ah int 21h mov dx,20h mov al,20h out dx,al out 0a0h,al dec bl jnz next in al,21h or al,08h out 21h,al sti mov ah,4ch int 21h next: iret code ends end start
这段代码是一段汇编代码,主要作用是设置中断处理程序,并且在中断处理程序中输出一些信息。下面是每一行代码的注释:
```
code segment ; 定义代码段
assume cs:code ; 设置代码段寄存器
start: ; 开始标记
mov ax,cs ; 将代码段寄存器 CS 的值移动到通用寄存器 AX 中
mov ds,ax ; 将 AX 中的值移动到数据段寄存器 DS 中
mov dx,offset int_proc ; 将中断处理程序的偏移地址移动到 DX 中
mov ax,2572h ; 将 2572H 移动到 AX 中
int 21h ; 执行 DOS 中断 21h,将中断向量设置为 int_proc
mov dx,21h ; 将端口地址 21H 移动到 DX 中
in al,dx ; 从 DX 指定的端口读取一个字节到 AL 中
and al,0fbh ; 将 AL 中的值与 0FBH 按位与
out dx,al ; 将 AL 中的值输出到 DX 指定的端口
in al,0a1h ; 从端口地址 0A1H 读取一个字节到 AL 中
and al,0fbh ; 将 AL 中的值与 0FBH 按位与
out 0a1h,al ; 将 AL 中的值输出到端口地址 0A1H
mov dx,28bh ; 将端口地址 28BH 移动到 DX 中
mov al,0b8h ; 将值 0B8H 移动到 AL 中
out dx,al ; 将 AL 中的值输出到 DX 指定的端口
mov al,09h ; 将值 09H 移动到 AL 中
out dx,al ; 将 AL 中的值输出到 DX 指定的端口
mov bl,8 ; 将值 8 移动到 BL 中
ll: ; 标记 ll
jmp ll ; 无条件跳转到标记 ll
int_proc: ; 定义中断处理程序
mov dx,288h ; 将端口地址 288H 移动到 DX 中
in al,dx ; 从 DX 指定的端口读取一个字节到 AL 中
mov dl,al ; 将 AL 中的值移动到 DL 中
mov ah,02h ; 将值 02H 移动到 AH 中
int 21h ; 执行 DOS 中断 21h,将 DL 中的值输出到屏幕上
mov dl,0dh ; 将值 0DH 移动到 DL 中,即回车符
int 21h ; 执行 DOS 中断 21h,输出回车符
mov dl,0ah ; 将值 0AH 移动到 DL 中,即换行符
int 21h ; 执行 DOS 中断 21h,输出换行符
mov dx,20h ; 将端口地址 20H 移动到 DX 中
mov al,20h ; 将值 20H 移动到 AL 中
out dx,al ; 将 AL 中的值输出到 DX 指定的端口
out 0a0h,al ; 将 AL 中的值输出到端口地址 0A0H
dec bl ; 将 BL 中的值减 1
jnz next ; 如果 BL 不为 0,跳转到标记 next
in al,21h ; 从端口地址 21H 读取一个字节到 AL 中
or al,08h ; 将 AL 中的值与 08H 按位或
out 21h,al ; 将 AL 中的值输出到端口地址 21H
sti ; 开启中断
mov ah,4ch ; 将值 4CH 移动到 AH 中,即结束程序
int 21h ; 执行 DOS 中断 21h
next: ; 标记 next
iret ; 中断返回指令
code ends ; 代码段结束
end start ; 程序结束
阅读全文