谁能解释这段386为何出错吗?马上给分

哪位高手能解释这段386为何出错吗?马上给分!
 
org 0100h
jmp start8086
;-----------------------------------------------------
[SECTION .gdt]

%macro Descriptor 3
dw %2 & 0FFFFh  
dw %1 & 0FFFFh  
db (%1 >> 16) & 0FFh  
dw ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh) 
db (%1 >> 24) & 0FFh 
%endmacro 

gdt_desc: Descriptor 0,0,0
code_desc: Descriptor 0,0,98h+4000h
data_desc: Descriptor 0b800h,0ffffh,92h

gdt_len equ $-gdt_desc
gdt_ptr dw gdt_len - 1
dd 0

sel_code equ code_desc - gdt_desc
sel_data equ data_desc - gdt_desc
;-----------------------------------------------------
[SECTION .s16]
[BITS 16]
start8086:
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov sp,100h

;*** initialize code descriptor ****
xor eax, eax
mov ax, cs
shl eax, 4
add eax, start386
mov word [code_desc + 2], ax
shr eax, 16
mov byte [code_desc + 4], al
mov byte [code_desc + 7], ah
 
;*** load GDTR register ****
xor eax, eax
mov ax, ds
shl eax, 4
add eax, gdt_desc 
mov dword [gdt_ptr + 2], eax 
lgdt [ gdt_ptr ]
 

lgdt [gdt_ptr] 
cli 
in al, 92h
or al, 00000010b
out 92h, al 
mov eax, cr0
or eax, 1
mov cr0, eax 
jmp dword sel_code:0 
 
 
[SECTION .s32]
[BITS 32]
start386:

mov ax,sel_data
mov es,ax
mov al,'X'
mov [es:180*10+20],al
 
jmp $





------解决方案--------------------
给你改了一下,应该没有什么问题啦:
Assembly code


%macro Descriptor 3
     dw %2 & 0FFFFh   
    dw %1 & 0FFFFh   
    db (%1 >> 16) & 0FFh   
    dw ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh)  
    db (%1 >> 24) & 0FFh  
%endmacro  

    org 07C00h
    jmp start8086


gdt_desc:        Descriptor        0,                    0,                        0
code_desc:        Descriptor        0,                    SegLen -1 ,        98h+4000h ; 修改段界限
data_desc:        Descriptor        0B8000h,            0FFFFh,                    92h 


gdt_len            equ        $ - gdt_desc


gdt_ptr                dw        gdt_len - 1        
                    dd        0                    

sel_code        equ        code_desc - gdt_desc
sel_data        equ        data_desc     - gdt_desc


;[SECTION .s16]
[BITS 16]        
start8086:

    mov ax,cs
     mov ds,ax
     mov es,ax
     mov ss,ax
     mov sp,100h
     
;*** initialize code descriptor ****
    xor    eax, eax
    mov ax, cs
    shl    eax, 4
    add eax, start386                    
    mov word [code_desc + 2], ax        
    shr eax, 16                            
    mov byte [code_desc + 4], al        
    mov byte [code_desc + 7], ah        
    
    ;*** load GDTR register ****
    xor    eax, eax
    mov ax, ds
    shl eax, 4
    add eax, gdt_desc
    mov dword [gdt_ptr + 2 ], eax
    lgdt [gdt_ptr]
    
    cli 
    in al, 92h
    or al, 00000010b
    out 92h, al
    mov eax, cr0
    or eax, 1
    mov cr0, eax
    jmp dword sel_code:0
    
    
;[SECTION .s32]
[BITS 32]        
start386:
    
    mov ax, sel_data
    mov es,ax
    ; 设置显示的属性
    mov ah, 0Ch
    mov al,'X'
    mov [es:((80*0+0)*2)],ax ;个人感觉这样写行列容易看出

    jmp $
SegLen    equ        $ - start386 ; 添加这一句
; 补齐剩余的字节和扇区结束标识
times 510 - ($ - $$) db 0
    dw 0xaa55