用MASM、TC2.0 写一个简单的x86引导程序 - lvjinhua的专栏 - CSDNBlog

来源:互联网 发布:java 泛型方法 返回值 编辑:程序博客网 时间:2024/05/16 17:04
导读:

/* file: load.c */
/*这个程序如此简单,功能只有两个,接受字符和显示,又编译连接吧。
现在我们生成了两个文件boot.exe,kernel.exe。其中boot.exe不要执行,你可以在dos
下运行的是kernel.exe,可以看看写对没有。
现在就差把这两个文件写入软盘的1,2扇区了。可是你会发现很怪的问题,boot有603字
节,kernel有522字节,但是一个扇区只有512字节,怎么写得下?这个问题我最先也迷
惑,后来把两个exe文件反汇编才知道真正我们写的代码出现在exe文件的513字节处,
exe文件的前512字节是mircosoft定义的exe文件的前缀,其中有exe文件标识,大小,
段定位指针等东西,这512字节我们不需要我们就只要后面的,那么我们就来写个程序
把boot.exe 和kernel.exe 写入软盘吧,(注意写入引导扇区的时候最后两个字节必须
是55aa这是规定的引导扇区的标识。)我这里选的是用tc2.0了,当然也可以用汇编写,
下面是writebt.c
*/
#include
#include
union REGS inreg,outreg;
struct SREGS segreg;
main()
{
    int i;
    char boot_buf[512];                          /*暂存放boot.exe的内容*/
    char kernel_buf[512];                        /*暂存放kernel.exe的内容*/
    FILE *fp;
    for(i=0;i<512;i++)
    {                                           /*先把这两个缓冲区清0*/
        boot_buf[i]=0;
        kernel_buf[i]=0;
    }
    if((fp=fopen("boot.exe","rb"))==NULL)
    {
        printf("cannot find boot.exe");exit(0);
    } /*打开boot.exe*/
    fseek(fp,512L,0);                            /*直接定位到文件第513个字节处,即512L*/
    i=0;
    while(1)
    {
        fread(&boot_buf[i],1,1,fp);                /*读入后面的所有内容直到结束*/
        i++;
        if(feof(fp))
        {
            fclose(fp);
            break;
        }
    }
    boot_buf[510] = 0x55;                        /*最后两个字节必须为55aa*/
    boot_buf[511] = 0xaa;
   
    /* 设置:将boot中的引导程序写入A盘的第0磁道1扇区*/
    inreg.h.ah=0x03;                             /*调用bios13h的3号写盘功能*/
    inreg.h.al=0x1;                              /*要读的扇区数为1*/
    inreg.h.ch=0;                                /*磁道号为0*/
    inreg.h.cl=1;                                /*扇区号为1*/
    inreg.h.dh=0;                                /*磁头号为0*/
    inreg.h.dl=0;                                /*驱动器号为0,即a盘*/
    inreg.x.bx=FP_OFF(boot_buf);                 /*bx中写boot_buf的内存偏移地址*/
    segreg.es=FP_SEG(boot_buf);                  /*es中写它的内存段地址*/
    int86x(0x13,&inreg,&outreg,&segreg);         /*调中断写盘*/
    if (_AH!=0)                                 /*ah为0刚写盘成功,否则退出*/
    {
        printf("error writing");exit(0);
    }
    else
    {
        printf("ok");
    }
   
   
    if((fp=fopen("kernel.exe","rb"))==NULL)        /*打开kernel.exe*/
    {
        printf("cannot find kernel.exe");exit(0);
    }
    fseek(fp,512L,0);                              /*直接定位到文件第513个字节处,即512L*/
    i=0;
    while(1)
    {
        fread(&kernel_buf[i],1,1,fp);               /*读入后面的所有内容直到结束*/
        i++;
        if(feof(fp))
        {
            fclose(fp);
            break;
        }
    }
   
    /* 设置:将kernel中的程序写入A盘的第0磁道2扇区*/
    inreg.h.ah=0x03;
    inreg.h.al=0x1;
    inreg.h.ch=0;
    inreg.h.cl=2;                 /*扇区号为2*/
    inreg.h.dh=0;
    inreg.h.dl=0;
    inreg.x.bx=FP_OFF(kernel_buf);
    segreg.es=FP_SEG(kernel_buf);
    int86x(0x13,&inreg,&outreg,&segreg);
    if (_AH!=0)
    {
        printf("error writing");exit(0);
    }
    else
    {
        printf("ok");
    }
   
   
}



本文转自
http://blog.csdn.net/lvjinhua/archive/2005/04/16/350429.aspx
原创粉丝点击