sbx 发表于 2020-9-23 20:25:28

实验17

本帖最后由 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:,200h
        mov word ptr es:,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

sbx 发表于 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:,200h
        mov word ptr es:,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


sbx 发表于 2020-9-25 17:26:09

若写入A软盘 0面0磁道1扇区,程序运行后,软盘A需重新格式化才能使用。
页: [1]
查看完整版本: 实验17