📄 findbad.asm
字号:
;版本 V1.3 增加使用说明
;版本 V1.2 需手动修改NO_F中参数值,并采用
;运行提示输入NO_F中参数值=》初始化=》测试=》复制数据区testhd至testhd_bak=》
;写坏柱连续扇区标识到FAT1表=》初始化=》复制数据区testhd_bak至testhd
;=》复制begin_FAT1_rs至begin_FAT2_rs写坏柱连续扇区标识到FAT2表
;针对FAT32分区格式 ,且FAT区+DBR区所在柱面不可有坏扇区
;C:盘(chs最大8G)寻找坏扇区并在FAT 记录表中标识0FFFFFF7H,以1柱为标识单位。
;我的笔记本硬盘分区参数 FBR_1beH:80 01 01 00 0B 7F BF 0C 3F 00 00 00 41 99 40 00
; DBR: bn_A=00020h bn_B=101fh bn_C=02h bn_E=08h sector=0200H nh=80h ns=3fh
;-------------------------------
;常量定义区
;color8 equ 1fh ;'LiGuohui'
;-------------------------------
;------------------------------
;数据定义区
data segment para 'data'
file db 100h dup(88h)
NO_F db 02h ;确认检查分区表中第几分区检查,默认第1分区
NO_F_DAT db 16 dup(0h) ;指定分区分区表数据
sector dw 200h ;每扇区字节512=200h,DBR偏移量0B-0CH
nc dw 20dh ;本硬盘柱面总数,柱面0~524=525=20dh
nh db 80h ;本硬盘磁头总数,磁头0~127=128=80h,DBR偏移量1A-1BH
ns db 3fh ;本硬盘单一磁道扇区总数,扇区1~63=63=3FH,DBR偏移量18-19H
int13_c db 00h ;中断13H格式访问硬盘时柱面参数值,注真实柱面由int13_s高2bit和int13_c组成
int13_h db 00h ;中断13H格式访问硬盘时磁头参数值
int13_s db 01h ;中断13H格式访问硬盘时扇区参数值
phy_c dw 00h ;硬盘物理真实柱面值
phy_h db 01h ;硬盘物理真实磁头值
phy_s db 01h ;硬盘物理真实扇区值
phy_1c_ns dw 00h;硬盘物理真实1柱面值扇区总数
dos_start_c dw 00h ;DOS分区开始柱面值
dos_start_h db 01h ;DOS分区开始磁头值
dos_start_s db 01h ;DOS分区开始扇区值
dos_end_c dw 20dh ;DOS分区结束柱面值
dos_end_h db 7fh ;DOS分区结束磁头值
dos_end_s db 3fh ;DOS分区结束扇区值
dos_rs_L16 dw 00h ;DOS分区逻辑扇区值,0-***双字
dos_rs_H16 dw 00h
dos_CH_L16 dw 00h ;DOS分区簇号,0-***双字
dos_CH_H16 dw 00h
bn_A dw 20h ;DOS分区保留扇区,DBR偏移量0E-0FH
bn_B dw 04b3h ;DOS分区中1个FAT表占用扇区数,DBR偏移量24-25H
bn_C db 02h ;DOS分区中FAT表个数,DBR偏移量10H
bn_E db 08h ;DOS分区中每簇扇区数,DBR偏移量0DH
testhd db 1024 dup(30h) ;硬盘物理真实柱面值坏柱记录区0-1023=1024=200H
testhd_bak db 1024 dup(30h)
;testhd db 0fh dup(30h),31h,1f0h dup(30h)
err_FAT32 db 'Disk isn`t FAT32!',0dh,0ah,'$'
temp_DAT db 512 dup(0h) ;读写扇区缓冲区
err_NH db 'Head must small than 100h!',0dh,0ah,'$'
err_ns db 'sector must small than 40h!',0dh,0ah,'$'
err_nc db 'Cyli must small than 400h !',0dh,0ah,'$'
err_dos_start_c db 'start cy is bad !',0dh,0ah,'$'
test_c db 00h ;测试坏扇区时柱面变量ch
test_h db 00h ;dh
test_s db 01h ;cl
begin_FAT1_rs_L16 dw 00h ;FAT1区开始逻辑扇区-双字
begin_FAT1_rs_H16 dw 00h
begin_FAT2_rs_L16 dw 00h ;FAT2区开始逻辑扇区-双字
begin_FAT2_rs_H16 dw 00h
BAD_C dw 01h ;坏柱面号
dos_CH_bg_L16 dw 00h ;坏柱开始簇号值-双字
dos_CH_bg_H16 dw 00h
dos_CH_ED_L16 dw 00h ;坏柱终止簇号值-双字
dos_CH_ED_H16 dw 00h
FAT1_BAD_CH_rs1_L16 DW 00H ;坏簇在FAT1表中开始相对逻辑扇区-双字
FAT1_BAD_CH_rs1_H16 DW 00H
FAT1_BAD_CH_rs2_L16 DW 00H ;坏簇在FAT1表中终止相对逻辑扇区-双字
FAT1_BAD_CH_rs2_H16 DW 00H
FAT2_BAD_CH_rs1_L16 DW 00H ;坏簇在FAT2表中开始相对逻辑扇区-双字
FAT2_BAD_CH_rs1_H16 DW 00H
FAT2_BAD_CH_rs2_L16 DW 00H ;坏簇在FAT2表中终止相对逻辑扇区-双字
FAT2_BAD_CH_rs2_H16 DW 00H
WRITE_SECTOR_BG_NO DW 00H
WRITE_SECTOR_ED_NO DW 00H
Bad_DAT DD 80H DUP(0FFFFFF7H) ;在相对fat表中的某扇区全填写坏簇标志
dsp_test_c_DAT db 'Testing '
dsp_test_c_DAt1 db 20h,20h,20h,20h,'H of '
dsp_test_c_DAT2 db 20h,20h,20h,20h,'H',0dh,0ah,'$'
cpy_FAT1_FAT2_1_L16 dw 00h
cpy_FAT1_FAT2_1_H16 dw 00h
cpy_FAT1_FAT2_2_L16 dw 00h
cpy_FAT1_FAT2_2_H16 dw 00h
dsp_cpy_FAT1_FAT2_DAT db 'Writting '
dsp_cpy_FAT1_FAT2_DAT1 db 20h,20h,20h,20h,'H of '
dsp_cpy_FAT1_FAT2_DAT2 db 20h,20h,20h,20h,'H',0dh,0ah,'$'
write_FAT1_dat db 'Writting FAT1.....',0dh,0ah,'$'
write_FAT2_dat db 'Writting FAT2.....',0dh,0ah,'$'
select_No_DPT db 'Select Disk Partition Table:',0dh,0ah
db ' 0: No.1 DPT',0dh,0ah
db ' 1: No.2 DPT',0dh,0ah
db ' 2: No.3 DPT',0dh,0ah
db ' 3: No.4 DPT',0dh,0ah
db 'Input Number: $'
select_hc db 0dh,0ah,'$'
VGA11H_DAT db 38400 dup(0ffh),'程序设计:江苏新科李国辉'
;FAT32公式说明: dos_rs=nh*ns*(phy_c - dos_strat_c)
; + ns*(phy_h - dos_start_h) + (phy_s - dos_start_s)
; phy_s=(dos_rs MOD ns) + dos_start_s
; phy_h=((dos_rs DIV ns) MOD nh) + dos_start_h
; phy_c=((dos_rs DIV ns) DIV nh) + dos_start_c
; dos_CH=((dos_rs - bn_A - bn_C*bn_B) DIV bn_E)+2
; dos_rs=bn_A + bn_C*bn_B + (dos_CH - 2)* bn_E
data ends
;------------------------------
;------------------------------
;代码区
code segment para 'code'
assume cs:code; ds:data;ss:stack
beg: mov ax,data
mov ds,ax
push ax
pop es
call DSP_VGA11H ;显示使用说明图像 按数字8继续
beg_0: mov ah,09h ;initial No_F
mov dx,offset select_No_DPT
int 21h
mov ah,1h
int 21h
sub al,30h
cmp al,4h
jnc beg_0
mov no_F,al
mov ah,09h
mov dx,offset select_hc
int 21h
call ini_bn
call tests
mov si,offset testhd
mov di,offset testhd_bak
mov cx,200h
beg1: mov al,[si]
mov [di],al
inc di
inc si
dec cx
jnz beg1
mov ah,09h
mov dx,offset write_fat1_dat
int 21h
call write_bad
mov di,offset testhd
mov si,offset testhd_bak
mov cx,200h
beg2: mov al,[si]
mov [di],al
inc di
inc si
dec cx
jnz beg2
call ini_bn
mov ax,begin_fat2_rs_L16
mov dx,begin_fat2_rs_H16
mov begin_fat1_rs_L16,ax
mov begin_fat1_rs_H16,dx
mov ah,09h
mov dx,offset write_fat2_dat
int 21h
call write_bad
; call copy_fat1_fat2
mov ax,4c00h
int 21h
ret
READ_NO_F proc near
;将由no_f选定检查盘分区表中16字节信息读出至no_f_dat区
push ax
push bx
push cx
push dx
pushf
push si
push di
mov ah,00h
mov dl,80h
int 13h
mov ax,0201h
mov bx,offset temp_dat
mov cx,0001h
mov dx,0080h
int 13h
mov si,bx
add si,1beh
mov cl,no_f
mov al,10h
mul cl
add si,ax
mov di,offset no_f_dat
mov cl,10h
read_no_f1:mov al,[si]
mov [di],al
inc si
inc di
dec cl
jnz read_no_f1
pop di
pop si
popf
pop dx
pop cx
pop bx
pop ax
ret
READ_NO_F endp
int13chs_phy proc near
;将int13柱磁扇转换成物理真实柱磁扇
;输入:int13_c/h/s 输出:phy_c/h/s
push ax
push bx
push cx
push dx
pushf
push si
push di
mov ah,int13_h
mov phy_h,ah
mov ah,int13_s
mov al,ah
and ah,0c0h
and al,3fh
mov phy_s,al
mov al,int13_c
shr ah,1h
shr ah,1h
shr ah,1h
shr ah,1h
shr ah,1h
shr ah,1h
and ah,03h
mov phy_c,ax
pop di
pop si
popf
pop dx
pop cx
pop bx
pop ax
ret
int13chs_phy endp
phychs_int13 proc near
;将物理真实柱<=1023磁扇转换成int13柱磁扇
;输入:phy_c/h/s 输出:int13_c/h/s
push ax
push bx
push cx
push dx
pushf
push si
push di
mov ah,phy_h
mov int13_h,ah
mov ax,phy_c
mov int13_c,al
shl ah,1h
shl ah,1h
shl ah,1h
shl ah,1h
shl ah,1h
shl ah,1h
and ah,0c0h
mov al,phy_s
or ah,al
mov int13_s,ah
pop di
pop si
popf
pop dx
pop cx
pop bx
pop ax
ret
phychs_int13 endp
ini_bn proc near
;初始化变量区子程序
push ax
push bx
push cx
push dx
pushf
push si
push di
call read_no_f
mov si,offset no_f_dat
mov ah,[si+4h]
cmp ah,0bh
jz ini_bn_1
mov dx,offset err_fat32
mov ah,09h
int 21h
mov ax,4c00h
int 21h
ret
ini_bn_1:mov al,[si+1h]
mov int13_h,al
mov al,[si+2h]
mov int13_s,al
mov al,[si+3h]
mov int13_c,al
call int13chs_phy
mov ax,phy_c
mov dos_start_c,ax
mov al,phy_h
mov dos_start_h,al
mov al,phy_s
mov dos_start_s,al
;-------------------------
mov al,[si+5h]
mov int13_h,al
mov al,[si+6h]
mov int13_s,al
mov al,[si+7h]
mov int13_c,al
call int13chs_phy
mov ax,phy_c
mov dos_end_c,ax
mov al,phy_h
mov dos_end_h,al
mov al,phy_s
mov dos_end_s,al
;--------------------------
mov ax,0201h ;读入选定分区DBR至temp_dat
mov bx,offset temp_dat
mov dl,80h
mov dh,[si+1h]
mov cl,[si+2h]
mov ch,[si+3h]
int 13h
;--------------------------
mov si,offset temp_dat
mov ax,[si+0bh] ;读入sector
mov sector,ax
mov ax,[si+1ah] ;读入nh
cmp ax,100h
jb ini_bn_2
mov dx,offset err_nh
exit: mov ah,09h
int 21h
mov ax,4c00h
int 21h
ret
ini_bn_2:mov nh,al
;--------------------------
mov ax,[si+18h] ;读入NS
cmp ax,40h
jb ini_bn_3
mov dx,offset err_ns
jmp exit
ini_bn_3:mov ns,al
;--------------------------
mov cl,ns ;计算phy_1c_ns
mov al,nh
mul cl
mov phy_1c_ns,ax
;--------------------------
mov ax,[si+0eh] ;读入bn_A bn_B bn_C bn_E
mov bn_A,ax
mov ax,[si+24h]
mov bn_B,ax
mov al,[si+10h]
mov bn_C,al
mov al,[si+0dh]
mov bn_E,al
;--------------------------
;计算要测试的总柱面数nc
mov si,offset no_f_dat
mov bx,[si+0ah]
mov dx,[si+0eh]
add dx,bx
mov ax,[si+08h]
mov cx,[si+0ch]
add ax,cx
jnc ini_bn_4
inc dx
ini_bn_4:mov bx,phy_1c_ns
div bx
cmp dx,00h
jz ini_bn_5
inc ax
ini_bn_5:cmp ax,400h
jb ini_bn_6
mov dx,offset err_nc
jmp exit
ini_bn_6:mov nc,ax
;-------------------------
mov ax,bn_A ;初始化begin_Fat1_rs begin_Fat2_rs
mov begin_fat1_rs_l16,ax
mov ax,00h
mov begin_fat1_rs_h16,ax
mov dx,00h
mov ax,bn_B
add ax,bn_A
jnc ini_bn_7
inc dx
ini_bn_7:mov begin_FAT2_rs_L16,ax
mov begin_FAT2_rs_H16,dx
pop di
pop si
popf
pop dx
pop cx
pop bx
pop ax
ret
ini_bn endp
dsp_test_c_nc proc near
push ax
push bx
push cx
push dx
pushf
push si
push di
mov al,test_c
mov ah,test_s
shr ah,1h
shr ah,1h
shr ah,1h
shr ah,1h
shr ah,1h
shr ah,1h
and ah,03h
mov si,offset dsp_test_C_dat1
push ax
shr ah,1h
shr ah,1h
shr ah,1h
shr ah,1h
and ah,0fh
cmp ah,0ah
jb dsp_t1
add ah,7h
dsp_t1:add ah,30h
mov [si+0],ah
pop ax
push ax
and ah,0fh
cmp ah,0ah
jb dsp_t2
add ah,7h
dsp_t2:add ah,30h
mov [si+1h],ah
pop ax
push ax
shr al,1h
shr al,1h
shr al,1h
shr al,1h
and al,0fh
cmp al,0ah
jb dsp_t3
add al,7h
dsp_t3:add al,30h
mov [si+2h],al
pop ax
push ax
and al,0fh
cmp al,0ah
jb dsp_t4
add al,7h
dsp_t4:add al,30h
mov [si+3h],al
pop ax
;--------------------
mov ax,nc
mov si,offset dsp_test_C_dat2
push ax
shr ah,1h
shr ah,1h
shr ah,1h
shr ah,1h
and ah,0fh
cmp ah,0ah
jb dsp_t5
add ah,7h
dsp_t5:add ah,30h
mov [si+0],ah
pop ax
push ax
and ah,0fh
cmp ah,0ah
jb dsp_t6
add ah,7h
dsp_t6:add ah,30h
mov [si+1h],ah
pop ax
push ax
shr al,1h
shr al,1h
shr al,1h
shr al,1h
and al,0fh
cmp al,0ah
jb dsp_t7
add al,7h
dsp_t7:add al,30h
mov [si+2h],al
pop ax
push ax
and al,0fh
cmp al,0ah
jb dsp_t8
add al,7h
dsp_t8:add al,30h
mov [si+3h],al
pop ax
;--------------
mov dx,offset dsp_test_c_dat
mov ah,09h
int 21h
pop di
pop si
popf
pop dx
pop cx
pop bx
pop ax
ret
dsp_test_c_nc endp
dsp_cpy_fat1_fat2 proc near
push ax
push bx
push cx
push dx
pushf
push si
push di
mov ax,cpy_FAT1_FAT2_1_L16
mov si,offset dsp_cpy_fat1_fat2_dat1
push ax
shr ah,1h
shr ah,1h
shr ah,1h
shr ah,1h
and ah,0fh
cmp ah,0ah
jb dsp_c1
add ah,7h
dsp_c1:add ah,30h
mov [si+0],ah
pop ax
push ax
and ah,0fh
cmp ah,0ah
jb dsp_c2
add ah,7h
dsp_c2:add ah,30h
mov [si+1h],ah
pop ax
push ax
shr al,1h
shr al,1h
shr al,1h
shr al,1h
and al,0fh
cmp al,0ah
jb dsp_c3
add al,7h
dsp_c3:add al,30h
mov [si+2h],al
pop ax
push ax
and al,0fh
cmp al,0ah
jb dsp_c4
add al,7h
dsp_c4:add al,30h
mov [si+3h],al
pop ax
;--------------------
mov ax,cpy_fat1_fat2_2_L16
mov si,offset dsp_cpy_fat1_fat2_dat2
push ax
shr ah,1h
shr ah,1h
shr ah,1h
shr ah,1h
and ah,0fh
cmp ah,0ah
jb dsp_c5
add ah,7h
dsp_c5:add ah,30h
mov [si+0],ah
pop ax
push ax
and ah,0fh
cmp ah,0ah
jb dsp_c6
add ah,7h
dsp_c6:add ah,30h
mov [si+1h],ah
pop ax
push ax
shr al,1h
shr al,1h
shr al,1h
shr al,1h
and al,0fh
cmp al,0ah
jb dsp_c7
add al,7h
dsp_c7:add al,30h
mov [si+2h],al
pop ax
push ax
and al,0fh
cmp al,0ah
jb dsp_c8
add al,7h
dsp_c8:add al,30h
mov [si+3h],al
pop ax
;--------------
mov dx,offset dsp_cpy_fat1_fat2_dat
mov ah,09h
int 21h
pop di
pop si
popf
pop dx
pop cx
pop bx
pop ax
ret
dsp_cpy_fat1_fat2 endp
tests proc near
;测试dos_start_c~nc-1柱面坏道,并将结果记录在testhd中
;每个字节对一个柱面,"31H"表示坏柱
push ax
push bx
push cx
push dx
pushf
push si
push di
mov ah,00h ;硬盘复位
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -