概述
;MASM5编译通过
;==========================================================================
;安装一个新的 INT 9 中断例程,为显示输出提供如下功能子程序:
;(1)清屏;(2)设置前景色;(3)设置背景色;(4)向上滚动一行
;用AH传递功能号,0表示清屏,1表示设置前景色,2表示设置背景色,3表示向上滚动一行.
;对于1、2号功能,用AL传递颜色值,(AL)∈{0,1,2,3,4,5,6,7}
;==========================================================================
ASSUME CS:CODE
CODE SEGMENT
S1 DB "Good,better,best,",'$'
S2 DB "Never let itrest,",'$'
S3 DB "Till good isbetter,",'$'
S4 DB "Andbetter,best.",'$'
S DW OFFSET S1,OFFSET S2,OFFSET S3,OFFSET S4
ROW DB 2,4,6,8
START:
;安装中断处理程序到0:200H处
PUSH CS
POP DS ;(DS)=传送原始位置的段地址
MOV SI,OFFSET INT7START ;DS:SI指向传送原始位置的首地址
MOV AX,0
MOV ES,AX ;(ES)=0,传送目的位置的段地址
MOV DI,200H ;ES:SI指向传送目的位置的首地址
MOV CX,OFFSET INT7END-OFFSET INT7START ;传送长度
CLD ;正向
REP MOVSB ;传送
;设置中断向量表
MOV WORD PTR ES:[4*7CH],200H
MOV WORD PTR ES:[4*7CH+2],0
;测试 INT 7CH 0号子程序
MOV AH,0
INT 7CH
;向屏幕输出四句英文诗
MOV AX,CS ;DS和CS使用同一段
MOV DS,AX
MOV BX,OFFSET S ;BX用来寻址字符串的首地址
MOV SI,OFFSET ROW ;SI用来寻址行数
MOV CX,4 ;循环次数4
OK:
MOV BH,0 ;0页
MOV DH,BYTE PTR CS:[SI] ;(DH)=行数
MOV DL,0 ;(DL)=列数
MOV AH,2 ;置光标
INT 10H
MOV DX,CS:[BX] ;DS:DX指向字符串的首地址
MOV AH,9 ;输出以"$"结尾的字符串
INT 21H
INC SI ;SI指向下一句诗的行数
ADD BX,2 ;BX指向下一句诗的字符串的首地址
LOOP OK ;输出下一句诗
;以下,测试 INT 7CH 1~3号子程序
MOV AH,1
MOV AL,10
INT 7CH
MOV AH,2
MOV AL,4
INT 7CH
MOV AH,3
INT 7CH
;程序返回
MOV AX,4C00H
INT 21H
;新的 INT 9 中断例程
;-----------------------------------------------------------------------------------
;功能:0号子程序:清屏 1号子程序:设置前景色 2号子程序:设置背景色 3号子程序:向上滚动一行
;参数:(AH)=功能选择,(AL)=颜色
;返回:无
INT7 PROC NEAR
INT7START:
JMP SHORT INT7_REAL_START
;直接定址表
TABLE DW SUB0-INT7+200H,SUB1-INT7+200H,SUB2-INT7+200H,SUB3-INT7+200H
;这一句执行完以后,TABLE中存放中断处理程序中各子程序的IP
;因为位移是在编译的时候算出来的,一定要保证这里算出来的结果和
;安装到0:200H处以后的结果相符
INT7_REAL_START:
PUSH AX ;保护现场
PUSH BX
PUSH DX
PUSH DS
PUSH ES
PUSH CS ;进入中断处理程序前,(CS)=0,(DS)可能≠0
POP DS ;设置(DS)=0
MOV BL,AH
MOV BH,0
SHL BX,1 ;(BX)=(BX)*2
MOV DX,0B800H
MOV ES,DX
;这里取得0:200H处中断处理程序子程序IP,也要按(CS)=0000考虑
CALL WORD PTR [TABLE-INT7+200H+BX] ;(DS)=0,DS:[TABLE-INT7+200H+BX]存放着
;中断处理程序被安装0:200H处后子程序的IP
JMP INT7RET
SUB0: ;0号子程序,清屏
PUSH CX
PUSH DI
;把屏幕上的所有字符替换成空格
MOV DI,0
MOV CX,2000
SUB0S:
MOV BYTE PTR ES:[DI],' '
INC DI
INC DI
LOOP SUB0S
POP DI
POP CX
RET
SUB1: ;1号子程序,改变前景色
PUSH CX
PUSH DI
;修改显示缓冲区所有字符属性字节的值
MOV DI,1
MOV CX,2000
SUB1S:
AND BYTE PTR ES:[DI],11111000B
OR ES:[DI],AL
INC DI
INC DI
LOOP SUB1S
POP DI
POP CX
RET
SUB2: ;2号子程序,改变背景色
PUSH AX
PUSH CX
PUSH DI
;修改显示缓冲区所有字符属性字节的值
MOV CL,4
SHL AL,CL
MOV DI,1
MOV CX,2000
SUB2S:
AND BYTE PTR ES:[DI],10001111B
OR ES:[DI],AL
INC DI
INC DI
LOOP SUB2S
POP DI
POP CX
POP AX
RET
SUB3: ;3号子程序,上卷一行
PUSH CX
PUSH SI
PUSH DI
PUSH DS
PUSH ES
POP DS ;设置(ES)=(DS)=显示缓冲区段地址
MOV SI,160 ;DS:SI指向传送原始位置的首地址
MOV DI,0 ;ES:SI指向传送目的位置的首地址
MOV CX,24*160 ;传送长度
REP MOVSB ;传送
MOV DI,24*160 ;最后一行的偏移地址
MOV CX,160 ;传送长度
SUB3S: ;用空格代替
MOV BYTE PTR ES:[DI],' '
INC DI
INC DI
LOOP SUB3S
POP DS
POP DI
POP SI
POP CX
RET
INT7RET: ;恢复现场
POP ES
POP DS
POP DX
POP BX
POP AX
IRET ;中断返回
INT7END:
NOP
INT7 ENDP
CODE ENDS
END START
最后
以上就是清脆雪糕为你收集整理的王爽《汇编语言》实验16——编写包含多个功能子程序的中断例程的全部内容,希望文章能够帮你解决王爽《汇编语言》实验16——编写包含多个功能子程序的中断例程所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复