中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS开发编程 & 发展交流 (开发室) » 扩展int13读取 MBR(硬盘主引导区)的原程序,端口读硬盘序列号
« [1] [2] »
作者:
标题: 扩展int13读取 MBR(硬盘主引导区)的原程序,端口读硬盘序列号 上一主题 | 下一主题
qb45
高级用户




积分 677
发帖 194
注册 2003-9-13
状态 离线
『楼 主』:  扩展int13读取 MBR(硬盘主引导区)的原程序,端口读硬盘序列号

基本 BIOS Int 13H 调用是 BIOS 提供的磁盘基本输入输出中断调用, 它可以完成磁盘(包括硬盘和软盘)的复位, 读写, 校验, 定位, 诊断, 格式化等功能.
它使用的就是 CHS 寻址方式, 因此最大识能访问 8 GB 左右的硬盘
扩展 Int13H 接口的目的是为了扩展 BIOS 的功能, 使其支持多于1024柱面的硬盘, 以及可移动介质的琐定, 解锁及弹出等功能
DAP 是基于绝对扇区地址的, 因此利用 DAP, Int13H 可以轻松地逾越 1024 柱面的限制, 因为它根本就不需要 CHS 的概念.
我在win98、dos71下用qb45调试成功
'在qbasic中调用中断,1 必须加入L命令,比如QB/L  2. 必须引用qb.bi',如下
'$INCLUDE: 'qb.bi'
DIM SHARED ax, bx, cx, dx, bp, si, di, ds, flags, es  '// 全局共享
BUFFdat$ = STRING$(512, 0)   '// 建立一个读写扇区缓冲区(512字节)
d1% = varSEG(buffdat$) '// 获得缓冲区的段地址
d2% = SADD(buffdat$) '// 获得缓冲区的偏移地址
'// 把段地址,偏移地址,读写命令等数据按要求写入数据包(DAP)
dat1$ = CHR$(&H10) + CHR$(0) + MKI$(1) + MKI$(d2%) + MKI$(d1%) + MKL$(0) + MKL$(0)

ds = varSEG(dat1$)   '// DS=数据包(DAP)的段地址
si = SADD(dat1$)      '// SI=数据包(DAP)的偏移地址
ax = &H4200            '// AX=调用扩展INT13的读扇区命令
dx = &H80               '// DX=第一个硬盘
xint &H13                '// 调用INT13中断

'//------把读出的MBR扇区内容保存到D盘的TESTHD.DAT文件中------
OPEN "d:\testhd.dat" FOR BINARY AS #1
PUT 1,1,BUFFDAT$
CLOSE #1
'//----------------------------------------------------------------------
END

'//中断调用的子程序
SUB xint (num%)
    DIM inregs AS RegTypeX
    DIM outregs AS RegTypeX
    inregs.ax = ax
    inregs.bx = bx
    inregs.cx = cx
    inregs.dx = dx
    inregs.si = si
    inregs.di = di
    inregs.ds = ds
    inregs.es = es
CALL INTERRUPTX(num%, inregs, outregs)
ax = outregs.ax
bx = outregs.bx
cx = outregs.cx
dx = outregs.dx
si = outregs.si
di = outregs.di
ds = outregs.ds
es = outregs.es
END SUB
[ Last edited by qb45 on 2006-7-9 at 11:14 ]



我(QB45)的照片与简历
http://www.programfan.com/club/showbbs.asp?id=197280
2004-8-9 00:00
查看资料  发送邮件  发短消息 网志  OICQ (406930019)  编辑帖子  回复  引用回复
Kinglion
铂金会员

痴迷DOS者


积分 5792
发帖 1921
注册 2003-6-20
来自 金獅電腦軟體工作室
状态 离线
『第 2 楼』:  

支持原创作品!



熟能生巧,巧能生精,一艺不精,终生无成,精亦求精,始有所成,臻于完美,永无止境!
金狮電腦軟體工作室愿竭诚为您服务!
QQ群:8393170(定期清理不发言者)
个人网站:http://www.520269.cn
电子邮件:doujiehui@vip.qq.com
微信公众号: doujiehui
2004-8-23 00:00
查看资料  发送邮件  访问主页  发短消息 网志  OICQ (79207959)  编辑帖子  回复  引用回复
DOSforever
金牌会员





积分 4639
发帖 2239
注册 2005-1-30
状态 离线
『第 3 楼』:  

请问各位,为何我在debug中直接填写要读取扇区的DAP参数而用扩展int13h不行呢?比如,要读出第一个硬盘的第一个物理扇区的内容到3333:3333地址处,DAP数据包是否应该如下:

10 00 01 00 33 33 33 33 00 00 00 00 00 00 00 00

debug
-a
mmmm:nnnn mov ah,42
mmmm:nnnn mov dl,80
mmmm:nnnn mov di,2000
mmmm:nnnn int13
mmmm:nnnn int3
mmmm:nnnn
-e2000 10 00 01 00 33 33 33 33 00 00 00 00 00 00 00 00
-g

执行后在DOS7.10下返回错误,即使查看内存地址3333:3333处也无要读出的数据。在Win98的DOS窗口下死机,热启动也不行。



DOS倒下了,但永远不死
DOS NEVER DIES !

投票调查:
http://www.cn-dos.net/forum/viewthread.php?tid=46187

本人尚未解决的疑难问题:
http://www.cn-dos.net/forum/viewthread.php?tid=15135
http://www.cn-dos.net/forum/viewthread.php?tid=47663
http://www.cn-dos.net/forum/viewthread.php?tid=48747
2005-5-30 00:00
查看资料  发短消息 网志   编辑帖子  回复  引用回复
qb45
高级用户




积分 677
发帖 194
注册 2003-9-13
状态 离线
『第 4 楼』:  

磁盘地址数据包  DAP 的结构如下:(DAP 是基于绝对扇区地址的, 可以轻松地逾越1024 柱面的限制)

struct DiskAddressPacket
       BYTE PacketSize;     // 数据包尺寸:
                             //(固定值,恒等于16,即10H,指本结构所占用的存储空间)
        BYTE Reserved;       // ==0
        WORD BlockCount;     // 要传输的数据块个数(以扇区为单位)
        DWORD BufferAddr;    // 传输缓冲地址(segment:offset)
        QWORD BlockNum;      // 磁盘起始绝对块地址
在扩展 Int13H 调用中一般使用如下寄存器约定:
       ds:si ==> 磁盘地址数据包( disk address packet )
       dl     ==> 驱动器号
       ah    ==> 功能代码 / 返回码

请你仔细看看扩展INT13的调用规范,你会发现
ds:si   ==> 磁盘地址数据包
而你的程序中是

  Quote:
mmmm:nnnn mov di,2000

你把SI弄成DI了!    如果你懂一点点Qbasic的话,就能从我的程序中发现你的这个错误!

[此贴子已经被作者于2005-6-10 17:32:54编辑过]





我(QB45)的照片与简历
http://www.programfan.com/club/showbbs.asp?id=197280
2005-6-10 00:00
查看资料  发送邮件  发短消息 网志  OICQ (406930019)  编辑帖子  回复  引用回复
DOSforever
金牌会员





积分 4639
发帖 2239
注册 2005-1-30
状态 离线
『第 5 楼』:  

多谢楼上的解答,按照你的方法果然能够成功的读取了!
但是一开始我所得到的资料中确实是写 DI 的,而且在该文中不止一处提到。以下是我找到的相关资料,几乎所以网上的关于扩展 int13h 详细说明都是源自这同一篇文章。后来我根据你指出的错误又再看了一遍,发现在“三. 接口规范”这一节中也确实是写 “ds:SI == 磁盘地址数据包” 的。但是在它后面的“3. API 详解”中所有的入口参数中又都写成“ds:DI = 磁盘地址数据包”。我不知道这是作者的笔误还是我的理解错了?
http://www.kaijia.net/info_Print.asp?ArticleID=542

[此贴子已经被作者于2005-6-30 9:43:01编辑过]



[ Last edited by dosforever on 2005-7-22 at 12:57 ]



DOS倒下了,但永远不死
DOS NEVER DIES !

投票调查:
http://www.cn-dos.net/forum/viewthread.php?tid=46187

本人尚未解决的疑难问题:
http://www.cn-dos.net/forum/viewthread.php?tid=15135
http://www.cn-dos.net/forum/viewthread.php?tid=47663
http://www.cn-dos.net/forum/viewthread.php?tid=48747
2005-6-30 00:00
查看资料  发短消息 网志   编辑帖子  回复  引用回复
qb45
高级用户




积分 677
发帖 194
注册 2003-9-13
状态 离线
『第 6 楼』:  

我有着和你相同的经历,我当时要用QBASIC语言做一个磁盘编辑器,因为老的INT13有限制,所以我到处去找资料,在本论坛我也发帖子问过哪里能找到这样的资料,结果有个网友给了我一个老外的中断大全网址,资料非常全,可惜我看不懂E文,后来在罗云彬的汇编找到了中文资料,我就参考这个资料用QBASIC来试验读一个扇区,结果不成功,后来我实验了N次,死鸡了N次,头发白了N根,当时我真以为QBASIC没有这个能力,又想了想,都是编程语言,QBASIC应该能做到,没有做不到的事情,当时没有操作系统的时候,QBASIC还被当作操作系统在用呢,比尔大叔不是说:给我BASIC,没有做不到吗!想到这我就到处去问高手,还好,我在QQ上碰到一个懂编程又懂E文的网友,我请他看看E文帮我翻译,哈哈,原来是中文资料错误!我感觉,这个资料是翻译的人故意弄错的,他可能想,只要你爱好编程,而且肯研究,就能发现错误,实际上这个资料中并不只有这一处错误,最重要的错误是这个,然后还有个错误,在你读前63个扇区的时候没有问题,但是,只要读写大于63个扇区的时候,你就会发现读出来的并不是你要的!这个资料总共有3处错误!你可以看看E文的资料,具体网站我不记得了,不过在本论坛还是能找到我发的求助的帖子,里面有网友给的这个网址。我在《数据恢复论坛》也提到过技术资料下载区,INT13中文资料的错误,他们改了一下,没有改很好,但是在论坛里的编程讨论区有高手写的帖子里把这3个错误都指出来了



我(QB45)的照片与简历
http://www.programfan.com/club/showbbs.asp?id=197280
2005-7-5 00:00
查看资料  发送邮件  发短消息 网志  OICQ (406930019)  编辑帖子  回复  引用回复
TurboY
中级用户

绝不写垃圾帖


积分 322
发帖 99
注册 2004-7-3
来自 湖北
状态 离线
『第 7 楼』:  

我也被那个资料给耍了,程序一直出问题都不知道出在哪里,原来就是SI和DI的错了。
看来尽信书不如无书。



从95年开始用DOS3.2,96年在Windows3.1里认识了鼠标,97年开始用Win95,98年装过NetWare,99年迷过Linux,现在用WinXP、WinME和DOS7.1。一回首,从盲到忙,从忙到茫。
2005-8-31 16:08
查看资料  发送邮件  访问主页  发短消息 网志  OICQ (123693086)  编辑帖子  回复  引用回复
qb45
高级用户




积分 677
发帖 194
注册 2003-9-13
状态 离线
『第 8 楼』:  

是啊,在很多编程的资料里有些很细小但很关键的错误,有时候作者也不可能去验证它,现在网络流行你COPY我,我COPY他,最后弄得大家都有相同的味道了!

还好的是我只懂qbasic,烦恼相对就少,碰到解决不了的问题,我大不了就说:QBASIC可能没有这个能力

[ Last edited by qb45 on 2005-8-31 at 17:01 ]



我(QB45)的照片与简历
http://www.programfan.com/club/showbbs.asp?id=197280
2005-8-31 16:46
查看资料  发送邮件  发短消息 网志  OICQ (406930019)  编辑帖子  回复  引用回复
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『第 9 楼』:  

没学过QB,试着,好像看懂了,
现在就试一试吧,回头再来。。。。

2006-6-30 18:21
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『第 10 楼』:  

成功了!

另:
我不懂QB,不知道QB能不能一次就把地址取出来?

,qb45的代码中:
MKI$变量是不是可以从buffdat$中取出一个地址值就可以了?
下面的代码却分成了两次:
d1% = varSEG(buffdat$)
d2% = SADD(buffdat$)
因为,buffdat创建后,他的地址已固定。
没必要分解他的地址吧?

2006-6-30 19:45
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『第 11 楼』:  

用C语言调用扩展13中断,读写大硬盘已解决拉!
主要代码如下:(测试正确)

#include <dos.h>
#include <stdio.h>
void main(){
unsigned char buf[51200];
FILE *f;
union REGS in,out;
struct DiskAddressPacket
{
unsigned char PacketSize; /* 数据包尺寸(16字节)     */
unsigned char Reserved; /* ==0  */
unsigned int BlockCount; /* 要传输的数据块个数(以扇区为单位)    */
unsigned long BufferAddr;/* 传输缓冲地址(segment:offset)    */
unsigned long BlockNum;/* 磁盘起始绝对块地址     */
/*unsigned long ab;     */
}dap={16,0,100,0,16434495};
dap.BufferAddr=(unsigned long)buf;

in.h.ah = 0x42;
in.h.dl = 0x80;
in.x.si = &dap;
/*磁盘地址数据包(Disk Address Packet)  */

int86(0x13,&in,&out);

f=fopen("int13ext.dat","wb+");
fwrite(buf,512,100,f);
fclose(f);
}

2006-6-30 20:36
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『第 12 楼』:  

还发现个小奇怪:
在测试我的读写小硬盘的程序中,照理只能读写1023(3FF,1111111111)个柱面(0-1022)
但是,却能读写1024个柱面!

百思不得其解!
谁知道的说一下。。。

2006-6-30 20:41
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『第 13 楼』:  

TO DOSforever:
在DEBUG中,先要把DAP弄进去吧?
你是怎么弄进去的?

2006-6-30 20:49
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
DOSforever
金牌会员





积分 4639
发帖 2239
注册 2005-1-30
状态 离线
『第 14 楼』:  

呵呵呵呵……
进去的,我上面不写着是怎么进去的吗,注意中间的

-e2000 10 00 01 00 33 33 33 33 00 00 00 00 00 00 00 00

一行。也就是手工把某个特定的参数填进去试验一下 int13h 的扩展调用。

原来我发这个贴的是论坛还是 DVBBS ,后来转成 DISCUZ! 后在排版上就有些变形了,该换行的没换行,都挤到一起了。



DOS倒下了,但永远不死
DOS NEVER DIES !

投票调查:
http://www.cn-dos.net/forum/viewthread.php?tid=46187

本人尚未解决的疑难问题:
http://www.cn-dos.net/forum/viewthread.php?tid=15135
http://www.cn-dos.net/forum/viewthread.php?tid=47663
http://www.cn-dos.net/forum/viewthread.php?tid=48747
2006-6-30 22:07
查看资料  发短消息 网志   编辑帖子  回复  引用回复
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『第 15 楼』:  

哦,刚才没太注意,
现在,知道了,等一下我也试一下。。。
多谢。。

2006-7-1 00:55
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
« [1] [2] »
请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: