|
qb45
高级用户
   
积分 677
发帖 194
注册 2003-9-13
状态 离线
|
『楼 主』:
扩展int13读取 MBR(硬盘主引导区)的原程序,端口读硬盘序列号
使用 LLM 解释/回答一下
基本 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 ]
The basic BIOS Int 13H call is a disk basic input/output interrupt call provided by BIOS. It can complete functions such as disk (including hard disk and floppy disk) reset, read/write, verification, positioning, diagnosis, formatting, etc.
It uses the CHS addressing method, so it can only access a hard disk of about 8 GB at most.
The purpose of extending the Int13H interface is to expand the functions of BIOS, so that it can support hard disks with more than 1024 cylinders, as well as functions such as locking, unlocking and ejecting of removable media.
DAP is based on the absolute sector address, so using DAP, Int13H can easily surpass the limit of 1024 cylinders because it doesn't need the concept of CHS at all.
I debugged successfully under win98 and dos71 with qb45
'In qbasic, to call the interrupt, 1 must add the L command, such as QB/L 2. Must reference qb.bi', as follows
'$INCLUDE: 'qb.bi'
DIM SHARED ax, bx, cx, dx, bp, si, di, ds, flags, es '// Global sharing
BUFFdat$ = STRING$(512, 0) '// Create a read/write sector buffer (512 bytes)
d1% = varSEG(buffdat$) '// Get the segment address of the buffer
d2% = SADD(buffdat$) '// Get the offset address of the buffer
'// Write data such as segment address, offset address, read/write command, etc. into the data packet (DAP) as required
dat1$ = CHR$(&H10) + CHR$(0) + MKI$(1) + MKI$(d2%) + MKI$(d1%) + MKL$(0) + MKL$(0)
ds = varSEG(dat1$) '// DS = segment address of the data packet (DAP)
si = SADD(dat1$) '// SI = offset address of the data packet (DAP)
ax = &H4200 '// AX = call the read sector command of extended INT13
dx = &H80 '// DX = the first hard disk
xint &H13 '// Call INT13 interrupt
'//------Save the content of the read MBR sector to the TESTHD.DAT file on drive D------
OPEN "d:\testhd.dat" FOR BINARY AS #1
PUT 1,1,BUFFDAT$
CLOSE #1
'//----------------------------------------------------------------------
END
'//Subroutine for interrupt call
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 |
|
|
Kinglion
铂金会员
       痴迷DOS者
积分 5798
发帖 1924
注册 2003-6-20 来自 金獅電腦軟體工作室
状态 离线
|
『第 2 楼』:
使用 LLM 解释/回答一下
支持原创作品!
|

熟能生巧,巧能生精,一艺不精,终生无成,精亦求精,始有所成,臻于完美,永无止境!
金狮電腦軟體工作室愿竭诚为您服务!
QQ群:8393170(定期清理不发言者)
个人网站:http://www.520269.cn
电子邮件:doujiehui@vip.qq.com
微信公众号: doujiehui
|
|
2004-8-23 00:00 |
|
|
DOSforever
金牌会员
     
积分 4639
发帖 2239
注册 2005-1-30
状态 离线
|
『第 3 楼』:
使用 LLM 解释/回答一下
请问各位,为何我在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窗口下死机,热启动也不行。
Excuse me, everyone, why can't I use the extended int13h when I directly fill in the DAP parameters of the sector to be read in debug? For example, to read the content of the first physical sector of the first hard disk to the address 3333:3333, should the DAP data packet be as follows:
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
After execution, an error is returned under DOS7.10, and even if I check the memory address 3333:3333, there is no data to be read. It crashes in the DOS window of Win98, and a warm boot doesn't work.
|

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 楼』:
使用 LLM 解释/回答一下
磁盘地址数据包 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 ==> 磁盘地址数据包
而你的程序中是 mmmm:nnnn mov di,2000
你把SI弄成DI了! 如果你懂一点点Qbasic的话,就能从我的程序中发现你的这个错误!
The structure of the Disk Address Packet (DAP) is as follows: (DAP is based on absolute sector addresses and can easily exceed the limit of 1024 cylinders)
struct DiskAddressPacket
BYTE PacketSize; // Packet size:
// (Fixed value, always equal to 16, that is, 10H, refers to the storage space occupied by this structure)
BYTE Reserved; // ==0
WORD BlockCount; // Number of data blocks to be transferred (in sectors)
DWORD BufferAddr; // Transfer buffer address (segment:offset)
QWORD BlockNum; // Absolute starting block address of the disk
In the extended Int13H call, the following register conventions are generally used:
ds:si ==> Disk address packet (disk address packet)
dl ==> Drive number
ah ==> Function code / return code
Please take a close look at the call specification of the extended INT13, and you will find that
ds:si ==> Disk address packet
而你的程序中是 mmmm:nnnn mov di,2000
You have made SI into DI! If you know a little Qbasic, you can find this mistake from my program!
|

我(QB45)的照片与简历
http://www.programfan.com/club/showbbs.asp?id=197280
|
|
2005-6-10 00:00 |
|
|
DOSforever
金牌会员
     
积分 4639
发帖 2239
注册 2005-1-30
状态 离线
|
|
2005-6-30 00:00 |
|
|
qb45
高级用户
   
积分 677
发帖 194
注册 2003-9-13
状态 离线
|
『第 6 楼』:
使用 LLM 解释/回答一下
我有着和你相同的经历,我当时要用QBASIC语言做一个磁盘编辑器,因为老的INT13有限制,所以我到处去找资料,在本论坛我也发帖子问过哪里能找到这样的资料,结果有个网友给了我一个老外的中断大全网址,资料非常全,可惜我看不懂E文,后来在罗云彬的汇编找到了中文资料,我就参考这个资料用QBASIC来试验读一个扇区,结果不成功,后来我实验了N次,死鸡了N次,头发白了N根,当时我真以为QBASIC没有这个能力,又想了想,都是编程语言,QBASIC应该能做到,没有做不到的事情,当时没有操作系统的时候,QBASIC还被当作操作系统在用呢,比尔大叔不是说:给我BASIC,没有做不到吗!想到这我就到处去问高手,还好,我在QQ上碰到一个懂编程又懂E文的网友,我请他看看E文帮我翻译,哈哈,原来是中文资料错误!我感觉,这个资料是翻译的人故意弄错的,他可能想,只要你爱好编程,而且肯研究,就能发现错误,实际上这个资料中并不只有这一处错误,最重要的错误是这个,然后还有个错误,在你读前63个扇区的时候没有问题,但是,只要读写大于63个扇区的时候,你就会发现读出来的并不是你要的!这个资料总共有3处错误!你可以看看E文的资料,具体网站我不记得了,不过在本论坛还是能找到我发的求助的帖子,里面有网友给的这个网址。我在《数据恢复论坛》也提到过技术资料下载区,INT13中文资料的错误,他们改了一下,没有改很好,但是在论坛里的编程讨论区有高手写的帖子里把这3个错误都指出来了
I have the same experience as you. At that time, I needed to use QBASIC language to make a disk editor. Because the old INT13 had limitations, so I searched everywhere for materials. I also posted a thread in this forum asking where I could find such materials. As a result, a netizen gave me a foreigner's interrupt大全 website, and the materials were very complete. Unfortunately, I couldn't understand English. Later, I found Chinese materials in Luo Yunbin's assembly language. I then referred to this material to experiment with reading a sector in QBASIC, but it didn't succeed. Later, I experimented many times, got stuck many times, and my hair turned white many times. At that time, I really thought QBASIC didn't have this ability. Then I thought again, all are programming languages, QBASIC should be able to do it, there's nothing that can't be done. When there was no operating system at that time, QBASIC was also used as an operating system. Didn't Bill Gates say: Give me BASIC, and there's nothing that can't be done! Then I asked experts everywhere. Fortunately, I met a netizen on QQ who was proficient in programming and English. I asked him to read the English for me. Haha, it turned out that the Chinese material was wrong! I felt that the person who translated this material deliberately made mistakes. He might think that as long as you are fond of programming and willing to study, you can find the mistakes. In fact, there are not only this mistake in this material, the most important mistake is this one, and then there is another mistake. When you read the first 63 sectors, there is no problem, but as long as you read and write more than 63 sectors, you will find that what is read is not what you want! There are a total of 3 mistakes in this material! You can look at the English materials. I don't remember the specific website, but you can still find the help thread I posted in this forum. There are netizens who gave this website. I also mentioned the technical materials download area in the "Data Recovery Forum", and the mistakes in the INT13 Chinese materials. They made some changes, but not very well. But in the programming discussion area of the forum, there are experts who wrote threads pointing out these 3 mistakes.
|

我(QB45)的照片与简历
http://www.programfan.com/club/showbbs.asp?id=197280
|
|
2005-7-5 00:00 |
|
|
TurboY
中级用户
   绝不写垃圾帖
积分 322
发帖 99
注册 2004-7-3 来自 湖北
状态 离线
|
『第 7 楼』:
使用 LLM 解释/回答一下
我也被那个资料给耍了,程序一直出问题都不知道出在哪里,原来就是SI和DI的错了。
看来尽信书不如无书。
I was also tricked by that material. The program has been having problems and I don't know where they are. It turns out it's the fault of SI and DI. It seems that it's better to not fully rely on books.
|

从95年开始用DOS3.2,96年在Windows3.1里认识了鼠标,97年开始用Win95,98年装过NetWare,99年迷过Linux,现在用WinXP、WinME和DOS7.1。一回首,从盲到忙,从忙到茫。 |
|
2005-8-31 16:08 |
|
|
qb45
高级用户
   
积分 677
发帖 194
注册 2003-9-13
状态 离线
|
『第 8 楼』:
使用 LLM 解释/回答一下
是啊,在很多编程的资料里有些很细小但很关键的错误,有时候作者也不可能去验证它,现在网络流行你COPY我,我COPY他,最后弄得大家都有相同的味道了!
还好的是我只懂qbasic,烦恼相对就少,碰到解决不了的问题,我大不了就说:QBASIC可能没有这个能力
Last edited by qb45 on 2005-8-31 at 17:01 ]
Yeah, in many programming materials, there are some very small but crucial errors. Sometimes the author can't verify it. Now the internet is popular with you copying me and me copying you, and finally everyone has the same flavor!
Fortunately, I only know qbasic, so the troubles are relatively less. When I encounter problems I can't solve, I can just say: QBASIC may not have this ability
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 |
|
|
GOTOmsdos
铂金会员
       C++启程者
积分 5154
发帖 1827
注册 2003-7-18
状态 离线
|
『第 9 楼』:
使用 LLM 解释/回答一下
没学过QB,试着,好像看懂了,
现在就试一试吧,回头再来。。。。
Haven't learned QB, try it, seems to understand,
Now just give it a try, come back later...
|
|
2006-6-30 18:21 |
|
|
GOTOmsdos
铂金会员
       C++启程者
积分 5154
发帖 1827
注册 2003-7-18
状态 离线
|
『第 10 楼』:
使用 LLM 解释/回答一下
成功了!
另:
我不懂QB,不知道QB能不能一次就把地址取出来?
,qb45的代码中:
MKI$变量是不是可以从buffdat$中取出一个地址值就可以了?
下面的代码却分成了两次:
d1% = varSEG(buffdat$)
d2% = SADD(buffdat$)
因为,buffdat创建后,他的地址已固定。
没必要分解他的地址吧?
It worked!
Another:
I don't know QB, I don't know if QB can get the address at once?
In the code of qb45:
Can the MKI$ variable take out an address value from buffdat$?
The following code is divided into two times:
d1% = varSEG(buffdat$)
d2% = SADD(buffdat$)
Because, after buffdat is created, its address is fixed.
There is no need to decompose its address, right?
|
|
2006-6-30 19:45 |
|
|
GOTOmsdos
铂金会员
       C++启程者
积分 5154
发帖 1827
注册 2003-7-18
状态 离线
|
『第 11 楼』:
使用 LLM 解释/回答一下
用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);
}
Calling the extended 13h interrupt in C language to read and write large hard drives is solved!
The main code is as follows: (tested correctly)
#include <dos.h>
#include <stdio.h>
void main(){
unsigned char buf;
FILE *f;
union REGS in,out;
struct DiskAddressPacket
{
unsigned char PacketSize; /* Packet size (16 bytes) */
unsigned char Reserved; /* ==0 */
unsigned int BlockCount; /* Number of data blocks to transfer (in sectors) */
unsigned long BufferAddr;/* Transfer buffer address (segment:offset) */
unsigned long BlockNum;/* Starting absolute block address of the disk */
/*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 (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 楼』:
使用 LLM 解释/回答一下
还发现个小奇怪:
在测试我的读写小硬盘的程序中,照理只能读写1023(3FF,1111111111)个柱面(0-1022)
但是,却能读写1024个柱面!
百思不得其解!
谁知道的说一下。。。
Also found a small oddity:
In the program for testing my read/write small hard disk,按理说it should only be able to read and write 1023 (3FF, 1111111111) cylinders (0-1022)
But, it can read and write 1024 cylinders!
Puzzled!
Anyone who knows, please speak up...
|
|
2006-6-30 20:41 |
|
|
GOTOmsdos
铂金会员
       C++启程者
积分 5154
发帖 1827
注册 2003-7-18
状态 离线
|
『第 13 楼』:
使用 LLM 解释/回答一下
TO DOSforever:
在DEBUG中,先要把DAP弄进去吧?
你是怎么弄进去的?
TO DOSforever:
In DEBUG, you first need to load the DAP, right?
How did you load it?
|
|
2006-6-30 20:49 |
|
|
DOSforever
金牌会员
     
积分 4639
发帖 2239
注册 2005-1-30
状态 离线
|
|
2006-6-30 22:07 |
|
|
GOTOmsdos
铂金会员
       C++启程者
积分 5154
发帖 1827
注册 2003-7-18
状态 离线
|
『第 15 楼』:
使用 LLM 解释/回答一下
哦,刚才没太注意,
现在,知道了,等一下我也试一下。。。
多谢。。
Oh, I didn't pay much attention just now,
Now, I know, I'll try it later...
Thanks.
|
|
2006-7-1 00:55 |
|
|