#define Descriptor(base,lim,type)\ .word lim&0xffff;\ .word base&0xffff;\ .byte (base>>16)&0xff;\ .word ((lim>>8)&0xf00)|(type&0x0f0ff);\ .byte ((base>>24)&0xff) DA_C = 0x98 DA_32 = 0x4000 DA_DRW = 0x92 .text .globl start .code16 start: jmpl $0x0, $code GDT_START: Descriptor_DUMMY:Descriptor(0x0,0x0,0x0) /* 第0项里面全是0,不会用到 */ Descript_CODE32 :Descriptor(0x0,0xffffffff,DA_C+DA_32) /* 32位代码段的段基址,段界限,访问类型 */ Descriptor_VIDEO:Descriptor(0xb8000,0x0ffff,DA_DRW) /* 显存的段基址,段界限,访问类型 */ GDT_END: GdtPtr: .word (GDT_END-GDT_START)-1 # so does gdt .long GDT_START # This will be rewrite by code. msg: .string "Hello world!" code: mov %cs,%ax mov %ax,%ds mov %ax,%es mov %ax,%ss mov $0x8000,%sp /*显示HelloWorld字符串*/ mov $msg ,%ax mov %ax ,%bp mov $12 ,%cx mov $0x1301,%ax mov $0x000c,%bx mov $0 ,%dl int $0x10 /*加载gdtr即将全局描述符表gdt的首地址和gdt的界限赋给gdtr寄存器*/ lgdt GdtPtr /*关中断*/ cli /*打开地址线A20*/ inb $0x92,%al or $0x02,%al outb %al,$0x92 /*设置cr0寄存器,切换到保护模式*/ movl %cr0,%eax or $1,%eax movl %eax,%cr0 /*真正进入保护模式,执行此命令后CS=0x8,IP=LABEL_SEG_CODE32的偏移地址*/ ljmp $0x8,$(LABEL_SEG_CODE32) /*此时CS:IP=全局描述符表中第1(0x8>>3)项描述符给出的段基址+LABEL_SEG_CODE32的偏移地址*/ LABEL_SEG_CODE32: .align 32 .code32 movw $0x10,%ax movw %ax,%gs movl $((80*11+79)*2),%edi/*第11行,79列*/ movb $0x0c,%ah/*高四位表示黑底,低四位表示红字*/ movb $'P',%al/*显示的字符*/ movw %ax,%gs:(%edi) loop2: jmp loop2 .org 0x1fe, 0x90 .word 0xaa55