搬运system到0地址

do_move用于将system移动到0地址,然后将Descriptor_SYSTM的基地址改为0,为了简单我把上面设置8259A的内容去掉了。

测试代码如下:

#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)    
    
/*    
*InitDescrptor(Descriptor,SegBase)初始化描述符函数    
*Descriptor:要初始化的描述符    
*SegBase:段基址    
*/    
#define InitDescrptor(Descriptor,SegBase)\
xor     %eax,%eax; \
mov     %cs,%ax  ; \
shl     $4,%eax  ; \
addl    $(SegBase), %eax ;\
movw    %ax, (Descriptor + 2);\
shr     $16, %eax;\
movb    %al, (Descriptor + 4);\
movb    %ah, (Descriptor + 7)   
   
DA_32=0x4000          //32位模式
DA_LIMIT_4K=0x8000          //颗粒度为4096
DA_DRW=0x92            //数据段可读可写
DA_CR=0x9A            //可读可执行
DA_C   = 0x98 
SETUPSEG = 0x9020
SETUPAddr = SETUPSEG<<4
.text  
.globl start/*程序从start处开始运行*/  
.code16  
start:  
 jmp code   
msg:  
 .string "I'm setup!"  
/**-----------------------------------------------------------------  
 * Global Descriptor Table: GDT  
 *-------------------------------*/  
GDT_START:    
Descriptor_DUMMY:Descriptor(0x0,0x0,0x0)  
Descriptor_CODE32 :Descriptor(SETUPAddr,0xffffffff,DA_C+DA_32)  
Descriptor_VIDEO:Descriptor(0xb8000,0x0ffff,DA_DRW) 
Descriptor_SYSTM :Descriptor(0x0,0xffffffff,DA_C+DA_32)  
GDT_END:  
  
GdtPtr:  
    .word (GDT_END-GDT_START)-1 # so does gdt   
    .long GDT_START+SETUPAddr     # This will be rewrite by code.
     
.set    selector_Code32,(Descriptor_CODE32-GDT_START)  
.set    Selector_Video,(Descriptor_VIDEO-GDT_START) 
.set    selector_System,(Descriptor_SYSTM-GDT_START)       

.align  4
code:  
    mov     %cs,%ax     
    mov     %ax,%ds   
    mov     %ax,%es      
    mov     %ax,%ss    
    mov  $0x400,%sp    
    call DispStr/*调用显示字符串函数*/
 
 /*关中断*/  
    cli 
    
    mov $0x0000,%ax
do_move:
		mov %ax,%es
		add $0x1000,%ax
		cmp $0x9000,%ax
		jz end_move
		mov %ax,%ds
		sub %di,%di
		sub %si,%si
		mov $0x8000,%cx
		rep
		movsw
		jmp do_move
end_move:
		mov $SETUPSEG,%ax
		mov %ax,%ds
/*初始全局描述符Descriptor_CODE32*/    
InitDescrptor(Descriptor_CODE32,LABEL_SEG_CODE32);

/*加载gdtr即将全局描述符表gdt的首地址和gdt的界限赋给gdtr寄存器*/         
    lgdt GdtPtr  
  
 
  
/*打开地址线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 $0x18,$(LABEL_SEG_CODE32) 
    ljmp $selector_Code32,$0 
/*此时CS:IP=全局描述符表中第1(0x8>>3)项描述符给出的段基址+LABEL_SEG_CODE32的偏移地址*/  
  
  
LABEL_SEG_CODE32:  
.align  32  
.code32 
nop
nop 
    movw $0x10,%ax  
    movw %ax,%gs  
    movl $((80*11+79)*2),%edi/*第11行,79列*/  
    movb $0x0c,%ah/*高四位表示黑底,低四位表示红字*/  
    movb $'P',%al/*显示的字符*/  
    movw %ax,%gs:(%edi) 
    
    ljmp $0x18,$0               
loop0:/*无限循环*/  
    jmp loop0  
      
DispStr: 
.align  16  
.code16 
    mov $msg   ,%ax  
    mov %ax    ,%bp/*es:bp = 串地址*/  
    mov $10    ,%cx/*cs = 串长度*/  
    mov $0x1301,%ax/*ah=13是功能号表示显示字符串 ,al=01是显示输出方式*/  
    mov $0x000c,%bx/*bh=0是0页,bl=0ch高亮 黑底红字*/  
    mov $0x0     ,%dl/*0行0列*/  
mov $0x1     ,%dh
      
    int $0x10  
    ret  
      
.org 0x7fe, 0x90   //让setup占4个扇区,共512*4字节
.word 0xaa55    


 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值