用C语言怎么样才能把某一扇区(如主引导扇区)的数据读到内存中的某位位置?
利用dos的debug可以把硬盘的某一扇区的数据读到硬盘!例如:
a
mov ax,0201
mov bx,1000;读到1000这个地方!
mov cx,0001
mov dx,0080
int 13
int 3
ctrl + C
用TC语言的int86可以利用中断13来读取硬盘数据.
如下所示:
union REGS i,o;
struct SREGS es;
s=(char*)malloc(1000);
i.h.ah=0x02;
i.h.al=1;
i.h.ch=0;
i.h.cl=1;
i.h.dh=0;
i.h.dl=80;
i.x.bx=s;
es.es=0;
int86(0x13,&i,&o);
请问如上的一段代码,能把主引导区读到s所指向的内存中去吗?
请指点迷津?
问题点数:120、回复次数:17Top
1 楼leojay(leojay)回复于 2002-01-18 23:54:07 得分 0
当然可以了。Top
2 楼ttzzgg_80713(身无立锥地,常有四海心---老子有条命)回复于 2002-01-19 00:24:09 得分 0
关注,作个记号先Top
3 楼foxmike(我们的故事爱就爱到值得)回复于 2002-01-19 00:27:14 得分 0
有兴趣,关注Top
4 楼Ykang()回复于 2002-01-19 00:36:48 得分 100
可能不可以,因为你的s是由远堆分配的指针,是个带段地址:偏移量的指针,而r.x.bx是个int,只有16bit,所以r.x.bx的值只是s的偏移量部分,而段地址没有传递过去。
所以你要这样定义 char s[512] 才可以。
如果你要检验是否读出来啦,可以写到文件里去看看;
前面声明: FLLE * f;
.....
最后在加: f=fopen("C:\Partable.bin","w+b");
fwrite(s,512,1,f);
最后你去看你的文件内容与其他工具软件读出的是否一样就可以证明啦。
下附全部程序:
#include <dos.h>
#include <stdio.h>
#include <alloc.h>
int main()
{
union REGS i,o;
struct SREGS es;
FILE * f;
char s[512] ;
i.h.ah=0x02;
i.h.al=1;
i.h.ch=0;
i.h.cl=1;
i.h.dh=0;
i.h.dl=80;
i.x.bx=(unsigned short)s;
es.es=0;
int86(0x13,&i,&o);
f=fopen("C:\Partable.bin","w+b");
fwrite(s,512,1,f);
}
在BC45下编译通过
Top
5 楼dedema(思想恐龙)回复于 2002-01-20 11:43:58 得分 0
现在改成如下这样的程序:
#include <dos.h>
#include <stdio.h>
#include <alloc.h>
unsigned char s[512]="";
int main()
{union REGS i,o;
struct SREGS es={0};
FILE * f;
clrscr();
i.h.ah=0x02;
i.h.al=1;
i.h.ch=0;
i.h.cl=1;
i.h.dh=0;
i.h.dl=80;
i.x.bx=(unsigned short)s;
es.es=0;
int86x(0x13,&i,&o,&es);
printf("%d\n",*s);/*把想象中的那个主引导区的第一个字符打印在屏幕上
本应该是数字3,其ASCII码值为33,可是并不是这样。*/
getch();
f=fopen("C:\Partable.bin","w+b");
fwrite(s,512,1,f);
fclose(f);
}
以上程序并不能达到目的,问题出在哪里?
Top
6 楼bigshi(小旋子)回复于 2002-01-20 19:25:06 得分 0
to dedema:
和我遇到了同样的问题,感谢!Top
7 楼Ykang()回复于 2002-01-20 22:01:48 得分 0
对不起啊,我没有看清楚程序运行结果.因为我的硬盘上原来有个partable.Bin文件:
你后来的代码错在:i.h.dl=80;应该是i.h.dl=0x80;
再由于你的s是全局变量,在用int86x时,es的值很重要,应该是es.es=_DS;
下面的程序是两个版本,都运行成功:
////////////////////////////////////////////
// 1: s是全局变量的数组,int86x版本
// 用int86也一样(s是全局或局部,在小模式下)
////////////////////////////////////////////
#include <dos.h>
#include <stdio.h>
#include <alloc.h>
char s[512]={0} ;
int main()
{
union REGS i,o;
struct SREGS es;
FILE * f;
i.h.ah=0x02;
i.h.al=1;
i.h.ch=0;
i.h.cl=1;
i.h.dh=0;
i.h.dl=0x80;
i.x.bx=(unsigned short)s;
es.es=_DS;
int86x(0x13,&i,&o,&es);
f=fopen("C:\\Partable.bin","w+b");
fwrite(s,512,1,f);
fclose(f);
}
//////////////////////////////////////////////////////
// 2:s是动态分配的指针,int86x版本
// 要注意es.es的值
//////////////////////////////////////////////////////
#include <dos.h>
#include <stdio.h>
#include <alloc.h>
int main()
{
union REGS i,o;
struct SREGS es;
FILE * f;
//char s[512]={0} ;
char *s=(char*)malloc(512);
i.h.ah=0x02;
i.h.al=1;
i.h.ch=0;
i.h.cl=1;
i.h.dh=0;
i.h.dl=0x80;
i.x.bx=(unsigned short)s;
es.es=FP_SEG(s);
printf(" s=%Fp,SS=%x,DS=%x,ES=%x",s,_SS,_DS,_ES);
int86x(0x13,&i,&o,&es);
f=fopen("C:\\Partable.bin","w+b");
fwrite(s,512,1,f);
fclose(f);
free(s);
}
Top
8 楼willa(chocolate boy)回复于 2002-01-20 22:52:15 得分 0
关注, 作记号Top
9 楼dedema(思想恐龙)回复于 2002-01-22 23:36:34 得分 0
to Ykang()
你的回复简直就是我最好的教材了。
不过,对于es.es=FP_SEG(s);这个语句中,FP_SEG(s)是宏命令,它相当于:es.es=(unsigned)((unsigned long)
s>>16);是吧?程序试验的结果也表明正是如此!
麻烦又来了?s是一个指针变量,占用2字节(这里是TC2.0)。当这个s被强行转化成unsigned long时,它的高位应
为0才对的吧,再经过>>16位后的返回值应为0啊,这样,es.es的值不就是为0了吗?实际却并非如此!
路漫漫其修远兮。。。。。。。。
Top
10 楼dedema(思想恐龙)回复于 2002-01-23 23:32:32 得分 0
FP_SEG(s)是个返回段地址的函数,我刚知道的!Top
11 楼Ykang()回复于 2002-01-24 10:39:07 得分 0
查看一下汇编代码,就会很明白的。 Top
12 楼dedema(思想恐龙)回复于 2002-01-24 23:09:51 得分 0
怎么查?我查不来的啊、Top
13 楼walkonthesky(★★★★★)回复于 2002-01-25 09:11:13 得分 0
记号Top
14 楼Ykang()回复于 2002-01-25 21:50:43 得分 0
Tcc -B 就可以产生汇编输出,还可以利用TD.exe来调试你的程序,也能带源码调试.Top
15 楼nipusa00100(泥菩萨)回复于 2002-01-25 22:48:12 得分 0
gzgzgzgzgzgzgTop
16 楼acqy(Just Programmer)回复于 2002-01-26 09:47:29 得分 20
#include <dos.h>
int iosector (int disk,unsigned long cylinder, unsigned long head, unsigned long sector, int action, unsigned char * buffer)
/*disk=磁盘代号,0=软盘,80h=第一硬盘*/
/*cylinder=柱面,head=磁头,sector=扇区*/
/*action=读/写:2h=读,3h=写*/
/*buffer=数据缓冲区*/
{
union REGS regs;
struct SREGS sregs;
regs.h.ah=action;
regs.h.al=1;
regs.x.bx=FP_OFF(buffer);
sregs.es=FP_SEG(buffer);
regs.h.ch=cylinder;
regs.h.cl=sector;
regs.h.dh=head;
regs.h.dl=disk;
int86x(0x13,®s,®s,&sregs);
return regs.ax;
}
void main ()
{
unsigned char buff[512];
iosector(0x80,0,0,1,2,buffer); /*将硬盘的0柱0头1扇区读到buffer中*/
}
如果您需要扩展INT 13H中断读写硬盘的程序,请与Arcobet工作室联系:acqy@263.net。在这种扩展方式下,能够读写大于100GB的大容量硬盘。Top
17 楼dedema(思想恐龙)回复于 2002-04-24 00:05:36 得分 0
有时间一定给分!Top




