汇编仿FDISK及PQMAGIC列出分区逻辑盘符的prw.asm实现
2007-11-13 09:31:21 来源:WEB开发网核心提示:(5) 例:笔者486,在pri_ds上,装ST32140A驱动器(2012M),在sec_ds上,装QUANTUM(514M).(5.1) 80h上,现有vol=6的DOS活跃主分区(FAT16B,1299M),vol=6的主分区(F16B,39.4M),vol=17h的非DOS分区(HiddenNTFS,574.9
(5) 例:
笔者486,在pri_ds上,装ST32140A驱动器(2012M),在sec_ds上,装QUANTUM(514M).
(5.1) 80h上,现有vol=6的DOS活跃主分区(FAT16B,1299M),vol=6的主分区(F16B,39.4M),vol=17h的非DOS分区(HiddenNTFS,574.9M),vol=5的扩展分区,其托4个逻辑分区,按链上次序是:
vol=0bh的DOS主分区(F32,35.4M),vol=83h的非DOS分区(LINUX_Ext2,19.7M),vol=1的DOS主分区(Unfmt,3.9M),vol=6的主分区(41.3M)
(5.2) 81h上,现有vol=82h的非DOS分区(L_Swap,3M),vol=11h的非DOS分区(Unfmt,3M),vol=6的活跃主分区(472.5M),vol=0fh的扩展分区,其托4个逻辑分区,按链上次序:
vol=82h的非DOS分区(L_Swap,10.8M),vol=1的主分区(F12,8.8M),vol=7的非DOS分区(N,9,8M),vol=1的主分区(U,7.8M).
从98软盘启动,F$,P$,列出这些分区的盘符及容:
C:1299M
D;472.5M
E:35.4M
F:3.9M
G:41.3M
J:39.4M
H:8.8M
I:7.8M
(6) prw功能
命令行是prw.exe [foo1]
初见:
b(pb),p(arti),r(ead sec to foo/stdout),w(rite foo to sec),v(xd w)
命令键b,p,r,w,v:
(6.1) b,显subBPB
(6.2) p,显分区盘编号,逻辑盘符,BootON值,vol值,Front值,In值,例如
80,C:,Boot:80,FAT:06,Front:0000003f,In:00101661
(6.3) r,读软硬盘内容到新建foo,或stdout
(6.4) wv,写已存foo到软硬盘.v多依VxD,胜v86禁13h写.算法,见"(8) 论V86下,直寻硬盘扇区,只能靠VxD"
rwv,用旧FCB式,读源F16,F32,写F16.逐扇有结果I/O,直至出错或事成.
欲读80h的MBR到文件b:d,先发:
prw b:d
再答r,界面:
drv(00~01,80~83)80
0~cyl(0029)
0~hd(1f)
1~sec(3f)
0~lba(00014abf)
c(hs),l(ba)l
0~lba(00014abf)00000000
0~cyl(0000)
0~hd(00)
1~sec(01)
0~lba(00000000)
1~total(ffff)0001
事成/中止,d长度512/0.
v86时,改向buf文符到F32的文件g,可发prw c:u>g
(7) 文
NIBSZ=8 ;8个hex数
nibasc macro
local nq
add al,48
cmp al,10+48
jb nq
add al,97-48-10
nq:
endm
alasc macro
mov ah,al
and al,15
nibasc
xchg ah,al
rept 4
shr al,1 高nibble
endm
nibasc
stosw
endm
axasc macro
push ax
mov al,ah 转ah
alasc
pop ax 转al
alasc
endm
d segment
buf db 511 dup(0) 放MRB.全囿V86页(4k),buf长1023,囿DMA_64k
buf511 db 0 老buf尾
info_sz dw 26 ;min sz of info buf 新buf
flags dw 0 ;flags
cylinders0 dw 0 ;number of cylinders on disk
cylinders1 dw 0
heads00 db 0 ;number of heads on disk
heads01 db 0
heads1 dw 0
s1track00 db 0 ;number of sectors per track
s1track01 db 0
s1track1 dw 0
sectors dq 0 ;number of sectors on requested disk
sector_sz dw 0 ;number of bytes per sector
db 511-26 dup(0) ;新buf
FAT db 13,10,'0~0eh:'
db 13,10,'?OS,F12/Unfmt,,,F16/U_,EXtend,F16B,NTFS,,,,F32,F32_13X,,F16'
db 13,10,'11,14,16,17,1b:(Hidden)'
db 13,10,'F12/U_,F16,F16B,N,F32$'
.view db '0000,cx='
viewcx db '13EX,dx='
viewdx db 'tend'
CR db 13,10,36
extblk db 16,0 分区表16字节用
sec_tot dw 1
buf_off dw buf ;buf偏移
buf_seg dw SEG buf
lbal dw 0 ;lba低双字低字
lbah dw 0 ;lba低双字高字
dd 0 ;lba高双字
cmd_p db 'b(pb),p(arti),r(ead sec to foo/stdout),w(rite foo to sec),v(xd w)$';rwv用
logi_p db 13,10,'logi_drv(A:=01)$'
subBPB db 13,10,'SV_sec:'
SV_sec db 0,'000,FATs:' 向foo读
FATs db '00,sec_per_FAT:'
sec1FAT db '0000$'
drv_p db 13,10,'drv(00~01,80~83)$' ;扩展i13用
mod_p db 13,10,'c(hs),l(ba)$' ;dosext,nondos用
db 13,10
from80 db '8?,'
logidrv db 'C:,Boot:'
Boot db '?0,FAT:'
volume db '06,Front:'
Front_h dw ?,? 又做总扇数
Front_l db '0000,In:'
In_h dw 0,? 又做当前扇号
In_l db '0000$'
cyl_p db 13,10,'0~cyl('
cyl_p1 db '????)$'
hd_p db 13,10,'0~hd('
hd_p1 db '??)$'
sec_p db 13,10,'1~sec('
sec_p1 db '??)$'
lba_p db 13,10,'0~lba('
lbah_p1 db '????'
lbal_p1 db '????)$'
total_p db 13,10,'1~total(ffff)$'
scr_p db '^C,f(ast),n(ext)$'
primk db 1,4,6,11,12,14 主分区标识
primksz=$-primk
extmk db 5,15 扩展分区标识
extmksz=$-extmk
stk1 dw NIBSZ/4 dup(0) ;INnib栈
db 32
rowasc db (2+1)*16 dup(32),36
kbd db NIBSZ+1 ;键盘buf
kbd1 db 67 parti用
kbd2 db NIBSZ+1 dup(0)
fcbdrv db 0
fcbnam db 8 dup(32)
fcbext db 3 dup(32)
fcbblk dw 0
fcbrsz dw 512
fcbsz db 4 dup (4) 已占分区表号,4硬盘*1字节,parti用
fcbdat dw 0
fcbdos1 db 10 dup(0)
fcbrno db 0
entry label dword ;fcbrand
entrydi dw 0
entryes dw 0
media_h db 0 ;头数
media_c dw 0 ;柱数
s1cyl dw 0 ;扇数/柱
s1track db 0 ;扇数/道
drv db 0 ;输入
hd db 0
cyl dw 0
sec db 0
hextbl db '0123456789abcdef'
d ends
c segment
assume cs:c,ds:d,es:d
@ proc far
push ds ;为exe返回
xor ax,ax 压cd20的psp:0
push ax
mov ax,d
mov es,ax
cmp byte ptr ds:[5dh],32 缺foo
je @0
inc es:SV_sec
mov cx,1+8+3
mov si,5ch sh复制盘符+大写8.3名到5ch
lea di,fcbdrv
rep movsb es:di=ds:si的盘符+8.3
@0: mov ds,ax
mov ah,9
lea dx,cmd_p ;问命令
int 21h
mov ah,1
int 21h
cmp al,'b'
je b
jmp p
b: mov kbd,2 + 1
lea dx,logi_p 问逻辑盘
Call INnib
mov ax,440dh
mov cx,860h 传统及扩展13,共享BPB前12字节
lea dx,buf
int 21h
mov ax,word ptr buf[7+3]
lea di,SV_sec
axasc
mov al,buf[7+5]
lea di,FATs
alasc
mov ax,word ptr buf[7+11]
or ax,ax
jnz bo
mov ax,word ptr buf[7+25]
bo: lea di,sec1FAT
axasc
mov ah,9
lea dx,subBPB
int 21h
ret
p: cmp al,'p'
jne r
mov ah,9
lea dx,FAT
int 21h
lea bx,buf
mov dx,80h 扩展i13,可兼容传统
Call dospri
mov mod_p,dl
mov dl,80h
Call dosext
mov lbal,0
mov lbah,0
mov dl,80h
Call nondos
ret
r: mov cmd_p,al
cmp al,'r'
je rwv
cmp al,'w'
je rwv
cmp al,'v'
je v
ret
v: mov ax,1684h ;func
mov bx,3180h ;接口ID
int 2fh
mov ax,es ;es:di=V86口cs:ip
or ax,di
jnz v1
ret es,di全0,失败
v1: mov entrydi,di
mov entryes,es
push ds
pop es
rwv: mov kbd,2 + 1
lea dx,drv_p 问磁盘
Call INnib
mov drv,bl
mov dl,bl 驱动器
test bl,80h
jne rwv1
xor dh,dh 头
Call f_geo
jmp rwv2
rwv1: Call h_geo
rwv2: test media_h,255
jne rwv3
ret
rwv3: mul s1cyl
sub ax,1 ;lba始于0,可写CF
sbb dx,0
mov lbal,ax
mov lbah,dx
Call lba2chs
Call rng
mov ah,9 ;问寻扇
lea dx,mod_p
int 21h
mov ah,1
int 21h
cmp al,'c'
je rwv4
mov kbd,8 + 1
lea dx,lba_p
call INnib ;问lbah,lbal
mov lbal,bx
mov ax,stk1
mov lbah,ax
Call lba2chs
jmp rwv5
rwv4:mov kbd,4 + 1
lea dx,cyl_p ;问柱面号
Call INnib
mov cyl,bx
mov kbd,2 + 1
lea dx,hd_p ;问头号
Call INnib
mov hd,bl
mov kbd,2 + 1
lea dx,sec_p ;问扇号
Call INnib
mov sec,bl
Call chs2lba
rwv5:Call rng ;显出立体,线性值
mov kbd,4 + 1
lea dx,total_p ;问总计
Call INnib
mov Front_h,bx
lea dx,fcbdrv ;指向fcb
mov ah,15 ;open for w,v
cmp cmd_p,'r'
jne rw1
test SV_sec,1 向foo读
jz rw2
mov ah,16h ;create or trunc for r,软盘启动,拒存取F32盘
rw1: int 21h 改fcbdrv为3=C
or al,al al为0,成功
jnz rw7
mov fcbrsz,512 重置
rw2: mov ax,600h al=clr
mov bx,700h bl=page
xor cx,cx
mov dx,184fh 25*80
int 10h cursor grow 0,24
mov ah,1ah ;DTA
lea dx,buf
mov bx,dx ;I/O数据区
int 21h
rw3: test Front_h,65535
jz rw6
cmp cmd_p,'r'
jne rw4
mov ax,201h
mov dl,drv
Call rw1by1
je rw6
Call scr
test SV_sec,1 ;向foo读
jz rw5
mov ah,15h ;强制write
lea dx,fcbdrv
int 21h
jmp rw5
rw4: mov ah,14h ;read
lea dx,fcbdrv
int 21h
Call scr
mov ax,301h
mov dl,drv
Call rw1by1
je rw8 ;出错,关闭
rw5: add lbal,1
adc lbah,0
inc In_h
dec Front_h
jmp rw3
rw6: test SV_sec,1 向foo读
jnz rw8
rw7: ret
rw8: mov ah,16 ;close
lea dx,fcbdrv
int 21h
ret
@ endp
dospri proc ;统计硬盘数,查DOS主分区
dospri0:cmp dl,80h+4
je dospri7
mov ax,201h ;测硬盘
mov cx,1
int 13h
jc dospri7
mov bp,4*16
xor si,si ;分区表,占4*16字节
dospri1:cmp si,4*16
je dospri4
mov al,buf[1beh+si+4] 取vol
mov cx,primksz 是主分区?
lea di,primk
repne scasb
jne dospri3
test byte ptr buf[1beh+si],80h ;取BootON
jnz dospri2
cmp bp,4*16
jnz dospri3
dospri2:mov bp,si ;暂选首现主分区
jnz dospri5
dospri3:Add si,16
jmp dospri1
dospri4:cmp bp,4*16
je dospri6
dospri5:mov si,dx
sub si,80h
mov ax,bp
div extblk
mov fcbsz[si],al 标占分区表项号
mov al,kbd1
mov logidrv,al
inc kbd1
Call Show
dospri6:inc dl ;读下块硬盘
jmp dospri0
dospri7:ret
dospri endp
pri_non proc
mov logidrv,32
mov cx,primksz
lea di,primk
repne scasb
jne non ;不赋非DOS分区盘符
mov logidrv,94 ^符
mov al,kbd1
cmp al,'Z'
ja non
mov logidrv,al
inc kbd1
non: Call Show
ret
pri_non endp
dosext proc 查DOS扩展分区
dosext0:cmp dl,mod_p
je dosext4
mov ax,201h
mov cx,1
int 13h
xor bp,bp
dosext1:cmp bp,4*16
je dosext3
mov al,buf[1beh+bp+4]
mov cx,extmksz 是扩展分区?
lea di,extmk
repne scasb
jne dosext2
push bx
push dx
Call h_geo
pop dx
pop bx
mov ax,word ptr buf[1beh+bp+8] ;Front low
mov entrydi,ax 基址
mov lbal,ax
mov ax,word ptr buf[1beh+bp+10] ;Front high
mov entryes,ax
mov lbah,ax
xor bp,bp ;为show
Call chain
jmp dosext3
dosext2:Add bp,16
jmp dosext1
dosext3:inc dl
jmp dosext0
dosext4:ret
dosext endp
h_geo proc
mov ah,41h
mov bx,55aah ;测BIOS支持i13_X
int 13h
jc h_geoo
cmp bx,0aa55h 再核
jne h_geoo
test cx,1 ;支持41~44,47~48第1子集?
jz h_geoo
mov ah,48h 取尺寸
lea si,info_sz
int 13h
mov al,heads00 ;头数
or al,al
jz h_geoo 无效info包
mov media_h,al
inc drv_p 启扩展
mov ah,s1track00 ;每道扇数
mov s1track,ah
mul ah
mov s1cyl,ax 每柱面扇数
mov ax,cylinders0 ;柱面数
mov media_c,ax
ret
h_geoo: mov ah,8 取尺寸
int 13h
jc h_geoq
inc dh
mov al,dh
mov media_h,al ;头数
mov s1track,cl
and s1track,63 每道扇数
mul s1track
mov s1cyl,ax ;每柱面扇数
xchg ch,cl
rol ch,1
rol ch,1
and ch,3
mov ax,cx
inc ax
mov media_c,ax ;柱面数
h_geoq: ret
h_geo endp
chain proc ;处理链
chain0: mov ax,201h
Call rw1by1
mov al,buf[1beh+4]
call pri_non
test buf[1beh+16+4],255 ;0,5,15之1
je chain1
mov ax,word ptr buf[1beh+16+8]
add ax,entrydi ;加基址entrydi
mov lbal,ax
mov ax,word ptr buf[1beh+16+10]
adc ax,entryes ;加基址entryes
mov lbah,ax
jmp chain0
chain1: ret
chain endp
nondos proc 查未占过盘符的DOS主分区及非DOS分区
nondos0:cmp dl,mod_p
je nondos4
mov ax,201h
mov cx,1
int 13h
mov bp,dx
sub bp,80h
mov al,fcbsz[bp] 取已占分区表号
mul extblk
mov fcbdat,ax
xor bp,bp
nondos1:cmp bp,4*16
je nondos3
cmp bp,fcbdat
je nondos2 ;已占
mov al,buf[1beh+bp+4]
test al,255 不理闲置分区
jz nondos2
mov cx,extmksz ;略扩展分区
lea di,extmk
repne scasb
jz nondos2
call pri_non
nondos2:Add bp,16
jmp nondos1
nondos3:inc dl
jmp nondos0
nondos4:ret
nondos endp
show proc ;分区信息
push dx
and dl,3 盘号80~83
add dl,48
mov from80[1],dl
mov Boot,48 多数为0
test buf[1beh+bp],80h
jz show0
mov Boot,56
show0: mov al,buf[1beh+bp+4] ;显vol
lea di,volume
alasc
mov ax,word ptr buf[1beh+bp+8] ;取Front low
add ax,lbal ;为chain而加
pushf
lea di,Front_l
axasc
mov ax,word ptr buf[1beh+bp+10] ;Front high
popf
adc ax,lbah ;为chain而加
lea di,Front_h
axasc
mov ax,word ptr buf[1beh+bp+12] ;取In low
lea di,In_l
axasc
mov ax,word ptr buf[1beh+bp+14] ;In high
lea di,In_h
axasc
mov ah,9
lea dx,from80
sub dx,2
int 21h
pop dx
ret
Show endp
rw1by1 proc 读/写1扇
test drv_p,1 13=传统
jnz rw1by11
xor al,al 不校验写
or ah,40h
lea si,extblk ;扩展块
jmp rw1by12
rw1by11:push ax
push dx
call lba2chs
pop dx
pop ax
call cxdh
mov word ptr viewcx,cx
mov word ptr viewdx,dx
rw1by12:cmp cmd_p,'v'
je rw1by13
int 13h
ret 遗c
rw1by13:Call [entry]
cmp bp,4096 VxD按(8.3)返bp值
jae rw1by14
push bx
add bx,bp ;使bx,bx+511在4k内
mov buf_off,bx 扩展i13
push cx
push si
lea si,buf511 ;原buf尾
mov di,si
add di,bp ;新buf尾
std ;从后向前移1扇
mov cx,256
rep movsw
cld
pop si
pop cx
Call [entry]
pop bx
mov buf_off,bx 扩展i13
cmp bp,4096
rw1by14:je rw1by15
cmp bp,1010h
jne rw1by16
xor ah,ah
Call [entry] 释它页
rw1by15:cmp al,al 置zr
rw1by16:ret
rw1by1 endp
f_geo proc
lea bx,buf ;缓区
mov cx,1 ;0:0:1(chs)引导扇
f_geo0: mov ax,201h ;读1扇
int 13h ;读11起的bios参数块
jc f_geo0 ;换盘
mov al,[bx+26] ;偏移26:头数
mov media_h,al
mov ah,[bx+24] ;偏移24:每道扇数
mov s1track,ah
mul ah
mov s1cyl,ax ;每柱面扇数
mov ax,[bx+19] ;偏移19:总扇数
xor dx,dx ;高字
div s1cyl
mov media_c,ax ;柱面数
ret
f_geo endp
rng proc
mov ax,cyl ;当前柱面
lea di,cyl_p1
axasc
mov al,hd ;当前头
lea di,hd_p1
alasc
mov al,sec ;当前扇号
lea di,sec_p1
alasc
mov ax,lbah ;当前lba高字
lea di,lbah_p1
axasc
mov ax,lbal ;当前lba低字
lea di,lbal_p1
axasc
mov ah,9
lea dx,cyl_p
int 21h
lea dx,hd_p
int 21h
lea dx,sec_p
int 21h
lea dx,lba_p
int 21h
ret
rng endp
scr proc
mov cx,16 字符数/row
xor si,si
scr0: push bx
mov ah,2
xor bh,bh pg
xor dx,dx dh=row
int 10h
pop bx
lea dx,.view
test si,256
jz scr1
jmp scr3
scr1: mov di,dx
mov ax,In_h 现扇号
axasc
test drv_p,1
jnz scr2
jmp scr3
scr2: lea di,viewcx
mov ax,word ptr [di]
axasc
lea di,viewdx
mov ax,word ptr [di]
axasc
scr3: mov ah,9
int 21h
scr4: mov ax,si
lea di,stk1
axasc
lea bp,rowasc
scr5: mov al,[bx+si]
mov di,si
and di,15
mov FAT[di],46
cmp al,32
jb scr6
mov FAT[di],al
scr6: mov di,bp
alasc
Add bp,2+2-1
inc si
test si,15
jne scr5
mov ah,9 行的hex
lea dx,stk1
int 21h
push bx
mov ah,64 行的asc及汉字
mov bx,1
lea dx,FAT
int 21h
pop bx
mov ah,9
lea dx,CR
int 21h
test si,255
je scr7
jmp scr4
scr7: cmp scr_p,'f'
je scr8
mov ah,9
lea dx,scr_p
int 21h
mov ah,1 ;按1键
int 21h
cmp al,'f'
jne scr8
mov scr_p,al
scr8: test si,511
je scr9
jmp scr0
scr9: ret
scr endp
cxdh proc
mov dh,hd ;头号
mov cx,cyl ;柱面号
xchg cl,ch
ror cl,1
ror cl,1
and cl,not 63
or cl,sec ;低6位扇号
ret
cxdh endp
lba2chs proc
mov ax,lbal
mov dx,lbah
div s1cyl ;柱面号
mov cyl,ax
mov ax,dx
div s1track
mov hd,al ;头号
inc ah
mov sec,ah ;扇号
ret
lba2chs endp
chs2lba proc
mov ax,cyl ;柱面号
mul s1cyl
mov lbal,ax
mov lbah,dx
mov al,s1track ;每道扇数
mul hd
Add lbal,ax
adc lbah,0
mov al,sec ;此处,低6位扇号
dec al
cbw
Add lbal,ax
adc lbah,0
ret
chs2lba endp
INnib proc ;kbd限长nib入kbd2.转后入stk1,低字还入bx
INnib0: mov ah,9
int 21h
push dx
inc ah ;回车才收
lea dx,kbd
int 21h
pop dx
mov al,kbd
dec al
cmp al,kbd1 ;实长
jnz INnib0
xor bp,bp
lea si,kbd2
INnib1: lodsb
mov cx,16
lea di,hextbl
repne scasb
jnz INnib0
dec kbd1
inc cx ;转'[0-9a-f]'为0~15
sub cx,16
neg cx
rept 4
shl bx,1 ;bx接收nibble,左入0
endm
or bl,cl
test kbd1,3 ;已收4个nibble
jnz INnib1
mov stk1[bp],bx
add bp,TYPE stk1
test kbd1,NIBSZ*2-1
jnz INnib1
ret
INnib endp
c ends
end @
更多精彩
赞助商链接