;==========================================================================
;实验17 编写包含多个功能子程序的中断例程
;安装一个新的 int 7ch 中断例程,用逻辑扇区号对软盘进行读写
;用AH寄存器传递功能号,0表示读,1表示写
;用DX寄存器传递要读写的扇区的逻辑扇区号
;用ES:BX指向存储读出数据或者写入数据的内存区
;==========================================================================
ASSUME CS:CODE
DATA SEGMENT
;用于检验中断例程
DB 32 DUP ("Welcome to masm!")
DATA ENDS
CODE SEGMENT
START:
;安装新的 INT 7CH 中断
PUSH CS
POP DS
MOV SI,OFFSET NEW_INT7CH_START
MOV AX,0
MOV ES,AX
MOV DI,200H
MOV CX,OFFSET NEW_INT7CH_END-OFFSET NEW_INT7CH_START
CLD
REP MOVSB
;设置新的中断向量表
CLI
MOV WORD PTR ES:[4*7CH],200H
MOV WORD PTR ES:[4*7CH+2],0
STI
;测试新的 INT 7CH 中断
MOV AX,DATA
MOV DS,AX
;写
PUSH DS ;ES:BX指向要写的单元
POP ES
MOV BX,0
MOV DX,0
MOV AL,1
MOV AH,1
INT 7CH
;读 ;ES:BX指向要读的单元
MOV AX,2000H ;读到2000:0处
MOV ES,AX
MOV BX,0
MOV DX,0
MOV AL,1
MOV AH,0
INT 7CH
MOV AX,4C00H
INT 21H
;新的 INT 7CH 中断
;-----------------------------------------------------------------------------------
;功能:用逻辑扇区号对软盘进行读写
;参数: (AH)=功能号,0=读,1=写;(DX)=要读写的扇区的逻辑扇区号,(AL)=读取或写入的扇区数
; ES:BX指向存储读出数据或者写入数据的内存区
;返回:同 INT 7CH 的返回,操作成功:(AH)=0,(AL)=读入或写入的扇区数,操作失败:(AH)=错误代码
NEWINT7 PROC NEAR
NEW_INT7CH_START:
JMP NEW_INT7CH_REAL_START
TABLE DW SUB0-NEWINT7+200H,SUB1-NEWINT7+200H
NEW_INT7CH_REAL_START:
PUSH DX
PUSH CX
PUSH SI
MOV CL,AH
MOV CH,0
SHL CX,1
MOV SI,CX
CALL CONVERT
CALL WORD PTR CS:[TABLE-NEWINT7+200H+SI]
JMP NEW_INT7CH_RET
SUB0:
;不能在子程序中再来POP!!因为在调用子程序的时候会压入IP
;此时POP会导致一系列不可预知的错误
MOV DL,0
MOV AH,02
INT 13H
RET
SUB1:
MOV DL,0
MOV AH,03
INT 13H
RET
NEW_INT7CH_RET:
POP SI
POP CX
POP DX
IRET
CONVERT:
;-------------------------------------------------------------------------------
;功能:根据逻辑扇区号计算物理扇区号
;参数:(DX)=逻辑扇区号(0~2879)
;返回:(DH)=面号(0,1),(CH)=磁道号(1~79),(CL)=扇区号(1~18)
PUSH AX
MOV AX,DX
MOV DX,0
MOV CX,1440
DIV CX ;(AX)=面号
MOV DH,AL
PUSH DX
MOV AX,DX
MOV DX,0
MOV CX,18
DIV CX ;(AX)=磁道号
MOV CH,AL
ADD DX,1 ;(DX)=扇区号
MOV CL,DL
POP DX
POP AX
RET
;-------------------------------------------------------------------------------
NEW_INT7CH_END:
NOP
NEWINT7 ENDP
;-----------------------------------------------------------------------------------
CODE ENDS
END START