[color=008080][color=0000FF][color=FF0000];从实模式转换到保护模式 ,然后在屏幕上打印一个"Hello,welcome to my S_OS"

; 宏 ------------------------------------------------------------------------------------------------------
;
; 描述符
; usage: Descriptor Base, Limit, Attr
;        Base:  dd
;        Limit: dd (low 20 bits available)
;        Attr:  dw (lower 4 bits of higher byte are always 0)
;%macro Descriptor 3
;    dw    %2 & 0FFFFh                ; 段界限 1                (2 字节)
;    dw    %1 & 0FFFFh                ; 段基址 1                (2 字节)
;    db    (%1 >> 16) & 0FFh            ; 段基址 2                (1 字节)
;    dw    ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh)    ; 属性 1 + 段界限 2 + 属性 2        (2 字节)
;    db    (%1 >> 24) & 0FFh            ; 段基址 3                (1 字节)
;%endmacro ; 共 8 字节
;
;
%include "pm.inc"

    org 0100h
    jmp start

;GDT
[SECTION .gdt]
    LABEL_GDT:             Descriptor     0,              0,                         0 
    LABEL_CODE32:          Descriptor     0,              SEG_CODE32_LEN-1,         4098h   
    LABEL_VIDEO32:         Descriptor     0B8000h,         0ffffh,                    92h
    LABEL_DATA32:           Descriptor     0,                SEG_DATA32_LEN-1,            92h    


;GDT_48
gdt_len EQU $-LABEL_GDT
gdt_48     dw gdt_len-1
        dd 0
    
;GDT选择子
    code32   EQU LABEL_CODE32-LABEL_GDT
    video32  EQU LABEL_VIDEO32 -LABEL_GDT
    data32      EQU LABEL_DATA32 - LABEL_GDT

[SECTION .data1]
ALIGN 32
[BITS    32]
LABEL_SEG_DATA32:
    
BootMessage: db "hello",0
offsetBootMessage  db BootMessage -$$
SEG_DATA32_LEN EQU $- LABEL_SEG_DATA32
[SECTION .s16]
[BITS 16]
start:
    mov ax , cs
    mov ds , ax
    mov es , ax
    mov ss , ax
    mov sp , 0100h

;初始化代码段描述符
    xor eax , eax
    mov ax  , cs
    shl eax , 4
    add eax , LABEL_SEG_CODE32
    mov word [LABEL_CODE32+2] , ax
    shr eax , 16
    mov byte [LABEL_CODE32+4] , al
    mov byte [LABEL_CODE32+7] , ah
;初始化数据段描述符
    xor eax , eax
    mov ax  , ds
    shl eax , 4
    add eax , LABEL_SEG_DATA32
    mov word [LABEL_DATA32+2] , ax
    shr eax , 16
    mov byte [LABEL_DATA32+4] , al
    mov byte [LABEL_DATA32+7] , ah

;加载GDTR
    xor eax , eax
    mov ax  , ds
    shl eax , 4
    add eax , LABEL_GDT
    mov dword [gdt_48+2] , eax
    
    lgdt [gdt_48]

;关中断
    cli 
    
;开A20地址线

    in    al, 92h
    or    al, 00000010b
    out    92h, al
;置cr0的pe位
    mov eax , cr0
    or  eax , 1
    mov cr0 ,eax

;开中断
    ;sti
    
;jmp 进入保护模式

    jmp dword code32:0 
[SECTION .s32]
[BITS    32]
LABEL_SEG_CODE32:

    mov ax , data32
    mov ds , ax
    
    mov ax , video32
    mov gs , ax
    
    mov ah  , 0ch
    xor esi , esi
    xor edi , edi
    mov esi , offsetBootMessage
    mov edi , (80*10+0)*2

    cld
    
sec:
    lodsb 

    test al ,al
    jz  fir
    mov [gs:edi] , ax
    add edi , 2
    jmp sec 
    
fir:
    jmp $

SEG_CODE32_LEN EQU $-LABEL_SEG_CODE32[/color][/color][/color]


第二个程序:
[color=008000]; ==========================================
; pmtest2.asm
; 编译方法:nasm pmtest2.asm -o pmtest2.com
; ==========================================

%include    "pm.inc"    ; 常量, 宏, 以及一些说明

org    0100h
    jmp    LABEL_BEGIN

[SECTION .gdt]
; GDT
;                                         段基址,       段界限     , 属性
LABEL_GDT:        Descriptor           0,                 0,                 0             ; 空描述符
LABEL_DESC_CODE32:    Descriptor       0,                 SegCode32Len - 1,  DA_C + DA_32    ; 非一致代码段, 32
LABEL_DESC_DATA:    Descriptor       0,                  DataLen - 1,       DA_DRW        ; Data
LABEL_DESC_VIDEO:    Descriptor       0B8000h,           0ffffh,            DA_DRW        ; 显存首地址
; GDT 结束

GdtLen        equ    $ - LABEL_GDT    ; GDT长度
GdtPtr        dw    GdtLen - 1    ; GDT界限
        dd    0        ; GDT基地址

; GDT 选择子

SelectorCode32        equ    LABEL_DESC_CODE32    - LABEL_GDT
SelectorData        equ    LABEL_DESC_DATA        - LABEL_GDT
SelectorVideo        equ    LABEL_DESC_VIDEO    - LABEL_GDT
; END of [SECTION .gdt]

[SECTION .data1]     ; 数据段
ALIGN    32
[BITS    32]
LABEL_DATA:
;SPValueInRealMode    dw    0
; 字符串
PMMessage:        db    "In Protect Mode now. ^-^", 0    ; 进入保护模式后显示此字符串
OffsetPMMessage        equ    PMMessage - $$

DataLen            equ    $ - LABEL_DATA
; END of [SECTION .data1]


[SECTION .s16]
[BITS    16]
LABEL_BEGIN:
    mov    ax, cs
    mov    ds, ax
    mov    es, ax
    mov    ss, ax
    mov    sp, 0100h


    
    ; 初始化 32 位代码段描述符
    xor    eax, eax
    mov    ax, cs
    shl    eax, 4
    add    eax, LABEL_SEG_CODE32
    mov    word [LABEL_DESC_CODE32 + 2], ax
    shr    eax, 16
    mov    byte [LABEL_DESC_CODE32 + 4], al
    mov    byte [LABEL_DESC_CODE32 + 7], ah

    ; 初始化数据段描述符
    xor    eax, eax
    mov    ax, ds
    shl    eax, 4
    add    eax, LABEL_DATA
    mov    word [LABEL_DESC_DATA + 2], ax
    shr    eax, 16
    mov    byte [LABEL_DESC_DATA + 4], al
    mov    byte [LABEL_DESC_DATA + 7], ah



    ; 为加载 GDTR 作准备
    xor    eax, eax
    mov    ax, ds
    shl    eax, 4
    add    eax, LABEL_GDT        ; eax <- gdt 基地址
    mov    dword [GdtPtr + 2], eax    ; [GdtPtr + 2] <- gdt 基地址

    ; 加载 GDTR
    lgdt    [GdtPtr]

    ; 关中断
    cli

    ; 打开地址线A20
    in    al, 92h
    or    al, 00000010b
    out    92h, al

    ; 准备切换到保护模式
    mov    eax, cr0
    or    eax, 1
    mov    cr0, eax

    ; 真正进入保护模式
    jmp    dword SelectorCode32:0    ; 执行这一句会把 SelectorCode32 装入 cs, 并跳转到 Code32Selector:0  处

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;




[SECTION .s32]; 32 位代码段. 由实模式跳入.
[BITS    32]

LABEL_SEG_CODE32:
    mov    ax, SelectorData
    mov    ds, ax            ; 数据段选择子
    
    mov    ax, SelectorVideo
    mov    gs, ax            ; 视频段选择子

    ; 下面显示一个字符串
    mov    ah, 0Ch            ; 0000: 黑底    1100: 红字
    xor    esi, esi
    xor    edi, edi
    mov    esi, OffsetPMMessage    ; 源数据偏移
    mov    edi, (80 * 10 + 0) * 2    ; 目的数据偏移。屏幕第 10 行, 第 0 列。
    cld                            ;清方向位
.1:
    lodsb                        ;[si]->ax
    test    al, al
    jz    .2
    mov    [gs:edi], ax
    add    edi, 2
    jmp    .1
.2:    ; 显示完毕
    jmp $
SegCode32Len  equ $ - LABEL_SEG_CODE32    
; ------------------------------------------------------------------------[/color]

这两个程序 ,两个程序都用nasmw.exe编译通过,但是第一个程序在纯dos下运行,会出现一个 "处理器运到一个随机的错误", 第二个程序正常运行,在屏幕上出现 “In Protect Mode now. ^-^”.大家帮我找找两个程序的不同啊?