各位386高手指点迷经啊!!!!!!!!
下面程序运行时dos窗口一闪而过,我找不出错误,请高手指点 ccdmsfjg struc
djx dw 0
ddjz dw 0
zdjz db 0
dsx dw 0
gdjz db 0
ccdmsfjg ends
mmsfjg struc
dpy dw 0
xzz dw 0
jsz db 0
dsx db 0
gpy dw 0
mmsfjg ends
vmsfjg struc
djx dw 0
djz dd 0
vmsfjg ends
jump32 macro xzz,py
db 0eah
dw py
dw 0
dw xzz
endm
jump16 macro xzz,py
db 0eah
dw py
dw xzz
endm
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386p
gdtseg segment use16 ;全局描述符表
gdt label byte
dummy ccdmsfjg <>
gfd ccdmsfjg <0ffffh,0,0,92h,0>
gfd_sel=gfd-gdt
bdata ccdmsfjg <26,0,01h,92h,0>
bdata_sel=bdata-gdt
effgdt label byte
vide ccdmsfjg <26*2,0b800h,0,92h,0>
vide_sel=vide-gdt
data ccdmsfjg <50,dataseg,,92h,>
data_sel=data-gdt
bcode ccdmsfjg <bcodeseglen-bcodesegst-1,bcodeseg,0,98h,>
bcode_sel=bcode-gdt
gdtnum=($-effgdt)/size ccdmsfjg
gdtlen=$-gdt
vgdtr vmsfjg <gdtlen-1,>
gdtseg ends
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
bcodeseg segment use16 ;演示代码段保护模式
assume cs:bcodeseg
bcodesegst:
mov ax,bdata_sel
mov es,ax
xor di,di
mov cx,26
mov al,41h
cld
lop1:stosb ; 把A---Z字符存入10000:0c处的26个字节中,选择子是bdata_sel
inc al
cmp al,'Z'
ja next0
loop lop1
next0:
mov ax,bdata_sel ;把选择子为bdata_sel处的26个字节值转入
;选择子为data_sel(dataseg)
mov ds,ax ;的sj处
or si,si
mov ax,data_sel
mov es,ax
mov di,es:offset sj
mov cx,26
rep movsb
mov ax,data_sel ;显示
mov ds,ax
mov si,0
mov ax,vide_sel
mov es,ax
mov di,0
mov cx,26
mov ah,7
lop2: lodsb
stosw
loop lop2
mov ax,gfd_sel ; 加载规范段
mov ds,ax
mov es,ax
mov ss,ax
mov eax,cr0 ;退出保护模式
and eax,0fffffffeh
mov cr0,eax
jmp far ptr read
bcodeseglen:nop
bcodeseg ends
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
dataseg segment use16 ;实模式数据段
sj db 26 dup(0)
rspz dw 0
rssz dw 0
rgdtr vmsfjg <>
dataseg ends
codeseg segment use16 ;实模式代码段
assume cs:codeseg,ds:dataseg
start:
mov ax,dataseg ;保存实模式各值
mov ds,ax
mov rspz,sp
mov rssz,ss
sgdt rgdtr
mov ax,gdtseg ;初始化gdtr
mov ds,ax
mov bx,16
mul bx
add ax,offset gdt
adc dx,0
mov ds:word ptr vgdtr.djz,ax
mov ds:word ptr vgdtr.djz+2,dx
lgdt ds:vgdtr
call cshgdt ;初始化gdt
cli
call dka20 ;打开地址a20
mov eax,cr0 ;进入保护模式
or eax,1
mov cr0,eax
jump16 <bcode_sel>,<offset bcodesegst>
read: call gba20 ;关闭a20
sti
mov ax,dataseg ;恢复实模式下的各值
mov ds,ax
lss sp,dword ptr rspz
lgdt rgdtr
mov ax,4c00h
int 21h
cshgdt proc ;初始化gdt子程序
push eax
push edx
push ds
push esi
mov ax,gdtseg
mov ds,ax
mov si,offset effgdt
mov cx,gdtnum
lop0: mov ax,[si].ddjz
movzx eax,ax
shl eax,4
shld edx,eax,16
mov word ptr [si].ddjz,ax
mov byte ptr [si].zdjz,dl
mov byte ptr [si].gdjz,dh
add si,size ccdmsfjg
loop lop0
pop esi
pop ds
pop edx
pop eax
ret
cshgdt endp
dka20 proc ;打开和关闭a20地址子程序
push ax
in al,92h
or al,2
out 92h,al
pop ax
ret
dka20 endp
gba20 proc
push ax
in al,92h
and al,0fdh
out 92h,al
pop ax
ret
gba20 endp
codeseg ends
end start
[[italic] 本帖最后由 longxies 于 2008-1-15 20:49 编辑 [/italic]]