汇编语言中断程序实例——定时小程序

;计算机在系统加电期间,把系统定时器初始化为每55ms发出一次中断请求。CPU在相应定时中断请求后转入08H号中断处理程序。

;BIOS提供的08H号中断处理程序中有一条中断指令“INT 1CH”。所以每秒要调用1000/55≈18.2次1CH号中断处理程序。
;而BIOS的1CH号中断处理程序实际上并没有执行任何工作,只有一条中断返回指令(IRET)

;这样安排的目的就是为应用程序留下一个软接口,应用程序只要提供新的1CH号中断处理程序,就能实现某些周期性的工作。
;本实验就是利用这个软接口实现“实时时钟显示”

CODE  SEGMENT
    ASSUME  CS:CODE
       YYY    DW  0
       MON    DB  0
       DDD    DB  0
       OLD1C  DD  0
       COUNT  DW  0
       HHH    DB  0
       MMM    DB  0
       SSS    DB  0
       NOZERO DB  0
       TIMECOUNT  DW   0
       TIMEFLY  DW   0
       TIMEAGO  DB   0
       TIMENOW  DB   0
       SHOWTIME DW   0
START  PROC  FAR
	   
       CALL  INPUTDEC					;输入定时时长,保存在BX中
       MOV   TIMEFLY,BX					
	   
       PUSH  CS
       POP   DS						;把CS的值赋给DS
      ;设置新的中断向量
       MOV   AX,351CH					;读取1C号中断向量
       INT   21H					;ES:BX是读取出的中断向量
       MOV   CS:WORD  PTR OLD1C,BX
       MOV   CS:WORD  PTR OLD1C+2,ES	                ;保存原1C号中断向量
       MOV   DX,OFFSET  INT1C
       MOV   AX,251CH					;设置中断向量,DS:DX=中断向量,AL=中断类型号
       INT   21H					;此后每55秒就进入一次新的1CH号中断处理程序
	   
CLOCKGO:
       CMP   SHOWTIME,5					;显示时间到了吗?
       JC   CLOCKGO					;没到,循环;否则执行结束
	   
       ;结束程序之前,应把1C号中断向量还原回去
       LDS   DX,CS:OLD1C
       MOV   AX,251CH
       INT   21H
   
       ;结束程序,返回操作系统
       MOV   AH,4CH
       INT   21H		   
START  ENDP

INT1C  PROC   FAR

       CMP    COUNT,0					;中断次数为0,经过大约一秒
       JZ     NEXT
       DEC    COUNT
       IRET
NEXT:  
	   MOV    COUNT,17					;置中断次数初值
       STI
       PUSH   DS
       PUSH   ES
       PUSH   AX
       PUSH   BX
       PUSH   CX
       PUSH   DX
       PUSH   SI
       PUSH   DI
	   
	   MOV    AH,2CH
	   INT    21H						;读系统时间
	   MOV    HHH,CH					;小时
	   MOV    MMM,CL					;分钟
	   MOV    SSS,DH					;秒
	   
	   CMP    TIMEAGO,DH				;是不是新的一秒?
	   JNE    GOON						;是,执行GOON,否则返回
	   POP    DI
       POP    SI
       POP    DX
       POP    CX
       POP    BX
       POP    AX
       POP    ES
       POP    DS
       IRET

GOON:
	   MOV    TIMEAGO,DH				;新的一秒
	   INC    TIMECOUNT					;计时器加一

	   MOV   AH,2AH
       INT   21H						;读系统日期
	   MOV   YYY,CX						;年
	   MOV   MON,DH						;月
	   MOV   DDD,DL						;日
	   
	   CALL   CLS						;清屏
	   
	   MOV    BH,0
	   MOV    DX,0105H
	   MOV    AH,2
	   INT    10H						;设置光标位置(1,5)
	   
	   MOV    BX,YYY					;输出年
	   CALL   OUTPUTDEC
	   CALL   OUTPOINT					;点
	   
	   MOV    BL,MON					;输出月
	   MOV    BH,0
	   CALL   OUTPUTDEC
	   CALL   OUTPOINT					;点
	   
	   MOV    BL,DDD					;输出日
	   MOV    BH,0
	   CALL   OUTPUTDEC
	   CALL   WHITESPACE				;空格
	   
	   MOV    BL,HHH					;时
	   MOV    BH,0
	   CALL   OUTPUTDEC
	   CALL   OUTMAOHAO					;冒号
	   
	   MOV    BL,MMM					;秒
	   MOV    BH,0
	   CALL   OUTPUTDEC
	   CALL   OUTMAOHAO					;冒号
	   
	   
	   MOV    BL,SSS					;秒
	   MOV    BH,0
	   CALL   OUTPUTDEC
	   

	   MOV   BX,TIMEFLY
	   CMP   BX,TIMECOUNT				;比较定时是否已到
	   JNC   RETURN						;没到,返回;否则继续执行显示方块
	   
SHOWWORD:	   
	   INC   SHOWTIME
	   
	   MOV   BH,0
	   MOV   DX,0140H
	   MOV   AH,2
	   INT   10H						;设置光标位置(1,65)	   
	   
	   MOV	 AL,09
	   MOV   CX,1
	   MOV   BL,0CCH
	   MOV   AH,9
	   INT 	 10H						;显示一红色方块
	   
RETURN:	   
       POP    DI
       POP    SI
       POP    DX
       POP    CX
       POP    BX
       POP    AX
       POP    ES
       POP    DS
       IRET
INT1C  ENDP

;清屏
CLS    PROC   
       MOV    AX,0600H
       MOV    CX,0
       MOV    DX,184FH
       MOV    BH,7
       INT    10H
       RET
CLS    ENDP

;十进制数输入(0—65535)
;输入数据存储在BX中,以回车符结束
INPUTDEC PROC
	PUSH CX
	MOV BX,0
P1:
	MOV AH,1
	INT 21H
	CMP AL,0DH		;与回车符比较,判断是否结束
	JE DECEXIT
	SUB AL,30H		;ASCII码减去30,得本次所输数值
	MOV AH,0		;AH清0
	XCHG AX,BX		;交换AX,BX
	MOV CX,10		
	MUL CX			;AX(原BX中数,以前输的数)10
	XCHG AX,BX		;交换AX,BX
	ADD BX,AX		;将本次输的数加进BX中
	JMP P1
DECEXIT:
	POP CX
	RET
INPUTDEC ENDP

;十进制输出(0-65535)
;数据保存在BX中
OUTPUTDEC PROC
	PUSH CX
	MOV NOZERO,0
	MOV CX,10000
	CALL PROCESS
	MOV CX,1000
	CALL PROCESS
	MOV CX,100
	CALL PROCESS
	MOV CX,10
	CALL PROCESS
	MOV CX,1
	CALL PROCESS
	CMP NOZERO,0
	JNE OUTPUTEXIT
	MOV DL,30H
	MOV AH,2
	INT 21H
OUTPUTEXIT:
	POP CX
	RET
OUTPUTDEC ENDP

PROCESS PROC
	MOV AX,BX
	MOV DX,0
	DIV CX
	MOV BX,DX
	MOV DL,AL
	CMP DL,0
	JNE OUTPUT			;该位不是0,输出
	CMP NOZERO,0		;该位是0,判断是否为首位
	JNE OUTPUT			;不是首位,输出
	JMP PROCEXIT		;是首位,退出
OUTPUT:
	MOV NOZERO,1
	ADD DL,30H
	MOV AH,2
	INT 21H
PROCEXIT:
	RET
PROCESS ENDP

;输出点号
OUTPOINT PROC
	MOV DL,'.'
	MOV AH,2
	INT 21H
	RET
	OUTPOINT ENDP

;输出冒号	
OUTMAOHAO PROC
	MOV DL,':'
	MOV AH,2
	INT 21H
	RET
	OUTMAOHAO ENDP

;输出空格
WHITESPACE PROC
	MOV DL,20H
	MOV AH,2
	INT 21H
	RET
	WHITESPACE ENDP

CODE   ENDS
       END   START

你可能感兴趣的:(汇编语言中断程序实例——定时小程序)