|
20鱼币
本帖最后由 张国祥 于 2013-1-7 21:13 编辑
- %include "pm.inc"
- org 0100h
- jmp start
- [SECTION .gdt]
- GDT_DESC: Descriptor 0,0,0
- NORMAL_DESC: Descriptor 0,0ffffh,DA_DRW
- RETURN_16_DESC: Descriptor 0,0ffffh,DA_C
- MAIN_DESC: Descriptor 0,mainlen-1,DA_C+DA_32
- DISP_DESC: Descriptor 0b8000h,0ffffh,DA_DRW
- STK_DESC: Descriptor 0,TopOfStk+1,DA_DRW+DA_32
- DATA_DESC: Descriptor 0,datalen-1,DA_DRW
- LDT_DESC: Descriptor 0,ldtlen-1,DA_LDT
- TEST_DESC: Descriptor 500000h,0ffffh,DA_DRW
- ;test和ldt两个描述符是不是不能共存
- gdtlim equ $-$-1
- ;注意长度和界限的区别
- dd 0
- SEL_NORMAL EQU NORMAL_DESC-GDT_DESC
- SEL_RETURN_16 EQU RETURN_16_DESC-GDT_DESC
- SEL_MAIN EQU MAIN_DESC-GDT_DESC
- SEL_DISP EQU DISP_DESC-GDT_DESC
- SEL_STK EQU STK_DESC-GDT_DESC
- SEL_DATA EQU DATA_DESC-GDT_DESC
- SEL_LDT EQU LDT_DESC-GDT_DESC
- SEL_TEST EQU TEST_DESC-GDT_DESC
- [SECTION .ldt]
- ldt:
- L_CODE_DESC: Descriptor 0,lcodelen-1,DA_C+DA_32
- ldtlen equ $-$
- SEL_L_CODE EQU L_CODE_DESC-ldt+SA_TIL
- [SECTION .lcode]
- [BITS 32]
- lcode:
- mov edi,160*0+2*40
- mov ah,0ah
- mov al,'L'
- mov [gs:edi],ax
- jmp SEL_RETURN_16:0
-
- lcodelen equ $-$
- [SECTION .data1]
- data:
- RMSPValue dw 0
- pmmsg: db 'Protect Mode!',0
- pmmsgost equ pmmsg-$
- datalen equ $-$
- [SECTION .stk]
- stk:
- times 512 db 0
- TopOfStk equ $-$-2
- [SECTION .start]
- [BITS 16]
- start:
- mov ax,cs
- mov ds,ax
- mov es,ax
- mov ss,ax
- mov sp,0100h
-
- mov [GoToReal+3],ax
- mov [RMSPValue],sp
-
- ;初始化
- movzx eax,ax
- shl eax,4
- add eax,main
- mov word [MAIN_DESC+2],ax
- shr eax,16
- mov byte [MAIN_DESC+4],al
- mov byte [MAIN_DESC+7],ah
-
- mov ax,ds
- movzx eax,ax
- shl eax,4
- add eax,data
- mov word [DATA_DESC+2],ax
- shr eax,16
- mov byte [DATA_DESC+4],al
- mov byte [DATA_DESC+7],ah
-
- mov ax,ds
- movzx eax,ax
- shl eax,4
- add eax,return16
- mov word [RETURN_16_DESC+2],ax
- shr eax,16
- mov byte [RETURN_16_DESC+4],al
- mov byte [RETURN_16_DESC+7],ah
-
- mov ax,ds
- movzx eax,ax
- shl eax,4
- add eax,ldt
- mov word [LDT_DESC+2],ax
- shr eax,16
- mov byte [LDT_DESC+4],al
- mov byte [LDT_DESC+7],ah
-
- mov ax,cs
- movzx eax,ax
- shl eax,4
- add eax,lcode
- mov word [L_CODE_DESC+2],ax
- shr eax,16
- mov byte [L_CODE_DESC+4],al
- mov byte [L_CODE_DESC+7],ah
-
- mov ax,ss
- movzx eax,ax
- shl eax,4
- add eax,stk
- mov word [STK_DESC+2],ax
- shr eax,16
- mov byte [STK_DESC+4],al
- mov byte [STK_DESC+7],ah
-
- mov ax,ds
- movzx eax,ax
- shl eax,4
- add eax,GDT_DESC
- mov dword [gdtlim+2],eax
- lgdt [gdtlim]
-
- cli
-
- in al,92h
- or al,00000010b
- out 92h,al
-
- mov eax,cr0
- or al,1
- mov cr0,eax
-
- jmp dword SEL_MAIN:0
-
- real:
- mov ax,cs
- mov ds,ax
- mov es,ax
- mov ss,ax
- mov sp,[RMSPValue]
-
- in al, 92h
- and al, 11111101b
- out 92h, al
- sti
- mov ax, 4c00h
- int 21h
-
- [SECTION .s16]
- [BITS 16]
- return16:
- mov ax,SEL_NORMAL
- mov ds,ax
- mov es,ax
- mov ss,ax
- mov fs,ax
- mov gs,ax
-
- mov eax, cr0
- and al, 11111110b
- mov cr0, eax
-
- GoToReal:
- jmp 0:real
-
- [SECTION .main]
- [BITS 32]
- main:
- mov ax,SEL_DISP
- mov gs,ax
- mov ax,SEL_DATA
- mov ds,ax
-
- mov ax,SEL_TEST
- mov es,ax
-
- mov ax,SEL_STK
- mov ss,ax
- mov sp,TopOfStk
- mov ah,0ah
- mov esi,pmmsgost
- mov edi,0
- cld
- .1:
- lodsb
- cmp al,0
- je .2
- mov [gs:edi],ax
- add edi,2
- jmp .1
-
- .2:
- jmp SEL_RETURN_16:0
- mov ax,SEL_LDT
- lldt ax
- call SEL_L_CODE:0
- mainlen equ $-$
复制代码 很诡异,是不是LDT描述符和TEST描述符不能共存,一运行就崩溃
|
最佳答案
查看完整内容
问题的根本原因是这一句:
把这里的“equ”改成“dw”就Okay了。
下面来具体分析一下,特别是奇偶描述符个数导致有时成功/失败的原因。
首先,lgdt指令的操作数需要一个指向6字节内存区域的指针。在你的程序中,是这样做的:
遗憾的是,gdtlim是一个常数 $-$$-1,所以,DS:[gdtlim]不会在你指定的位置(GDT表的后面)。
那么,它在哪里呢?
注意,这是一个.COM文件,段寄存器DS指向程序段前缀PSP。因此,gdtlim如果 ...
|