仿98(DOS7.1)的F$.EXE(>512M模式运行),P_QUEST的P$.EXE
本文基于486DX2,主板,可带primary(启动)/secondary控制IDE器2,中断14/15,每个IDE,可带master(启动,电缆中)/slave(缆端)(跳线ds插/空)2通道,每通道,可带1台硬盘驱动器,每驱动器,可带1块NORMAL,LBA,LARGE模式的IDE硬盘.
DOS,98对硬盘,先按IDE,后按m/s,依次编号,不编闲置通道.例如,有3块盘,块1,2在pri_m/s上,块3在sec_cs上,此3块,编为80h~82h.
开机盘的IDE及通道,由BIOS的BOOTSEQ指定.
(1)DOS/98的读写F16/32格式的位置X的Y个连续扇区的BIOS中断13h参数:
ah的2/3指明读/写,al的低6位指明Y,es:bx指向内存buf首,cl的低6位指明X的扇号sector,最小1,ch,左拼cl第6,7位,齐指X的柱面号cylinder,最小0,dh指明磁头号head,最小0,dl指明软硬盘编号.
IDE原有的NORMAL,BIOS限定柱面数1024,磁头数16,扇区数63,每扇512字节,相乘=容量528MB.用作cmos_chs(cylinder:head:sector)立体寻扇.
LBA,仅磁头数异达255,容量8.4GB 财管家园 fs119.net
LARGE,柱面数>1024,磁头数16,控制器做柱面数/2,磁头数*2,以适13h.容量2048*16*63*512=1G
周边设定:Block模式加速,PIO(并行I/O接口)模式,影响rate
(2)针对LBA的扩展13h线性64位lba寻扇:
chs转时,lba=c*sectors_per_cylinderh*sectors_per_track(s-1)
其中,sectors_per_cylinder为每柱面扇数,sectors_per_track为每磁道扇数,因s从1编号,要减1.
互转,见"(7)文"的chs2lba,lba2chs.
利用extblk块:
extblkdb16;块的字节数(含此字节)
db0
sec_totdw1指明Y个扇区
buf_offdw0;内存buf偏移
buf_segdw0;buf段值
lbaldw0;lba低双字低字
lbahdw0;lba低双字高字
dd0;lba高双字
读/写时,ah=42h/43h,多ds:si指向extblk
扩展i13的BIOS支持性(柱数<1024,先用chs),及导出硬盘柱数,头数,每道扇数,算法见"(7)文"的h_geo
(3)硬盘分区:
每硬盘,最多划为DOS主分区,DOS扩展分区,非DOS分区之1的4区,述于16字节/区的64字节分区表(dpt): 财软联盟,fs119.net
bootONdb080H/0,是活跃/不活跃.
db?分区启动chs的头号
dw?低6位:扇区,低第6,7位与高字节,'齐指'柱面号
volumedb0分区标识值
db?结束chs
dw?
Frontdd0此分区之前(称隐藏)扇区数.INT_25H_dx=1,是在其后读逻辑首扇
Indd0此分区所含扇区数
MBR(F$制的1扇盘主引导记录,软盘0:0:1,硬盘DOS分区的首扇,即INT_25H_扇号dx=1),转cpu给Format.com制的驻有OS的活跃主分区引导记录(OBR).
主分区的保留区(引导扇区PBS囿其内,软盘仅藏1区)之后,常是2份FAT,再后,是根目录.
PBS片断:
0~2:JMP引导程序
3~0AH:厂,sys_ver
(BPB首)0BH~0CH:每扇bytes
0DH:每簇扇数
0EH~0FH:保留区扇数
10H:FAT份数
11H~12H:F16根目录32字节项的数目,F32:0.
13H~14H:软盘,32M内硬盘:分区总扇数
15H:介质,软盘:F0H,硬盘:F8H
16H~17H:软盘,32M内硬盘:每FAT占用扇
18H~19H:每道扇数
1AH~1BH:磁头数
1CH~1FH:此分区之前隐藏扇数
20H~23H:32M外硬盘:分区总扇数 财 管家园 fs119.net
24H~27H:32M外硬盘:每FAT占用扇
40H:磁盘BIOS,1st硬盘:80H,软盘:0
47H~51H:vol
52H~59H:file_sys
软盘6.22的io.sys,最先分得簇,如目录项0基第13字,指向1e,此12BIT的项值,是1f0002,指明01f->020->...->fff链.
分区标识值:
闲置:0
DOS主分区:1,4,6,0bh,0ch,0eh
DOS扩展分区:5,0fh
非DOS分区:其它
笔者用P,对硬盘划分4个DOS主分区,再prw,读此盘(0:0:0)到文件0,用debug,改分区vol值为2,用prw,回写0到(0:0:0),P的分区info页,显vol对应XENIX.
释意,见"(7)文"的FAT
若vol<20H,则高4位,1/0表示隐藏/非隐藏,后缀X,用于扩展i13接口.
各硬盘,均含0:0:1(chs)的1扇MBR,其偏移1be字节,连续存4个分区表.
各硬盘,最多1个DOS扩展分区,其内,能划分称为逻辑分区的数个DOS主分区,非DOS分区.
逻辑分区串成链.例如,vol=5的扩展分区E,先含1个DOS主分区D,后含1个非DOS分区N,则E的Front域值F,是E内的各逻辑分区位置基址,F指明扇区S1,而S1的偏移1be字节,是D的分区表,偏移1ce字节,其vol=0fh,表示DOS扩展分区,其Front域值,加上基址F,指明扇区S2,而S2的偏移1be字节,是N的分区表,偏移1ce字节,其vol=链尾0. 财软.联盟.fs119.net
(4)仿F$及P$,列出分区逻辑盘符:
盘符,C:~Z:列出.用F$,P$,能建数个逻辑分区
分区超过Z:符时,F$照列,P$不赋盘符,prw赋^符
活跃分区数>1时,引导错,但F$及prw照列,P$显错
F$,P$,依vol域,查以下3步,每步,查80h至83h:
(1)查DOS主分区
若是,则查bootON是否80H,若是,此分区就占1个逻辑盘符,若无活跃主分区,表项在MBR首现的主分区,就占1个逻辑盘符.
例如,3硬盘,80h的第1,3分区是主分区,但第3分区活跃,则第3分区占盘符C:.而81h,只含DOS扩展分区,其上,含1个DOS主分区及1个非DOS分区;82h的第2,4分区是不活跃主分区,则最先在MBR中出现的第2分区,占盘符D:
(2)查DOS扩展分区
按逻辑分区在链上次序,查它是否DOS主分区,若是,就占盘符,81h的DOS扩展分区上的DOS主分区,占盘符E:
(3)查未占过盘符的DOS主分区及非DOS分区
按MBR中,分区表项出现的先后次序,查分区是否DOS主分区,若是,且它未占过盘符,就占盘符.80h的第1分区,占盘符F:,82h的第4分区,占盘符G: 财.软联盟.fs119.net
F$,P$,prw,不给非DOS分区赋盘符,仅显In值.
(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(eadsectofoo/stdout),w(ritefootosec),v(xdw)
命令键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,先发:
prwb: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,可发prwc:u>g
(7)文
NIBSZ=8;8个hex数
nibascmacro
localnq
addal,48
cmpal,1048
jbnq
addal,97-48-10 财管家,园,fs119.net
nq:
endm
alascmacro
movah,al
andal,15
nibasc
xchgah,al
rept4
shral,1高nibble
endm
nibasc
stosw
endm
axascmacro
pushax
moval,ah转ah
alasc
popax转al
alasc
endm
dsegment
bufdb511dup(0)放MRB.全囿V86页(4k),buf长1023,囿DMA_64k
buf511db0老buf尾
info_szdw26;minszofinfobuf新buf
flagsdw0;flags
cylinders0dw0;numberofcylindersondisk
cylinders1dw0
heads00db0;numberofheadsondisk
heads01db0
heads1dw0
s1track00db0;numberofsectorspertrack
s1track01db0
s1track1dw0
sectorsdq0;numberofsectorsonrequesteddisk
sector_szdw0;numberofbytespersector
db511-26dup(0);新buf
FATdb13,10,'0~0eh:'
db13,10,'?OS,F12/Unfmt,,,F16/U_,EXtend,F16B,NTFS,,,,F32,F32_13X,,F16'
db13,10,'11,14,16,17,1b:(Hidden)'
db13,10,'F12/U_,F16,F16B,N,F32$'
.viewdb'0000,cx='
viewcxdb'13EX,dx='
viewdxdb'tend'
CRdb13,10,36
extblkdb16,0分区表16字节用
sec_totdw1
buf_offdwbuf;buf偏移
buf_segdwSEGbuf
lbaldw0;lba低双字低字
lbahdw0;lba低双字高字
dd0;lba高双字
cmd_pdb'b(pb),p(arti),r(eadsectofoo/stdout),w(ritefootosec),v(xdw)$';rwv用
logi_pdb13,10,'logi_drv(A:=01)$'
subBPBdb13,10,'SV_sec:'
SV_secdb0,'000,FATs:'向foo读
FATsdb'00,sec_per_FAT:'
sec1FATdb'0000$'
drv_pdb13,10,'drv(00~01,80~83)$';扩展i13用
mod_pdb13,10,'c(hs),l(ba)$';dosext,nondos用
db13,10
from80db'8?,'
logidrvdb'C:,Boot:'
Bootdb'?0,FAT:'
volumedb'06,Front:'
Front_hdw?,?又做总扇数
Front_ldb'0000,In:'
In_hdw0,?又做当前扇号
In_ldb'0000$'
cyl_pdb13,10,'0~cyl('
cyl_p1db'????)$'
hd_pdb13,10,'0~hd('
hd_p1db'??)$'
sec_pdb13,10,'1~sec('
sec_p1db'??)$'
lba_pdb13,10,'0~lba('
lbah_p1db'????'
lbal_p1db'????)$'
total_pdb13,10,'1~total(ffff)$'
scr_pdb'^C,f(ast),n(ext)$'
primkdb1,4,6,11,12,14主分区标识
primksz=$-primk
extmkdb5,15扩展分区标识
extmksz=$-extmk
stk1dwNIBSZ/4dup(0);INnib栈
db32
rowascdb(21)*16dup(32),36
kbddbNIBSZ1;键盘buf
kbd1db67parti用
kbd2dbNIBSZ1dup(0)
fcbdrvdb0
fcbnamdb8dup(32)
fcbextdb3dup(32)
fcbblkdw0
fcbrszdw512
fcbszdb4dup(4)已占分区表号,4硬盘*1字节,parti用
fcbdatdw0
fcbdos1db10dup(0)
fcbrnodb0
entrylabeldword;fcbrand
entrydidw0
entryesdw0
media_hdb0;头数
media_cdw0;柱数
s1cyldw0;扇数/柱
s1trackdb0;扇数/道
drvdb0;输入
hddb0
cyldw0
secdb0
hextbldb'0123456789abcdef'
dends
csegment
assumecs:c,ds:d,es:d
@procfar
pushds;为exe返回
xorax,ax压cd20的psp:0
pushax
movax,d
moves,ax
cmpbyteptrds:[5dh],32缺foo
je@0
inces:SV_sec
movcx,183
movsi,5chsh复制盘符大写8.3名到5ch
leadi,fcbdrv
repmovsbes:di=ds:si的盘符8.3
@0:movds,ax
movah,9
leadx,cmd_p;问命令
int21h
movah,1
int21h
cmpal,'b'
jeb
jmpp
b:movkbd,21
leadx,logi_p问逻辑盘
CallINnib
movax,440dh
movcx,860h传统及扩展13,共享BPB前12字节
leadx,buf
int21h
movax,wordptrbuf[73]
leadi,SV_sec
axasc
moval,buf[75]
leadi,FATs
alasc
movax,wordptrbuf[711]
orax,ax
jnzbo
movax,wordptrbuf[725]
bo:leadi,sec1FAT
axasc
movah,9
leadx,subBPB
int21h
ret
p:cmpal,'p'
jner
movah,9
leadx,FAT
int21h
leabx,buf
movdx,80h扩展i13,可兼容传统
Calldospri
movmod_p,dl
movdl,80h
Calldosext
movlbal,0
movlbah,0
movdl,80h
Callnondos
ret
r:movcmd_p,al
cmpal,'r'
jerwv
cmpal,'w'
jerwv
cmpal,'v'
jev
ret
v:movax,1684h;func
movbx,3180h;接口ID
int2fh
movax,es;es:di=V86口cs:ip
orax,di
jnzv1
retes,di全0,失败
v1:moventrydi,di
moventryes,es
pushds
popes
rwv:movkbd,21
leadx,drv_p问磁盘
CallINnib
movdrv,bl
movdl,bl驱动器
testbl,80h 财管家园,fs119.net
jnerwv1
xordh,dh头
Callf_geo
jmprwv2
rwv1:Callh_geo
rwv2:testmedia_h,255
jnerwv3
ret
rwv3:muls1cyl
subax,1;lba始于0,可写CF
sbbdx,0
movlbal,ax
movlbah,dx
Calllba2chs
Callrng
movah,9;问寻扇
leadx,mod_p
int21h
movah,1
int21h
cmpal,'c'
jerwv4
movkbd,81
leadx,lba_p
callINnib;问lbah,lbal
movlbal,bx
movax,stk1
movlbah,ax
Calllba2chs
jmprwv5
rwv4:movkbd,41
leadx,cyl_p;问柱面号
CallINnib
movcyl,bx
movkbd,21
leadx,hd_p;问头号
CallINnib
movhd,bl
movkbd,21
leadx,sec_p;问扇号
CallINnib
movsec,bl
Callchs2lba
rwv5:Callrng;显出立体,线性值
movkbd,41
leadx,total_p;问总计
CallINnib
movFront_h,bx
leadx,fcbdrv;指向fcb
movah,15;openforw,v
cmpcmd_p,'r'
jnerw1
testSV_sec,1向foo读
jzrw2
movah,16h;createortruncforr,软盘启动,拒存取F32盘
rw1:int21h改fcbdrv为3=C
oral,alal为0,成功
jnzrw7
movfcbrsz,512重置
rw2:movax,600hal=clr
movbx,700hbl=page
xorcx,cx
movdx,184fh25*80
int10hcursorgrow0,24
movah,1ah;DTA
leadx,buf
movbx,dx;I/O数据区
int21h
rw3:testFront_h,65535
jzrw6
cmpcmd_p,'r'
jnerw4
movax,201h
movdl,drv
Callrw1by1
jerw6
Callscr
testSV_sec,1;向foo读
jzrw5
movah,15h;强制write
leadx,fcbdrv
int21h
jmprw5
rw4:movah,14h;read
leadx,fcbdrv
int21h
Callscr
movax,301h
movdl,drv
Callrw1by1
jerw8;出错,关闭
rw5:addlbal,1
adclbah,0
incIn_h
decFront_h
jmprw3
rw6:testSV_sec,1向foo读
jnzrw8
rw7:ret
rw8:movah,16;close
leadx,fcbdrv
int21h
ret
@endp
dospriproc;统计硬盘数,查DOS主分区
dospri0:cmpdl,80h4
jedospri7
movax,201h;测硬盘
movcx,1
int13h
jcdospri7
movbp,4*16
xorsi,si;分区表,占4*16字节
dospri1:cmpsi,4*16 财软联 盟 fs119.net
jedospri4
moval,buf[1behsi4]取vol
movcx,primksz是主分区?
leadi,primk
repnescasb
jnedospri3
testbyteptrbuf[1behsi],80h;取BootON
jnzdospri2
cmpbp,4*16
jnzdospri3
dospri2:movbp,si;暂选首现主分区
jnzdospri5
dospri3:Addsi,16
jmpdospri1
dospri4:cmpbp,4*16
jedospri6
dospri5:movsi,dx
subsi,80h
movax,bp
divextblk
movfcbsz[si],al标占分区表项号
moval,kbd1
movlogidrv,al
inckbd1
CallShow
dospri6:incdl;读下块硬盘
jmpdospri0
dospri7:ret
dospriendp
pri_nonproc
movlogidrv,32
movcx,primksz
leadi,primk
repnescasb
jnenon;不赋非DOS分区盘符
movlogidrv,94^符
moval,kbd1
cmpal,'Z'
janon
movlogidrv,al
inckbd1
non:CallShow
ret
pri_nonendp
dosextproc查DOS扩展分区
dosext0:cmpdl,mod_p
jedosext4
movax,201h
movcx,1
int13h
xorbp,bp
dosext1:cmpbp,4*16
jedosext3
moval,buf[1behbp4]
movcx,extmksz是扩展分区?
leadi,extmk
repnescasb
jnedosext2
pushbx
pushdx
Callh_geo
popdx
popbx
movax,wordptrbuf[1behbp8];Frontlow
moventrydi,ax基址
movlbal,ax
movax,wordptrbuf[1behbp10];Fronthigh
moventryes,ax
movlbah,ax
xorbp,bp;为show
Callchain
jmpdosext3
dosext2:Addbp,16
jmpdosext1
dosext3:incdl
jmpdosext0
dosext4:ret
dosextendp
h_geoproc
movah,41h
movbx,55aah;测BIOS支持i13_X
int13h
jch_geoo
cmpbx,0aa55h再核
jneh_geoo
testcx,1;支持41~44,47~48第1子集?
jzh_geoo
movah,48h取尺寸
leasi,info_sz
int13h
moval,heads00;头数
oral,al
jzh_geoo无效info包
movmedia_h,al
incdrv_p启扩展
movah,s1track00;每道扇数
movs1track,ah
mulah
movs1cyl,ax每柱面扇数
movax,cylinders0;柱面数
movmedia_c,ax
ret
h_geoo:movah,8取尺寸
int13h
jch_geoq
incdh
moval,dh
movmedia_h,al;头数
movs1track,cl
ands1track,63每道扇数
muls1track
movs1cyl,ax;每柱面扇数
xchgch,cl
rolch,1
rolch,1
andch,3
movax,cx
incax
movmedia_c,ax;柱面数
h_geoq:ret
h_geoendp
chainproc;处理链
chain0:movax,201h
Callrw1by1
moval,buf[1beh4]
callpri_non
testbuf[1beh164],255;0,5,15之1
jechain1
movax,wordptrbuf[1beh168]
addax,entrydi;加基址entrydi
movlbal,ax
movax,wordptrbuf[1beh1610]
adcax,entryes;加基址entryes
movlbah,ax
jmpchain0
chain1:ret
chainendp
nondosproc查未占过盘符的DOS主分区及非DOS分区
nondos0:cmpdl,mod_p
jenondos4
movax,201h
movcx,1
int13h
movbp,dx
subbp,80h
moval,fcbsz[bp]取已占分区表号
mulextblk
movfcbdat,ax
xorbp,bp
nondos1:cmpbp,4*16
jenondos3
cmpbp,fcbdat
jenondos2;已占
moval,buf[1behbp4]
testal,255不理闲置分区
jznondos2
movcx,extmksz;略扩展分区
leadi,extmk
repnescasb
jznondos2
callpri_non
nondos2:Addbp,16
jmpnondos1
nondos3:incdl
jmpnondos0
nondos4:ret
nondosendp
showproc;分区信息
pushdx
anddl,3盘号80~83
adddl,48
movfrom80[1],dl
movBoot,48多数为0
testbuf[1behbp],80h
jzshow0
movBoot,56
show0:moval,buf[1behbp4];显vol
leadi,volume
alasc
movax,wordptrbuf[1behbp8];取Frontlow
addax,lbal;为chain而加
pushf
leadi,Front_l
axasc
movax,wordptrbuf[1behbp10];Fronthigh
popf
adcax,lbah;为chain而加
leadi,Front_h
axasc
movax,wordptrbuf[1behbp12];取Inlow
leadi,In_l
axasc
movax,wordptrbuf[1behbp14];Inhigh
leadi,In_h
axasc
movah,9
leadx,from80
subdx,2
int21h
popdx
ret
Showendp
rw1by1proc读/写1扇
testdrv_p,113=传统
jnzrw1by11
xoral,al不校验写
orah,40h
leasi,extblk;扩展块
jmprw1by12
rw1by11:pushax
pushdx
calllba2chs
popdx
popax
callcxdh
movwordptrviewcx,cx
movwordptrviewdx,dx
rw1by12:cmpcmd_p,'v'
jerw1by13
int13h
ret遗c
rw1by13:Call[entry]
cmpbp,4096VxD按(8.3)返bp值
jaerw1by14
pushbx
addbx,bp;使bx,bx511在4k内
movbuf_off,bx扩展i13
pushcx
pushsi
leasi,buf511;原buf尾
movdi,si
adddi,bp;新buf尾
std;从后向前移1扇
movcx,256
repmovsw
cld
popsi
popcx
Call[entry]
popbx
movbuf_off,bx扩展i13
cmpbp,4096
rw1by14:jerw1by15
cmpbp,1010h
jnerw1by16
xorah,ah
Call[entry]释它页
rw1by15:cmpal,al置zr
rw1by16:ret
rw1by1endp
f_geoproc
leabx,buf;缓区
movcx,1;0:0:1(chs)引导扇
f_geo0:movax,201h;读1扇
int13h;读11起的bios参数块
jcf_geo0;换盘
moval,[bx26];偏移26:头数
movmedia_h,al
movah,[bx24];偏移24:每道扇数
movs1track,ah
mulah
movs1cyl,ax;每柱面扇数
movax,[bx19];偏移19:总扇数 财软联 盟 fs119.net
xordx,dx;高字
divs1cyl
movmedia_c,ax;柱面数
ret
f_geoendp
rngproc
movax,cyl;当前柱面
leadi,cyl_p1
axasc
moval,hd;当前头
leadi,hd_p1
alasc
moval,sec;当前扇号
leadi,sec_p1
alasc
movax,lbah;当前lba高字
leadi,lbah_p1
axasc
movax,lbal;当前lba低字
leadi,lbal_p1
axasc
movah,9
leadx,cyl_p
int21h
leadx,hd_p
int21h
leadx,sec_p
int21h
leadx,lba_p
int21h
ret
rngendp
scrproc
movcx,16字符数/row
xorsi,si
scr0:pushbx
movah,2
xorbh,bhpg
xordx,dxdh=row
int10h
popbx
leadx,.view
testsi,256
jzscr1
jmpscr3
scr1:movdi,dx
movax,In_h现扇号
axasc
testdrv_p,1
jnzscr2
jmpscr3
scr2:leadi,viewcx
movax,wordptr[di]
axasc
leadi,viewdx
movax,wordptr[di]
axasc
scr3:movah,9
int21h
scr4:movax,si
leadi,stk1
axasc
leabp,rowasc
scr5:moval,[bxsi]
movdi,si
anddi,15
movFAT[di],46
cmpal,32
jbscr6
movFAT[di],al
scr6:movdi,bp
alasc
Addbp,22-1
incsi
testsi,15
jnescr5
movah,9行的hex
leadx,stk1
int21h
pushbx
movah,64行的asc及汉字
movbx,1
leadx,FAT
int21h
popbx
movah,9
leadx,CR
int21h
testsi,255
jescr7
jmpscr4
scr7:cmpscr_p,'f'
jescr8
movah,9
leadx,scr_p
int21h
movah,1;按1键
int21h
cmpal,'f'
jnescr8
movscr_p,al
scr8:testsi,511
jescr9
jmpscr0
scr9:ret
screndp
cxdhproc
movdh,hd;头号
movcx,cyl;柱面号
xchgcl,ch
rorcl,1
rorcl,1
andcl,not63
orcl,sec;低6位扇号
ret
cxdhendp
lba2chsproc
movax,lbal
movdx,lbah
divs1cyl;柱面号
movcyl,ax
movax,dx
divs1track
movhd,al;头号
incah
movsec,ah;扇号
ret
lba2chsendp
chs2lbaproc
movax,cyl;柱面号
muls1cyl
movlbal,ax
movlbah,dx
moval,s1track;每道扇数
mulhd
Addlbal,ax
adclbah,0
moval,sec;此处,低6位扇号
decal
cbw
Addlbal,ax
adclbah,0
ret
chs2lbaendp
INnibproc;kbd限长nib入kbd2.转后入stk1,低字还入bx
INnib0:movah,9
int21h
pushdx
incah;回车才收
leadx,kbd
int21h
popdx
moval,kbd
decal
cmpal,kbd1;实长
jnzINnib0
xorbp,bp
leasi,kbd2
INnib1:lodsb
movcx,16
leadi,hextbl
repnescasb
jnzINnib0
deckbd1
inccx;转'[0-9a-f]'为0~15
subcx,16
negcx
rept4
shlbx,1;bx接收nibble,左入0
endm
orbl,cl
testkbd1,3;已收4个nibble
jnzINnib1
movstk1[bp],bx
addbp,TYPEstk1
testkbd1,NIBSZ*2-1
jnzINnib1
ret
INnibendp
cends
end@
(8)论V86下,直寻硬盘扇区,只能靠VxD
VToolsD建的C级VxD,有读/写DOS分区的R0_ReadAbsoluteDisk/R0_Write...函数.
例如,响应自32位C的W32_DEVICEIOCONTROL事件时,用格式R0_Read...(2,1,0,buf,&w),读相对DOS分区的逻辑扇号是1的分区引导扇区PBS.这时,当前虚拟机hVM,是系统(证于Test_Sys_VM_Handle测事件实参IOCTLPARAMS.dioc_hvm).VxD不改hVM身份. 财.软联盟.fs119.net
又如,响应自16位ASM程序的V86_API_Entry入口调用时,同上,读PBS,这时,hVM是DOS(证于Test_...测入口实参VMHANDLE).
均读PBS含"MSWIN4...".
但VxD,也能在V86下,用Exec_Int(0x13),法如13h,直寻硬盘,如PBS之前MBR.
笔者c.cppa.exe,直读MBR连续5扇.需cfg.sys,隐dev=EMM386
(8.1)用QuickVxD,建C级VxD,设备名=C,设备ID=0x3180,选动态装
选API页StandardAppEntryPoints框Real/V86Mode.体,见(8.3).
选OnSysDynamicDevice的Init及Exit.体中:
选发SHELL_SYSMODAL_Message(Get_Cur_VM_Handle(),MB_SYSTEMMODAL,"m","cap")
必发return(true)
(8.2)写a.asm,汇编时,/DNPAGE=5,指明5扇.读变写,需debug下,改r2w3处的2为3.
VxD查客户这5扇缓区,囿V86空间1页(4K字节)的整体性,未全囿,bp返回<4k的修正量.
IF2
IFNPAGELT1orNPAGEGT8
%OUT0.ERR
ENDIF
ENDIF
dsegment
bufdbNPAGE*512*2-1dup(9);留足修区
entrydd0
dends
csegment
assumecs:c,ds:d
@:movbp,d 财管家.园.fs119.net
movds,bp
movax,1684h功能号
movbx,3180h接口ID
int2fh
movax,eses/di=API_Entry入口段/偏移
orax,di
jz@3;es及di全为零,失败
movwordptr[entry],di
movwordptr[entry2],es
movax,ds设exec_int参数
moves,ax
leabx,bufes:bx,指向缓区首
r2w3:movah,2读80h硬盘MBR处NPAGE扇
moval,NPAGE
movcx,10:0:1(chs)
movdx,128
stdVxD出兰屏,写修
call[entry]
cmpbp,4096VxD按(8.3)返bp值
jae@2
addbx,bp修缓区首址
testah,1查读/写
jz@1此例ah=2,读盘
leasi,buf写入时,从后向前,移NPAGE*256字
addsi,NPAGE*512-1si指向原缓区尾
movdi,si
adddi,bpdi指向新缓区尾
movcx,NPAGE*256
repmovswds:si所指cx字,移到es:di
movcx,1
@1:call[entry]
cmpbp,4096
@2:je@3
cmpbp,1010h
jne@3
xorah,ah;释它页
call[entry]
@3:xorax,ax
moves,ax
movax,[bx1beh]成功/失败,72h矢量=分区表首字/9
moves:[1c8h],ax
movah,4ch
int21h
cends
end@
(8.3)...V86_API_Entry(VMHANDLEhVM,CLIENT_STRUCT*pRegs)体
DWORDh,t;
CLIENT_STRUCTs;
if(pRegs->CBRS.Client_AH){//2读3写
h=(DWORD)Map_Flat(CLIENT_ES,CLIENT_BX);//h=客户缓区首es:bx的32位线性址
t=hpRegs->CBRS.Client_AL*512-1;//t=尾的线性址
if((h>>12)!=(t>>12)){
pRegs->CWRS.Client_BP=(4096-(h&4095));//首尾未囿同页,bp返客户增bx量
return;
}
if((h>>12)<0x110)//缓区能被V86寻,bp返4096
pRegs->CWRS.Client_BP=4096;
else
if(LinMapIntoV86(h>>12,hVM,0x10,1,0,&t)){
//缓区所在页,成功映入V86第0x10页,bp返0x1010
pRegs->CWRS.Client_BP=0x1010;
h=(16<<12)(h&4095);//由t及偏移,得缓区V86址h
}else{//无页等,bp返0x1110
pRegs->CWRS.Client_BP=0x1110;
return;
}
Save_Client_State(&s);//存reg
Begin_Nest_V86_Exec();//当前虚拟机,能寻V86
pRegs->CRS.Client_ES=(h>>4);//es=址h的段值
pRegs->CRS.Client_EBX=(h&15);//bx=址h的偏移
Exec_Int(0x13);
End_Nest_Exec();//复原
Restore_Client_State(&s);
if(pRegs->CWRS.Client_Flags&1024){//方向,控兰屏
sprintf((char*)s.CBRS.Client_res30,"%x",pRegs->CWRS.Client_BP);
SHELL_SYSMODAL_Message(hVM,MB_SYSTEMMODAL,(char*)s.CBRS.Client_res30,"bp");
}
}else//知bp返0x1010时,客户释它页
MapIntoV86(GetNulPageHandle(),hVM,16,1,0,0);
(8.4)装VxD法
静态:
放C.VXD于c:\windows\system,在c:\windows\system.ini的386Enh,写device=C.VxD,再reboot
动态4法:
用VxD_Loader,选C.VXD
用DriverMonitor,先打开C.VXD,再Start
放C.VXD于c:\windows\system\iosubsys,再reboot
用笔者DOS窗口a的exe
#include
#definepre"\\\\.\\"
main(intac,char*av[]){
char*vxd;
HANDLEh;
if(ac==1)printf("vxd_load?.vxd\n");
else{
vxd=malloc(strlen(pre)strlen(av[1]));
sprintf(vxd,"%s%s",pre,av[1]);
h=CreateFile(vxd,0,0,0,0,FILE_FLAG_DELETE_ON_CLOSE,0); 财管家.园.fs119.net
if(h!=INVALID_HANDLE_VALUE){
printf("Tounload,hitEnter");
getch();
CloseHandle(h);
}
}
}
装C.VXD,事毕,敲回车到窗a,卸此VXD
文章摘自网络,如有侵权,请与我们联系.
本文基于486DX2,主板,可带primary(启动)/secondary控制IDE器2,中断14/15,每个IDE,可带master(启动,电缆中)/slave(缆端)(跳线ds插/空)2通道,每通道,可带1台硬盘驱动器,每驱动器,可带1块NORMAL,LBA,LARGE模式的IDE硬盘.
DOS,98对硬盘,先按IDE,后按m/s,依次编号,不编闲置通道.例如,有3块盘,块1,2在pri_m/s上,块3在sec_cs上,此3块,编为80h~82h.
开机盘的IDE及通道,由BIOS的BOOTSEQ指定.
(1)DOS/98的读写F16/32格式的位置X的Y个连续扇区的BIOS中断13h参数:
ah的2/3指明读/写,al的低6位指明Y,es:bx指向内存buf首,cl的低6位指明X的扇号sector,最小1,ch,左拼cl第6,7位,齐指X的柱面号cylinder,最小0,dh指明磁头号head,最小0,dl指明软硬盘编号.
IDE原有的NORMAL,BIOS限定柱面数1024,磁头数16,扇区数63,每扇512字节,相乘=容量528MB.用作cmos_chs(cylinder:head:sector)立体寻扇.
LBA,仅磁头数异达255,容量8.4GB 财管家园 fs119.net
LARGE,柱面数>1024,磁头数16,控制器做柱面数/2,磁头数*2,以适13h.容量2048*16*63*512=1G
周边设定:Block模式加速,PIO(并行I/O接口)模式,影响rate
(2)针对LBA的扩展13h线性64位lba寻扇:
chs转时,lba=c*sectors_per_cylinderh*sectors_per_track(s-1)
其中,sectors_per_cylinder为每柱面扇数,sectors_per_track为每磁道扇数,因s从1编号,要减1.
互转,见"(7)文"的chs2lba,lba2chs.
利用extblk块:
extblkdb16;块的字节数(含此字节)
db0
sec_totdw1指明Y个扇区
buf_offdw0;内存buf偏移
buf_segdw0;buf段值
lbaldw0;lba低双字低字
lbahdw0;lba低双字高字
dd0;lba高双字
读/写时,ah=42h/43h,多ds:si指向extblk
扩展i13的BIOS支持性(柱数<1024,先用chs),及导出硬盘柱数,头数,每道扇数,算法见"(7)文"的h_geo
(3)硬盘分区:
每硬盘,最多划为DOS主分区,DOS扩展分区,非DOS分区之1的4区,述于16字节/区的64字节分区表(dpt): 财软联盟,fs119.net
bootONdb080H/0,是活跃/不活跃.
db?分区启动chs的头号
dw?低6位:扇区,低第6,7位与高字节,'齐指'柱面号
volumedb0分区标识值
db?结束chs
dw?
Frontdd0此分区之前(称隐藏)扇区数.INT_25H_dx=1,是在其后读逻辑首扇
Indd0此分区所含扇区数
MBR(F$制的1扇盘主引导记录,软盘0:0:1,硬盘DOS分区的首扇,即INT_25H_扇号dx=1),转cpu给Format.com制的驻有OS的活跃主分区引导记录(OBR).
主分区的保留区(引导扇区PBS囿其内,软盘仅藏1区)之后,常是2份FAT,再后,是根目录.
PBS片断:
0~2:JMP引导程序
3~0AH:厂,sys_ver
(BPB首)0BH~0CH:每扇bytes
0DH:每簇扇数
0EH~0FH:保留区扇数
10H:FAT份数
11H~12H:F16根目录32字节项的数目,F32:0.
13H~14H:软盘,32M内硬盘:分区总扇数
15H:介质,软盘:F0H,硬盘:F8H
16H~17H:软盘,32M内硬盘:每FAT占用扇
18H~19H:每道扇数
1AH~1BH:磁头数
1CH~1FH:此分区之前隐藏扇数
20H~23H:32M外硬盘:分区总扇数 财 管家园 fs119.net
24H~27H:32M外硬盘:每FAT占用扇
40H:磁盘BIOS,1st硬盘:80H,软盘:0
47H~51H:vol
52H~59H:file_sys
软盘6.22的io.sys,最先分得簇,如目录项0基第13字,指向1e,此12BIT的项值,是1f0002,指明01f->020->...->fff链.
分区标识值:
闲置:0
DOS主分区:1,4,6,0bh,0ch,0eh
DOS扩展分区:5,0fh
非DOS分区:其它
笔者用P,对硬盘划分4个DOS主分区,再prw,读此盘(0:0:0)到文件0,用debug,改分区vol值为2,用prw,回写0到(0:0:0),P的分区info页,显vol对应XENIX.
释意,见"(7)文"的FAT
若vol<20H,则高4位,1/0表示隐藏/非隐藏,后缀X,用于扩展i13接口.
各硬盘,均含0:0:1(chs)的1扇MBR,其偏移1be字节,连续存4个分区表.
各硬盘,最多1个DOS扩展分区,其内,能划分称为逻辑分区的数个DOS主分区,非DOS分区.
逻辑分区串成链.例如,vol=5的扩展分区E,先含1个DOS主分区D,后含1个非DOS分区N,则E的Front域值F,是E内的各逻辑分区位置基址,F指明扇区S1,而S1的偏移1be字节,是D的分区表,偏移1ce字节,其vol=0fh,表示DOS扩展分区,其Front域值,加上基址F,指明扇区S2,而S2的偏移1be字节,是N的分区表,偏移1ce字节,其vol=链尾0. 财软.联盟.fs119.net
(4)仿F$及P$,列出分区逻辑盘符:
盘符,C:~Z:列出.用F$,P$,能建数个逻辑分区
分区超过Z:符时,F$照列,P$不赋盘符,prw赋^符
活跃分区数>1时,引导错,但F$及prw照列,P$显错
F$,P$,依vol域,查以下3步,每步,查80h至83h:
(1)查DOS主分区
若是,则查bootON是否80H,若是,此分区就占1个逻辑盘符,若无活跃主分区,表项在MBR首现的主分区,就占1个逻辑盘符.
例如,3硬盘,80h的第1,3分区是主分区,但第3分区活跃,则第3分区占盘符C:.而81h,只含DOS扩展分区,其上,含1个DOS主分区及1个非DOS分区;82h的第2,4分区是不活跃主分区,则最先在MBR中出现的第2分区,占盘符D:
(2)查DOS扩展分区
按逻辑分区在链上次序,查它是否DOS主分区,若是,就占盘符,81h的DOS扩展分区上的DOS主分区,占盘符E:
(3)查未占过盘符的DOS主分区及非DOS分区
按MBR中,分区表项出现的先后次序,查分区是否DOS主分区,若是,且它未占过盘符,就占盘符.80h的第1分区,占盘符F:,82h的第4分区,占盘符G: 财.软联盟.fs119.net
F$,P$,prw,不给非DOS分区赋盘符,仅显In值.
(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]
财.软联盟.fs119.net
初见:
b(pb),p(arti),r(eadsectofoo/stdout),w(ritefootosec),v(xdw)
命令键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,先发:
prwb: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,可发prwc:u>g
(7)文
NIBSZ=8;8个hex数
nibascmacro
localnq
addal,48
cmpal,1048
jbnq
addal,97-48-10 财管家,园,fs119.net
nq:
endm
alascmacro
movah,al
andal,15
nibasc
xchgah,al
rept4
shral,1高nibble
endm
nibasc
stosw
endm
axascmacro
pushax
moval,ah转ah
alasc
popax转al
alasc
endm
dsegment
bufdb511dup(0)放MRB.全囿V86页(4k),buf长1023,囿DMA_64k
buf511db0老buf尾
info_szdw26;minszofinfobuf新buf
flagsdw0;flags
cylinders0dw0;numberofcylindersondisk
cylinders1dw0
heads00db0;numberofheadsondisk
heads01db0
heads1dw0
s1track00db0;numberofsectorspertrack
s1track01db0
s1track1dw0
sectorsdq0;numberofsectorsonrequesteddisk
sector_szdw0;numberofbytespersector
db511-26dup(0);新buf
FATdb13,10,'0~0eh:'
db13,10,'?OS,F12/Unfmt,,,F16/U_,EXtend,F16B,NTFS,,,,F32,F32_13X,,F16'
db13,10,'11,14,16,17,1b:(Hidden)'
db13,10,'F12/U_,F16,F16B,N,F32$'
.viewdb'0000,cx='
viewcxdb'13EX,dx='
viewdxdb'tend'
CRdb13,10,36
extblkdb16,0分区表16字节用
sec_totdw1
buf_offdwbuf;buf偏移
buf_segdwSEGbuf
财管家园,fs119.net
lbaldw0;lba低双字低字
lbahdw0;lba低双字高字
dd0;lba高双字
cmd_pdb'b(pb),p(arti),r(eadsectofoo/stdout),w(ritefootosec),v(xdw)$';rwv用
logi_pdb13,10,'logi_drv(A:=01)$'
subBPBdb13,10,'SV_sec:'
SV_secdb0,'000,FATs:'向foo读
FATsdb'00,sec_per_FAT:'
sec1FATdb'0000$'
drv_pdb13,10,'drv(00~01,80~83)$';扩展i13用
mod_pdb13,10,'c(hs),l(ba)$';dosext,nondos用
db13,10
from80db'8?,'
logidrvdb'C:,Boot:'
Bootdb'?0,FAT:'
volumedb'06,Front:'
Front_hdw?,?又做总扇数
Front_ldb'0000,In:'
In_hdw0,?又做当前扇号
In_ldb'0000$'
cyl_pdb13,10,'0~cyl('
cyl_p1db'????)$'
hd_pdb13,10,'0~hd('
hd_p1db'??)$'
sec_pdb13,10,'1~sec('
sec_p1db'??)$'
lba_pdb13,10,'0~lba('
lbah_p1db'????'
lbal_p1db'????)$'
total_pdb13,10,'1~total(ffff)$'
scr_pdb'^C,f(ast),n(ext)$'
primkdb1,4,6,11,12,14主分区标识
primksz=$-primk
extmkdb5,15扩展分区标识
extmksz=$-extmk
stk1dwNIBSZ/4dup(0);INnib栈
财,管家园,fs119.net
db32
rowascdb(21)*16dup(32),36
kbddbNIBSZ1;键盘buf
kbd1db67parti用
kbd2dbNIBSZ1dup(0)
fcbdrvdb0
fcbnamdb8dup(32)
fcbextdb3dup(32)
fcbblkdw0
fcbrszdw512
fcbszdb4dup(4)已占分区表号,4硬盘*1字节,parti用
fcbdatdw0
fcbdos1db10dup(0)
fcbrnodb0
entrylabeldword;fcbrand
entrydidw0
entryesdw0
media_hdb0;头数
media_cdw0;柱数
s1cyldw0;扇数/柱
s1trackdb0;扇数/道
drvdb0;输入
hddb0
cyldw0
secdb0
hextbldb'0123456789abcdef'
dends
csegment
assumecs:c,ds:d,es:d
@procfar
pushds;为exe返回
xorax,ax压cd20的psp:0
pushax
movax,d
moves,ax
cmpbyteptrds:[5dh],32缺foo
je@0
inces:SV_sec
movcx,183
movsi,5chsh复制盘符大写8.3名到5ch
leadi,fcbdrv
repmovsbes:di=ds:si的盘符8.3
@0:movds,ax
movah,9
leadx,cmd_p;问命令
int21h
movah,1
int21h
cmpal,'b'
jeb
jmpp
b:movkbd,21
leadx,logi_p问逻辑盘
财.管家园.fs119.net
CallINnib
movax,440dh
movcx,860h传统及扩展13,共享BPB前12字节
leadx,buf
int21h
movax,wordptrbuf[73]
leadi,SV_sec
axasc
moval,buf[75]
leadi,FATs
alasc
movax,wordptrbuf[711]
orax,ax
jnzbo
movax,wordptrbuf[725]
bo:leadi,sec1FAT
axasc
movah,9
leadx,subBPB
int21h
ret
p:cmpal,'p'
jner
movah,9
leadx,FAT
int21h
leabx,buf
movdx,80h扩展i13,可兼容传统
Calldospri
movmod_p,dl
movdl,80h
Calldosext
movlbal,0
movlbah,0
movdl,80h
Callnondos
ret
r:movcmd_p,al
cmpal,'r'
jerwv
cmpal,'w'
jerwv
cmpal,'v'
jev
ret
v:movax,1684h;func
movbx,3180h;接口ID
int2fh
movax,es;es:di=V86口cs:ip
orax,di
jnzv1
retes,di全0,失败
v1:moventrydi,di
moventryes,es
pushds
popes
rwv:movkbd,21
leadx,drv_p问磁盘
CallINnib
movdrv,bl
movdl,bl驱动器
testbl,80h 财管家园,fs119.net
jnerwv1
xordh,dh头
Callf_geo
jmprwv2
rwv1:Callh_geo
rwv2:testmedia_h,255
jnerwv3
ret
rwv3:muls1cyl
subax,1;lba始于0,可写CF
sbbdx,0
movlbal,ax
movlbah,dx
Calllba2chs
Callrng
movah,9;问寻扇
leadx,mod_p
int21h
movah,1
int21h
cmpal,'c'
jerwv4
movkbd,81
leadx,lba_p
callINnib;问lbah,lbal
movlbal,bx
movax,stk1
movlbah,ax
Calllba2chs
jmprwv5
rwv4:movkbd,41
leadx,cyl_p;问柱面号
CallINnib
movcyl,bx
movkbd,21
leadx,hd_p;问头号
CallINnib
movhd,bl
movkbd,21
leadx,sec_p;问扇号
CallINnib
movsec,bl
Callchs2lba
rwv5:Callrng;显出立体,线性值
movkbd,41
leadx,total_p;问总计
CallINnib
movFront_h,bx
leadx,fcbdrv;指向fcb
movah,15;openforw,v
cmpcmd_p,'r'
jnerw1
testSV_sec,1向foo读
jzrw2
movah,16h;createortruncforr,软盘启动,拒存取F32盘
rw1:int21h改fcbdrv为3=C
财.软联盟.fs119.net
oral,alal为0,成功
jnzrw7
movfcbrsz,512重置
rw2:movax,600hal=clr
movbx,700hbl=page
xorcx,cx
movdx,184fh25*80
int10hcursorgrow0,24
movah,1ah;DTA
leadx,buf
movbx,dx;I/O数据区
int21h
rw3:testFront_h,65535
jzrw6
cmpcmd_p,'r'
jnerw4
movax,201h
movdl,drv
Callrw1by1
jerw6
Callscr
testSV_sec,1;向foo读
jzrw5
movah,15h;强制write
leadx,fcbdrv
int21h
jmprw5
rw4:movah,14h;read
leadx,fcbdrv
int21h
Callscr
movax,301h
movdl,drv
Callrw1by1
jerw8;出错,关闭
rw5:addlbal,1
adclbah,0
incIn_h
decFront_h
jmprw3
rw6:testSV_sec,1向foo读
jnzrw8
rw7:ret
rw8:movah,16;close
leadx,fcbdrv
int21h
ret
@endp
dospriproc;统计硬盘数,查DOS主分区
dospri0:cmpdl,80h4
jedospri7
movax,201h;测硬盘
movcx,1
int13h
jcdospri7
movbp,4*16
xorsi,si;分区表,占4*16字节
dospri1:cmpsi,4*16 财软联 盟 fs119.net
jedospri4
moval,buf[1behsi4]取vol
movcx,primksz是主分区?
leadi,primk
repnescasb
jnedospri3
testbyteptrbuf[1behsi],80h;取BootON
jnzdospri2
cmpbp,4*16
jnzdospri3
dospri2:movbp,si;暂选首现主分区
jnzdospri5
dospri3:Addsi,16
jmpdospri1
dospri4:cmpbp,4*16
jedospri6
dospri5:movsi,dx
subsi,80h
movax,bp
divextblk
movfcbsz[si],al标占分区表项号
moval,kbd1
movlogidrv,al
inckbd1
CallShow
dospri6:incdl;读下块硬盘
jmpdospri0
dospri7:ret
dospriendp
pri_nonproc
movlogidrv,32
movcx,primksz
leadi,primk
repnescasb
jnenon;不赋非DOS分区盘符
movlogidrv,94^符
moval,kbd1
cmpal,'Z'
janon
movlogidrv,al
inckbd1
non:CallShow
ret
pri_nonendp
dosextproc查DOS扩展分区
dosext0:cmpdl,mod_p
jedosext4
movax,201h
movcx,1
int13h
xorbp,bp
dosext1:cmpbp,4*16
jedosext3
moval,buf[1behbp4]
财,软联盟,fs119.net
movcx,extmksz是扩展分区?
leadi,extmk
repnescasb
jnedosext2
pushbx
pushdx
Callh_geo
popdx
popbx
movax,wordptrbuf[1behbp8];Frontlow
moventrydi,ax基址
movlbal,ax
movax,wordptrbuf[1behbp10];Fronthigh
moventryes,ax
movlbah,ax
xorbp,bp;为show
Callchain
jmpdosext3
dosext2:Addbp,16
jmpdosext1
dosext3:incdl
jmpdosext0
dosext4:ret
dosextendp
h_geoproc
movah,41h
movbx,55aah;测BIOS支持i13_X
int13h
jch_geoo
cmpbx,0aa55h再核
jneh_geoo
testcx,1;支持41~44,47~48第1子集?
jzh_geoo
movah,48h取尺寸
leasi,info_sz
int13h
moval,heads00;头数
oral,al
jzh_geoo无效info包
movmedia_h,al
incdrv_p启扩展
movah,s1track00;每道扇数
movs1track,ah
mulah
movs1cyl,ax每柱面扇数
movax,cylinders0;柱面数
movmedia_c,ax
ret
h_geoo:movah,8取尺寸
int13h
jch_geoq
incdh
moval,dh
movmedia_h,al;头数
财管家.园.fs119.net
movs1track,cl
ands1track,63每道扇数
muls1track
movs1cyl,ax;每柱面扇数
xchgch,cl
rolch,1
rolch,1
andch,3
movax,cx
incax
movmedia_c,ax;柱面数
h_geoq:ret
h_geoendp
chainproc;处理链
chain0:movax,201h
Callrw1by1
moval,buf[1beh4]
callpri_non
testbuf[1beh164],255;0,5,15之1
jechain1
movax,wordptrbuf[1beh168]
addax,entrydi;加基址entrydi
movlbal,ax
movax,wordptrbuf[1beh1610]
adcax,entryes;加基址entryes
movlbah,ax
jmpchain0
chain1:ret
chainendp
nondosproc查未占过盘符的DOS主分区及非DOS分区
nondos0:cmpdl,mod_p
jenondos4
movax,201h
movcx,1
int13h
movbp,dx
subbp,80h
moval,fcbsz[bp]取已占分区表号
mulextblk
movfcbdat,ax
xorbp,bp
nondos1:cmpbp,4*16
jenondos3
cmpbp,fcbdat
jenondos2;已占
moval,buf[1behbp4]
testal,255不理闲置分区
jznondos2
movcx,extmksz;略扩展分区
财软 联盟 fs119.net
leadi,extmk
repnescasb
jznondos2
callpri_non
nondos2:Addbp,16
jmpnondos1
nondos3:incdl
jmpnondos0
nondos4:ret
nondosendp
showproc;分区信息
pushdx
anddl,3盘号80~83
adddl,48
movfrom80[1],dl
movBoot,48多数为0
testbuf[1behbp],80h
jzshow0
movBoot,56
show0:moval,buf[1behbp4];显vol
leadi,volume
alasc
movax,wordptrbuf[1behbp8];取Frontlow
addax,lbal;为chain而加
pushf
leadi,Front_l
axasc
movax,wordptrbuf[1behbp10];Fronthigh
popf
adcax,lbah;为chain而加
leadi,Front_h
axasc
movax,wordptrbuf[1behbp12];取Inlow
leadi,In_l
axasc
movax,wordptrbuf[1behbp14];Inhigh
leadi,In_h
axasc
movah,9
leadx,from80
subdx,2
int21h
popdx
ret
Showendp
rw1by1proc读/写1扇
testdrv_p,113=传统
jnzrw1by11
xoral,al不校验写
orah,40h
leasi,extblk;扩展块
jmprw1by12
rw1by11:pushax
pushdx
calllba2chs
popdx
财软 联盟 fs119.net
popax
callcxdh
movwordptrviewcx,cx
movwordptrviewdx,dx
rw1by12:cmpcmd_p,'v'
jerw1by13
int13h
ret遗c
rw1by13:Call[entry]
cmpbp,4096VxD按(8.3)返bp值
jaerw1by14
pushbx
addbx,bp;使bx,bx511在4k内
movbuf_off,bx扩展i13
pushcx
pushsi
leasi,buf511;原buf尾
movdi,si
adddi,bp;新buf尾
std;从后向前移1扇
movcx,256
repmovsw
cld
popsi
popcx
Call[entry]
popbx
movbuf_off,bx扩展i13
cmpbp,4096
rw1by14:jerw1by15
cmpbp,1010h
jnerw1by16
xorah,ah
Call[entry]释它页
rw1by15:cmpal,al置zr
rw1by16:ret
rw1by1endp
f_geoproc
leabx,buf;缓区
movcx,1;0:0:1(chs)引导扇
f_geo0:movax,201h;读1扇
int13h;读11起的bios参数块
jcf_geo0;换盘
moval,[bx26];偏移26:头数
movmedia_h,al
movah,[bx24];偏移24:每道扇数
movs1track,ah
mulah
movs1cyl,ax;每柱面扇数
movax,[bx19];偏移19:总扇数 财软联 盟 fs119.net
xordx,dx;高字
divs1cyl
movmedia_c,ax;柱面数
ret
f_geoendp
rngproc
movax,cyl;当前柱面
leadi,cyl_p1
axasc
moval,hd;当前头
leadi,hd_p1
alasc
moval,sec;当前扇号
leadi,sec_p1
alasc
movax,lbah;当前lba高字
leadi,lbah_p1
axasc
movax,lbal;当前lba低字
leadi,lbal_p1
axasc
movah,9
leadx,cyl_p
int21h
leadx,hd_p
int21h
leadx,sec_p
int21h
leadx,lba_p
int21h
ret
rngendp
scrproc
movcx,16字符数/row
xorsi,si
scr0:pushbx
movah,2
xorbh,bhpg
xordx,dxdh=row
int10h
popbx
leadx,.view
testsi,256
jzscr1
jmpscr3
scr1:movdi,dx
movax,In_h现扇号
axasc
testdrv_p,1
jnzscr2
jmpscr3
scr2:leadi,viewcx
movax,wordptr[di]
axasc
leadi,viewdx
movax,wordptr[di]
axasc
scr3:movah,9
int21h
scr4:movax,si
leadi,stk1
axasc
leabp,rowasc
scr5:moval,[bxsi]
财.管家园.fs119.net
movdi,si
anddi,15
movFAT[di],46
cmpal,32
jbscr6
movFAT[di],al
scr6:movdi,bp
alasc
Addbp,22-1
incsi
testsi,15
jnescr5
movah,9行的hex
leadx,stk1
int21h
pushbx
movah,64行的asc及汉字
movbx,1
leadx,FAT
int21h
popbx
movah,9
leadx,CR
int21h
testsi,255
jescr7
jmpscr4
scr7:cmpscr_p,'f'
jescr8
movah,9
leadx,scr_p
int21h
movah,1;按1键
int21h
cmpal,'f'
jnescr8
movscr_p,al
scr8:testsi,511
jescr9
jmpscr0
scr9:ret
screndp
cxdhproc
movdh,hd;头号
movcx,cyl;柱面号
xchgcl,ch
rorcl,1
rorcl,1
andcl,not63
orcl,sec;低6位扇号
ret
cxdhendp
lba2chsproc
movax,lbal
movdx,lbah
divs1cyl;柱面号
movcyl,ax
movax,dx
divs1track
movhd,al;头号
incah
movsec,ah;扇号
ret
lba2chsendp
chs2lbaproc
movax,cyl;柱面号
muls1cyl
财 软联盟 fs119.net
movlbal,ax
movlbah,dx
moval,s1track;每道扇数
mulhd
Addlbal,ax
adclbah,0
moval,sec;此处,低6位扇号
decal
cbw
Addlbal,ax
adclbah,0
ret
chs2lbaendp
INnibproc;kbd限长nib入kbd2.转后入stk1,低字还入bx
INnib0:movah,9
int21h
pushdx
incah;回车才收
leadx,kbd
int21h
popdx
moval,kbd
decal
cmpal,kbd1;实长
jnzINnib0
xorbp,bp
leasi,kbd2
INnib1:lodsb
movcx,16
leadi,hextbl
repnescasb
jnzINnib0
deckbd1
inccx;转'[0-9a-f]'为0~15
subcx,16
negcx
rept4
shlbx,1;bx接收nibble,左入0
endm
orbl,cl
testkbd1,3;已收4个nibble
jnzINnib1
movstk1[bp],bx
addbp,TYPEstk1
testkbd1,NIBSZ*2-1
jnzINnib1
ret
INnibendp
cends
end@
(8)论V86下,直寻硬盘扇区,只能靠VxD
VToolsD建的C级VxD,有读/写DOS分区的R0_ReadAbsoluteDisk/R0_Write...函数.
例如,响应自32位C的W32_DEVICEIOCONTROL事件时,用格式R0_Read...(2,1,0,buf,&w),读相对DOS分区的逻辑扇号是1的分区引导扇区PBS.这时,当前虚拟机hVM,是系统(证于Test_Sys_VM_Handle测事件实参IOCTLPARAMS.dioc_hvm).VxD不改hVM身份. 财.软联盟.fs119.net
又如,响应自16位ASM程序的V86_API_Entry入口调用时,同上,读PBS,这时,hVM是DOS(证于Test_...测入口实参VMHANDLE).
均读PBS含"MSWIN4...".
但VxD,也能在V86下,用Exec_Int(0x13),法如13h,直寻硬盘,如PBS之前MBR.
笔者c.cppa.exe,直读MBR连续5扇.需cfg.sys,隐dev=EMM386
(8.1)用QuickVxD,建C级VxD,设备名=C,设备ID=0x3180,选动态装
选API页StandardAppEntryPoints框Real/V86Mode.体,见(8.3).
选OnSysDynamicDevice的Init及Exit.体中:
选发SHELL_SYSMODAL_Message(Get_Cur_VM_Handle(),MB_SYSTEMMODAL,"m","cap")
必发return(true)
(8.2)写a.asm,汇编时,/DNPAGE=5,指明5扇.读变写,需debug下,改r2w3处的2为3.
VxD查客户这5扇缓区,囿V86空间1页(4K字节)的整体性,未全囿,bp返回<4k的修正量.
IF2
IFNPAGELT1orNPAGEGT8
%OUT0.ERR
ENDIF
ENDIF
dsegment
bufdbNPAGE*512*2-1dup(9);留足修区
entrydd0
dends
csegment
assumecs:c,ds:d
@:movbp,d 财管家.园.fs119.net
movds,bp
movax,1684h功能号
movbx,3180h接口ID
int2fh
movax,eses/di=API_Entry入口段/偏移
orax,di
jz@3;es及di全为零,失败
movwordptr[entry],di
movwordptr[entry2],es
movax,ds设exec_int参数
moves,ax
leabx,bufes:bx,指向缓区首
r2w3:movah,2读80h硬盘MBR处NPAGE扇
moval,NPAGE
movcx,10:0:1(chs)
movdx,128
stdVxD出兰屏,写修
call[entry]
cmpbp,4096VxD按(8.3)返bp值
jae@2
addbx,bp修缓区首址
testah,1查读/写
jz@1此例ah=2,读盘
leasi,buf写入时,从后向前,移NPAGE*256字
addsi,NPAGE*512-1si指向原缓区尾
movdi,si
adddi,bpdi指向新缓区尾
movcx,NPAGE*256
repmovswds:si所指cx字,移到es:di
movcx,1
@1:call[entry]
cmpbp,4096
@2:je@3
cmpbp,1010h
jne@3
xorah,ah;释它页
call[entry]
@3:xorax,ax
moves,ax
movax,[bx1beh]成功/失败,72h矢量=分区表首字/9
moves:[1c8h],ax
财软.联盟.fs119.net
movah,4ch
int21h
cends
end@
(8.3)...V86_API_Entry(VMHANDLEhVM,CLIENT_STRUCT*pRegs)体
DWORDh,t;
CLIENT_STRUCTs;
if(pRegs->CBRS.Client_AH){//2读3写
h=(DWORD)Map_Flat(CLIENT_ES,CLIENT_BX);//h=客户缓区首es:bx的32位线性址
t=hpRegs->CBRS.Client_AL*512-1;//t=尾的线性址
if((h>>12)!=(t>>12)){
pRegs->CWRS.Client_BP=(4096-(h&4095));//首尾未囿同页,bp返客户增bx量
return;
}
if((h>>12)<0x110)//缓区能被V86寻,bp返4096
pRegs->CWRS.Client_BP=4096;
else
if(LinMapIntoV86(h>>12,hVM,0x10,1,0,&t)){
//缓区所在页,成功映入V86第0x10页,bp返0x1010
pRegs->CWRS.Client_BP=0x1010;
h=(16<<12)(h&4095);//由t及偏移,得缓区V86址h
}else{//无页等,bp返0x1110
pRegs->CWRS.Client_BP=0x1110;
return;
}
Save_Client_State(&s);//存reg
Begin_Nest_V86_Exec();//当前虚拟机,能寻V86
pRegs->CRS.Client_ES=(h>>4);//es=址h的段值
财管,家园,fs119.net
pRegs->CRS.Client_EBX=(h&15);//bx=址h的偏移
Exec_Int(0x13);
End_Nest_Exec();//复原
Restore_Client_State(&s);
if(pRegs->CWRS.Client_Flags&1024){//方向,控兰屏
sprintf((char*)s.CBRS.Client_res30,"%x",pRegs->CWRS.Client_BP);
SHELL_SYSMODAL_Message(hVM,MB_SYSTEMMODAL,(char*)s.CBRS.Client_res30,"bp");
}
}else//知bp返0x1010时,客户释它页
MapIntoV86(GetNulPageHandle(),hVM,16,1,0,0);
(8.4)装VxD法
静态:
放C.VXD于c:\windows\system,在c:\windows\system.ini的386Enh,写device=C.VxD,再reboot
动态4法:
用VxD_Loader,选C.VXD
用DriverMonitor,先打开C.VXD,再Start
放C.VXD于c:\windows\system\iosubsys,再reboot
用笔者DOS窗口a的exe
#include
#definepre"\\\\.\\"
main(intac,char*av[]){
char*vxd;
HANDLEh;
if(ac==1)printf("vxd_load?.vxd\n");
else{
vxd=malloc(strlen(pre)strlen(av[1]));
sprintf(vxd,"%s%s",pre,av[1]);
h=CreateFile(vxd,0,0,0,0,FILE_FLAG_DELETE_ON_CLOSE,0); 财管家.园.fs119.net
if(h!=INVALID_HANDLE_VALUE){
printf("Tounload,hitEnter");
getch();
CloseHandle(h);
}
}
}
装C.VXD,事毕,敲回车到窗a,卸此VXD
财,软联盟,fs119.net
数据统计中!!
Google.cn搜索关键字:
实现 逻辑 分区 列出 mov ax db al lea bp dx ah buf
Google.cn搜索相关文章:
谷歌中搜索全球网 仿FDISK及PQMAGIC列出分区逻辑盘符的prw.asm实现
百度中搜索 仿FDISK及PQMAGIC列出分区逻辑盘符的prw.asm实现
谷歌中搜索www.fs119.net 仿FDISK及PQMAGIC列出分区逻辑盘符的prw.asm实现
上一篇:驻留exe文件
Google.cn搜索相关文章:
谷歌中搜索全球网 仿FDISK及PQMAGIC列出分区逻辑盘符的prw.asm实现
百度中搜索 仿FDISK及PQMAGIC列出分区逻辑盘符的prw.asm实现
谷歌中搜索www.fs119.net 仿FDISK及PQMAGIC列出分区逻辑盘符的prw.asm实现
下一篇:5个DOS专用文件的6种io重定向,more实现管道原理
精品课程推荐
相关文章
用MASM32编写通用游戏改器流程 2007-06-15 09:41:44 5个DOS专用文件的6种io重定向,more实现管道原理 2007-06-15 09:41:43 仿FDISK及PQMAGIC列出分区逻辑盘符的prw.asm实现 2007-06-15 09:41:42 驻留exe文件 2007-06-15 09:41:41 动态库的执行时间 2007-06-15 09:41:41 矛与盾的较量——CRC实践篇 2007-06-15 09:41:40