鱼C论坛

 找回密码
 立即注册
查看: 3161|回复: 2

[技术交流] 实验17

[复制链接]
发表于 2020-9-23 20:25:28 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 sbx 于 2020-9-23 20:32 编辑

实验17  通过逻辑扇区号对软盘进行读写
;功能:安装新的int 7ch中断例程,实现通过逻辑扇区号对软盘进行读写
;入口参数:
;    (dx)=读写扇区的逻辑扇区号
;    (ah)=0表示读扇区,(ah)=1表示写扇区
;    es:bx指向存储读出数据或写入数据的内存区
;返回参数:
;    (ah)=int 13h的功能号(2表示读扇区,3表示写扇区)
;    (ch)=磁道号
;    (cl)=扇区号
;    (dh)=磁头号(面号)

assume cs:code
code segment
start:
        mov ax,cs
        mov ds,ax
        mov si,offset do7h             ;设置ds:si指向源地址

        mov cx,offset do7hend - offset do7h ;设置cx为传输长度

        mov ax,0
        mov es,ax
        mov di,200h                     ;设置es:di指向目标地址

        cld                             ;设置传输方向为正
        rep movsb
       
        ;在中断向量表中设置新的int 7ch中断例程的入口地址
        cli           ;设置IF=0屏蔽中断
        mov word ptr es:[7ch*4],200h
        mov word ptr es:[7ch*4+2],0
        sti            ;设置IF=1不屏蔽中断

        ;结束
        mov ax,4c00h
        int 21h

;新的int 7ch中断例程
do7h:
        push bx
        cmp ah,1
        ja sret       ;功能号ah大于1,结束
        cmp dx,1443   ;逻辑扇区号大于1443,结束
        ja sret
        cmp ah,0
        je s1
        cmp ah,1
        je s2



s3:push bx
        mov ax,dx      ;逻辑扇区号赋值到ax中
        mov dx,0
        mov bx,1440
        div bx         ;商在ax,余在dx
        push ax      ;ax=面号=int(逻辑扇区号/1440),入栈保存
        mov ax,dx    ;rem(逻辑扇区号/1440),余数
        mov bx,18    ;
        div bx       ;商在ax,余在dx
        push ax     ;ax=磁道号=int(rem(逻辑扇区号/1440)/18),入栈保存
        add dx,1     ;dx=扇区号=rem(rem(逻辑扇区号/1440)/18)+1

        mov al,1      ;al扇区数赋值为1
        mov cl,dl     ;扇区号赋值给cl
        pop bx        ;磁道号出栈
        mov ch,bl     ;磁道号赋值给ch
        pop bx        ;面号出栈
        mov dh,bl     ;面号赋值给dh
        mov dl,80h     ;dl驱动器号设置为80h,硬盘c读出或写入
        pop si        ;es:bx偏移出栈
        pop bx        ;功能号出栈
        mov ah,bh     ;功能赋值给ah
        mov bx,si     ;偏移赋值给bx
        int 13h
sret:   
        pop bx
        iret
               

s1:mov ah,2   ;int 13h的功能号(ah=2表示读扇区)
        push ax       ;功能号,入栈
        jmp s3
s2:mov ah,3   ;int 13h的功能号(ah=3表示写扇区)
        push ax       ;功能号,入栈
        jmp s3

do7hend: nop

code ends
end start


;测试程序代码:

assume cs:code
code segment
start:
mov bx,0b800h
mov es,bx
mov bx,0      ;es:bx指向存储读出数据或写入数据的存在区

mov ah,0         ;传递功能号(0表示读,1表示写)
mov dx,0                ;读写扇区的逻辑扇区号

int 7ch

mov ax,4c00h
int 21h

code ends
end start
未命名图片1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-9-25 17:16:10 | 显示全部楼层
本帖最后由 sbx 于 2020-9-25 17:17 编辑

读取A盘0面0道1扇区的内容显示到屏幕上

assume cs:code
code segment
start:
        mov ax,cs
        mov ds,ax
        mov si,offset do7h             ;设置ds:si指向源地址

        mov cx,offset do7hend - offset do7h ;设置cx为传输长度

        mov ax,0
        mov es,ax
        mov di,200h                     ;设置es:di指向目标地址

        cld                             ;设置传输方向为正
        rep movsb
       
        ;在中断向量表中设置新的int 7ch中断例程的入口地址
        cli           ;设置IF=0屏蔽中断
        mov word ptr es:[7ch*4],200h
        mov word ptr es:[7ch*4+2],0
        sti            ;设置IF=1不屏蔽中断

        ;结束
        mov ax,4c00h
        int 21h

;新的int 7ch中断例程
do7h:
        push bx
        cmp ah,1
        ja sret       ;功能号ah大于1,结束
        cmp dx,1443   ;逻辑扇区号大于1443,结束
        ja sret
        cmp ah,0
        je s1
        cmp ah,1
        je s2



s3:push bx
        mov ax,dx      ;逻辑扇区号赋值到ax中
        mov dx,0
        mov bx,1440
        div bx         ;商在ax,余在dx
        push ax      ;ax=面号=int(逻辑扇区号/1440),入栈保存
        mov ax,dx    ;rem(逻辑扇区号/1440),余数
        mov bx,18    ;
        div bx       ;商在ax,余在dx
        push ax     ;ax=磁道号=int(rem(逻辑扇区号/1440)/18),入栈保存
        add dx,1     ;dx=扇区号=rem(rem(逻辑扇区号/1440)/18)+1

        mov al,1      ;al扇区数赋值为1
        mov cl,dl     ;扇区号赋值给cl
        pop bx        ;磁道号出栈
        mov ch,bl     ;磁道号赋值给ch
        pop bx        ;面号出栈
        mov dh,bl     ;面号赋值给dh
        mov dl,0    ;dl驱动器号设置为0,软盘A读出或写入
        pop si        ;es:bx偏移出栈
        pop bx        ;功能号出栈
        mov ah,bh     ;功能赋值给ah
        mov bx,si     ;偏移赋值给bx
        int 13h
sret:   
        pop bx
        iret
               

s1:mov ah,2   ;int 13h的功能号(ah=2表示读扇区)
        push ax       ;功能号,入栈
        jmp s3
s2:mov ah,3   ;int 13h的功能号(ah=3表示写扇区)
        push ax       ;功能号,入栈
        jmp s3

do7hend: nop

code ends
end start


;测试程序代码:

assume cs:code
code segment
start:
mov bx,0b800h
mov es,bx
mov bx,0      ;es:bx指向存储读出数据或写入数据的存在区

mov ah,0         ;传递功能号(0表示读,1表示写)
mov dx,0                ;读写扇区的逻辑扇区号

int 7ch

mov ax,4c00h
int 21h

code ends
end start


截图未命名23.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-25 17:26:09 | 显示全部楼层
若写入A软盘 0面0磁道1扇区,程序运行后,软盘A需重新格式化才能使用。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-23 12:20

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表