CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
花落谁家,你作主! 盛大widget设计大赛英雄榜
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C语言

用C语言怎么样才能把某一扇区(如主引导扇区)的数据读到内存中的某位位置?

楼主dedema(思想恐龙)2002-01-18 23:48:51 在 C/C++ / 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,&regs,&regs,&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

相关问题

  • 谁知道WinXP的引导扇区的第一扇区信息?
  • 急,引导扇区错误,请帮助!!!!
  • 硬盘主引导扇区的读写??
  • 启动WIN2000 PRO时出错?!引导扇区问题?
  • 如何用dd导出linux引导扇区???
  • 如何杀除引导扇区病毒chan(b)?
  • 如何复原被Linux改写的引导扇区呢
  • 主引导扇区(0,0,1)坏了,怎么办?
  • 我的硬盘出现了坏的扇区(C盘),怎么办?
  • 安装linux,引系统不能正常启动,引导扇区破坏。急!!!!!!!!

关键词

  • 硬盘
  • 引导
  • 指针
  • 数据
  • 文件
  • es
  • 扇区
  • partable
  • w+b
  • regs

得分解答快速导航

  • 帖主:dedema
  • Ykang
  • acqy

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo