跳到main函数

来源:互联网 发布:淘宝1元秒杀优惠卷 编辑:程序博客网 时间:2024/06/10 08:32

首先我设计一个简单的mian.c,打开中断然后进入死循环。

#define sti() __asm__ ("sti"::)void main(void){sti();while(1);}


同时对应的我们把head.S中是sti注释掉

代码如下:

#define Descriptor(base,lim,attr)\.word lim&0xffff;\.word base&0xffff;\.byte (base>>16)&0xff;\.word ((lim>>8)&0xf00)|(attr&0x0f0ff);\.byte ((base>>24)&0xff)    #define Gate(Selector,Offset,PCount,Attr)\  .2byte (Offset&0xffff);\  .2byte (Selector);\  .2byte (PCount&0x1f)|((Attr<<8)&0xff00);\  .2byte ((Offset>>16)&0xffff)      DA_32=0x4000          //32位模式DA_LIMIT_4K=0x8000          //颗粒度为4096DA_DRW=0x92            //数据段可读可写DA_CR=0x9A            //可读可执行DA_C   = 0x98 SETUPSEG = 0x9020SETUPAddr = SETUPSEG<<4DA_386CGate = 0x8c DA_386IGate = 0x8E DA_PL0 = 0x00.text  .globl start/*程序从start处开始运行*/  .code32 _pg_dir://页目录将会存放在这里 start:movl     $0x20,%eax         mov     %ax,%ds //因为ds是数据段寄存器,所以要加载一个数据段,否则会发生异常(可以试试0x08描述符)    mov     %ax,%es          mov     %ax,%ss        mov  $0xffff,%esp /*加载gdtr即将全局描述符表gdt的首地址和gdt的界限赋给gdtr寄存器*/             lgdt GdtPtr     lidt IdtPtr    movl     $0x20,%eax         mov     %ax,%ds       mov     %ax,%es          mov     %ax,%ss        mov  $0xffff,%esp     ljmp $0x8,$LABEL_SEG_CODE32    .align  4    LABEL_SEG_CODE32:  .code32      movw $0x10,%ax      movw %ax,%gs      movl $((80*12+79)*2),%edi/*第12行,79列*/      movb $0x0c,%ah/*高四位表示黑底,低四位表示红字*/      movb $'S',%al/*显示的字符*/      movw %ax,%gs:(%edi)      int $0x80    //sti    jmp after_page_tables              loop1:/*无限循环*/      jmp loop1    .align  4INT_TEST:  .code32       movl $((80*13+79)*2),%edi/*第11行,79列*/      movb $0x0c,%ah/*高四位表示黑底,低四位表示红字*/      movb $'I',%al/*显示的字符*/      movw %ax,%gs:(%edi)     iret             loop2:/*无限循环*/      jmp loop2      /**每个页表长4kb字节,而每个页表项需要4个字节,因此一个页表可以存放1024个表项*/       .org 0x1000pg0:.org 0x2000pg1:.org 0x3000pg2:.org 0x4000pg3:.org 0x5000//定义下面的内存块从0x5000开始//软盘缓冲区_tmp_floppy_area:.fill 1024,1,0 //预留1024项,每项1字节,填充数值为0after_page_tables:pushl $0pushl $0pushl $0pushl $L6pushl $mainjmp setup_pagingL6:jmp L6int_msg:.asciz "Unknown interrupt\n\r".align  4ignore_int:  .code32       movl $((80*13+79)*2),%edi/*第11行,79列*/      movb $0x0c,%ah/*高四位表示黑底,低四位表示红字*/      movb $'I',%al/*显示的字符*/      movw %ax,%gs:(%edi)     iret             loop21:/*无限循环*/      jmp loop21 .align  4ClockHandler:      movl $((80*14+79)*2),%edi    movw %gs:(%edi),%ax    add  $1,%ax    movw %ax,%gs:(%edi)    movb $0x20,%al    out %al,$0x20        iret                  loop3:/*无限循环*/      jmp loop3        ret .align 4 //按4字节方式对齐内存地址边界    setup_paging: //先对5页内存清零(1页目录+4页页表)movl $1024*5,%ecxxorl %eax,%eaxxorl %edi,%edi//重复执行rep下面的语句,每次ecx减一,直到ecx为0 //页目录从0x00地址开始cld;rep;stosl //eax内容存到es:edi所指内存位置,且edi增4//STOSL指令相当于将EAX中的值保存到ES:EDI指向的地址中,若设置了EFLAGS中的方向位置位(即在STOSL指令前使用STD指令)则EDI自减4,否则(使用CLD指令)EDI自增4。//设置页目录movl $pg0+7,_pg_dir//7表示该页存在、用户可读写movl $pg1+7,_pg_dir+4movl $pg2+7,_pg_dir+8movl $pg3+7,_pg_dir+12//设置页表,共有4个页表,每个页表1024movl $pg3+4092,%edimovl $0xfff007,%eax//16Mb - 4096 + 7 = 0xfff007//cld,清方向标志,即(DF)=0,地址从低到高  //std,置方向标志1,DF=1,地址从高到低std//std(set direction)置方向标志1:stoslsubl $0x1000,%eaxjge 1bxorl %eax,%eaxmovl %eax,%cr3movl %cr0,%eaxorl$0x80000000,%eaxmovl %eax,%cr0//jmp Page_testret/**/.align  4 .word 0IdtPtr:        .word (END_IDT-LABEL_IDT)-1 # so does gdt         .long LABEL_IDT     # This will be rewrite by code.     .align  4 .word 0GdtPtr:      .word (GDT_END-GDT_START)-1 # so does gdt       .long GDT_START     # This will be rewrite by code.    .align  8 LABEL_IDT:   .rep 32Gate(0x08,(ignore_int - start),0,(DA_386IGate+DA_PL0)).endrGate(0x08,(ClockHandler - start),0,(DA_386IGate+DA_PL0)).rep 222Gate(0x08,(ignore_int - start),0,(DA_386IGate+DA_PL0)).endrEND_IDT: GDT_START:    Descriptor_DUMMY:Descriptor(0x0,0x0,0x0)  Descriptor_CODE32 :Descriptor(0x0,0xffffffff,DA_C+DA_32)  Descriptor_VIDEO:Descriptor(0xb8000,0x0ffff,DA_DRW) Descriptor_SYSTM :Descriptor(0x00000,0xffffffff,DA_C+DA_32) Descriptor_SYSTM2 :Descriptor(0x00000,0xffffffff,DA_DRW) GDT_END:  


Makefile代码如下:

AS    =asLD    =ldLDFLAGS   = --oformat binary -N -e start -Ttext 0x0Image:bootsect setup systemcat bootsect setup system >Imagebootsect:bootsect.s$(AS) -o bootsect.o -a bootsect.s$(LD) $(LDFLAGS) -o bootsect bootsect.osetup:setup.s$(AS) -o setup.o -a setup.s$(LD) $(LDFLAGS) -o setup setup.ohead.o:head.s$(AS) -o head.o -a head.smain.o: main.cgcc -c -o main.o main.csystem:head.o main.o$(LD) $(LDFLAGS) -o system head.o main.oclean:rm -f  Image setup bootsect system *.o *.s


 

原创粉丝点击