您的位置:首页 > 其它

保护模式到实模式

2016-09-03 11:13 274 查看
弄了几天了,终于弄好了,呵呵,也得到了不少东西。从保护模式到是模式的转换一定要注意的有(转):

 

1、程序开始时在实模式下要有自己的堆栈段,进入保护模式前先暂存ss及sp的值至某内存处,以便从保护模式返回实模式后恢复到原先的堆栈。 

2、返回实模式前需把各段寄存器设置为规范段,包括SS也要设置 

3、返回实模式前必须在16位段返回,不能在32位段里返回实模式。 

4、返回实模式前的段必须定义在GDT中。 

5、在32位段下操作有关寄存器时,注意32位寄存器和16位寄存器的差别,类似于SP寄存器,应用使用ESP寄存器。 

6、在使用定义在LDT中的段时,一定要使用LLDT先加载LDT缓冲寄存器(LDTR)。 

7、用于返回实模式的代码段的段界限必须为0FFFFH,不能为实际长度,否则要么在跳转到实模式的时候出错要么在跳转到实模式后执行int 21H出错。(个人推测原因如下:80286开始为每个段寄存器增加了段描述符高速缓冲寄存器,而这些缓冲寄存器对于程序员是不可见的,且在实模式下是不能修改的,要想改变这些高速缓冲寄存器的值必须通过在保护模式下修改相应的段寄存器的选择子来实现,这也是为什么在返回实模式之前必须把DS、ES、FS、GS、SS设置为规范段的原因。但是CS是一个特殊的段,不能通过常规方式修改,只能通过段间跳转修改,而一旦跳到实模式后又不能修改了,所以就要求在返回实模式的段的段描述符必须符合实模式下的要求。实模式下的段长度是0FFFFH,也就是64K,如果用于返回实模式的段的段界限不是0FFFFH,会导致返回实模式后实模式下的CS段的高速缓冲寄存器的段长度还是保护模式时的段界限值,这是不正确的,所以要求用于返回实模式的段的段界限必须是0FFFFH。) 

ps:所谓规范段是指实模式下的标准段属性,一般段界限为0FFFFH,段属性为可读写。 

 

自己的认识是从保护模式到实模式转换的过程为从某个保护模式下的函数中跳到16位下,在16位模式下要做的工作是设置各个段寄存器和设置CR0,(此处需要特别特别注意的是段寄存器中的选择子必须是要定义在GDT中的,而且其段界限必须为0xffff,否则仍然可以跳回实模式,但是会有段界限异常),然后再跳到最开始引导的段中关A20和开中断(sti),之所以还要跳回最开始的引导段,是因为需要用jmp设置cs。

 

1.f和g段寄存器可以不设为Normal

2.Normal段界限必须为0xffff  不然仍可以返回,但会有段界限异常

3.code16所在的段界限可以不为0xffff

4.某个函数->16位关CR0&&设置段寄存器->跳到最开始引导的段关A20、开中断(之所以跳到开始引导的段是因为

需要用jmp语句设置cs为段0)

5.代码中将16位的代码放在了文件的最后,原来是放在DISPLAY前的,是因为碰到了如下奇怪的情况在生成bin文件后,jmp指令和下面的mov ax,VIDEOSELECTOR指令混淆了,CPU执行时仍然是按照32位的指令执行的,所以将jmp解释为32位的,而编译的文件中却是16位的,因此会误将mov的机器指令当做jmp指令中的操作数。

6.如5中所说,在源文件中将代码声明为16位([BITS 16])后,生成的机器码为16位的,而在CPU执行时却仍按32位指令执行,暂时还不知道是怎么回事,有时间再看看。

代码中需要注意的是在引导段中的这一句

mov [RETURN_JMP+3],ax

这一句的作用是将jmp指令中的段字节设为0。在16位模式下,段间jmp指令的格式为

            offset           segment

ea   byte1 byte2    byte3 byte4

在32位模式下段间jmp指令的格式为

 

                      offset                    segment

ea   byte1 byte2 byte3 byte4   byte5 byte6

[cpp]
view plain
copy

org 0x7c00  
    jmp MAIN  
;数据结构  
GDT:  
    DEFAULT_SEG:  
    dw 0,0,0,0  
    CODE32_SEG:  
    dw 0x07ff  
    dw 0x0000  
    dw 0x9a00  
    dw 0x00cf  
    DATA_SEG:  
    dw 0x07ff  
    dw 0x0000  
    dw 0x9200  
    dw 0x00cf  
    TEST_DATA_SEG:  
    dw 0x07ff  
    dw 0x0000  
    dw 0x9250;三字节的基址  
    dw 0x00cf  
    VIDEO_SEG:;0x20  
    dw 0x07ff  
    dw 0x8000  
    dw 0x920B  
    dw 0x00cf  
    REAL_SEG:;0x28  
    dw 0xffff  
    dw 0x0000  
    dw 0x9200  
    dw 0x00cf  
    CODE16_SEG:  
    dw 0x07ff  
    dw 0x0000  
    dw 0x9a00  
    dw 0x00cf  
    CALL_GATE_SEG:  
    dw 0x0000  
    dw CODE_SELECTOR  
    dw 0x8c00  
    dw 0x0000  
GDT_END:  
GDTR:  
    dw GDT_END-GDT-1  
    dw GDT,0  
DEFAULT_SELECTOR equ DEFAULT_SEG-GDT  
CODE_SELECTOR equ CODE32_SEG-GDT  
DATA_SELECTOR equ DATA_SEG-GDT  
TEST_DATA_SELECTOR equ TEST_DATA_SEG-GDT  
VIDEO_SELECTOR equ VIDEO_SEG-GDT  
REAL_SEG_SELECTOR equ REAL_SEG-GDT  
CODE16_SELECTOR equ CODE16_SEG-GDT  
CALL_GATE equ CALL_GATE_SEG-GDT  
[BITS 16]  
MAIN:  
mov ax,cs  
mov ds,ax  
mov gs,ax  
mov [RETURN_JMP+3],ax  
;init code32  
xor eax,eax  
mov ax,cs  
shl eax,4  
add eax,DISPLAY  
mov word [CODE32_SEG+2],ax  
shr eax,16  
mov byte [CODE32_SEG+4],al  
mov byte [CODE32_SEG+7],ah  
;init code16  
xor eax,eax  
mov ax,cs  
shl eax,4  
add eax,BACK_TO_REAL  
mov word [CODE16_SEG+2],ax  
shr eax,16  
mov byte [CODE16_SEG+4],al  
mov byte [CODE16_SEG+7],ah  
lgdt [GDTR]  
cli  
;a20  
in al,0x92  
or al,00000010b  
out 0x92,al  
;cr0  
mov eax,cr0  
or eax,00000001b  
mov cr0,eax  
call CALL_GATE:0  
REAL_ENTRY:;00007cb8  
mov ax,cs  
mov ds,ax  
mov es,ax  
mov ss,ax  
;关A20  
;in al,0x92  
;and al,11111101b  
;out 0x92,al  
;开中断  
sti  
jmp $  
[BITS 32]  
DISPLAY:  
mov ax,VIDEO_SELECTOR  
mov gs,ax  
mov ah,0x0c  
mov al,'P'  
mov edi,(80*0+0)*2  
mov [gs:edi],ax  
;jmp $  
jmp CODE16_SELECTOR:0  
;放在CODE16_SEG中  
;还在CODE16中,CS=0x0030  
;ALIGN 32  
[BITS 16];指令是16位的,但CPU在32位模式下,取指时按32位取  
BACK_TO_REAL:  
mov ax,REAL_SEG_SELECTOR;mov eax,0xd88e0028  
mov ds,ax  
mov ds,ax  
mov es,ax  
;mov fs,ax  
mov gs,ax  
mov ss,ax  
mov eax,cr0  
and al,11111110b;!!!!!!!!! 段界限异常  
mov cr0,eax  
RETURN_JMP:  
jmp 0:REAL_ENTRY;jmp far b866:00007cb8  
times 510-($-$) db 0  
dw 0xaa55  

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: