;安装一个新的中断例程 int 7ch ,实现通过逻辑扇区号对软盘惊醒读写。
;参数ah 功能号,0:读。1:写
;DX要读或写的逻辑扇区号
;ES:BX指向要读的数据或者写入的内存区
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;通用中断安装程序 被安装开始标志install结束标志installend
;安装程序
assume cs:code
code segment
start:
mov ax,cs
mov ds,ax
mov si,offset install
mov ax,0
mov es,ax
mov di,200h
mov cx,offset installend-offset install
cld
rep movsb
mov ax,0
mov es,ax
mov word ptr es:[7ch*4],200h ;例程的偏移
mov word ptr es:[7ch*4+2],0 ;例程的段
mov ax,4c00h
int 21h
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
install:
st0:
jmp short set
table dw sub1-st0+200h,offset sub2-offset st0+200h
;这个中断有两个功能,所以直接定址表里边的table由于两个地址
;ah=0是读ah=1是写
set:
push bx
cmp ah,1
ja sret
;DX的范围是 0~2879一共
cmp dx,2879
ja sret
mov bl,ah
mov bh,0
add bx,bx ;根据AH中的功能号,计算出对应子程序在TABLE表中的偏移
call word ptr cs:[bx+offset table-offset st0+200h] ;teble段减去程序开始的位移加上200H,这样就定位了
sret:
pop bx
iret
;下边ah就可以无视了
;主要就是参数DX和参数ES:BX
;功能子程序1:读取
sub1:
;这里要完成通过DX里边描述的逻辑扇区进行读
;然后传递到es:bx指向的地方
;先找到DX指向的面号
push dx ;保存dx
mov ax,dx ;被除数是AX
mov dx,1440 ;被除数是1440
div dx ;商存在了AX中,面号找到了
pop dx ;恢复dx
push ax ;面号进栈
;;;;;;;;;;;;;;;;;;;;;;;;;;
;下面要找到磁道号
push dx ;保存dx
mov ax,dx ;被除数是AX
mov dx,1440 ;被除数是1440
div dx ;余数存在了DX中
mov ax,dx
mov dx,18
div dx ;商在ax中 找到了
pop dx ;恢复DX
push ax; 磁道号 进栈
;;;;;;;;;;;;;;;;;;;;;;;;;;
;下面要找到扇区号
push dx ;保存dx
mov ax,dx ;被除数是AX
mov dx,1440 ;被除数是1440
div dx ;余数存在了DX中
mov ax,dx
mov dx,18
div dx ;余数在DX中
add dx,1 ;DX就是扇区号
pop ax; 扔掉之前保存的DX
push dx ;扇区号进栈
;;;;;;;;;;;;;;;;;;;;;;;;;;
;现在栈里从顶到底的3个字分别是 扇区号,磁道号,面号。
;int13H的参数开始
mov ah,2 ;读
pop dx
mov cl,dl
pop dx
mov ch,dl
pop dx
mov dh,dl
mov dl,0
mov al,1
int 13h
ret
;功能子程序2:写入
sub2:
;这里要完成向DX里边描述的逻辑扇区进行写
;源是es:bx指向的地方
;先找到DX指向的面号
push dx ;保存dx
mov ax,dx ;被除数是AX
mov dx,1440 ;被除数是1440
div dx ;商存在了AX中,面号找到了
pop dx ;恢复dx
push ax ;面号进栈
;;;;;;;;;;;;;;;;;;;;;;;;;;
;下面要找到磁道号
push dx ;保存dx
mov ax,dx ;被除数是AX
mov dx,1440 ;被除数是1440
div dx ;余数存在了DX中
mov ax,dx
mov dx,18
div dx ;商在ax中 找到了
pop dx ;恢复DX
push ax; 磁道号 进栈
;;;;;;;;;;;;;;;;;;;;;;;;;;
;下面要找到扇区号
push dx ;保存dx
mov ax,dx ;被除数是AX
mov dx,1440 ;被除数是1440
div dx ;余数存在了DX中
mov ax,dx
mov dx,18
div dx ;余数在DX中
add dx,1 ;DX就是扇区号
pop ax; 扔掉之前保存的DX
push dx ;扇区号进栈
;;;;;;;;;;;;;;;;;;;;;;;;;;
;现在栈里从顶到底的3个字分别是 扇区号,磁道号,面号。
;int13H的参数开始
mov ah,3 ;读
pop dx
mov cl,dl
pop dx
mov ch,dl
pop dx
mov dh,dl
mov dl,0
mov al,1
int 13h
ret
installend:nop
code ends
end start
- [ce54605802] 经过我自己的测试,有问题,调试的时候出现除法溢出。需要改进 10/27 20:49
- [tinyparticle] 功能完成 10/14 18:39
- [tinyparticle] 正确 10/14 18:38
- [tinyparticle] 测试通过 10/14 18:38
- [tinyparticle] 理解没问题 10/11 14:49
- [ce54605802] 。。 “啥” 是东北方言 10/11 14:40
- [tinyparticle] 没啥问题。 10/11 14:26
- [younggay] 不错,加油。 10/10 13:33
- [ce54605802] 上去看了一下,真不错,网站也收藏了 我QQ是54605802 加下QQ吧,方便交流 10/09 23:15
- [tinyparticle] 加密与解密(第三版) 支持网站:http://bbs.pediy.com/index.php 10/09 23:09
- [ce54605802] 呵呵 你给加上0001H 有什么意义啊 加上 00FFH 试试啊 09/15 23:34
- [abob] 物理地址 等于 FFFF*16+FFFF 等于16FFE9,远远超过了20位数字 ------ 08/05 17:10