-->在纯DOS下访问1M以上內存的汇编代码问题。

SoRoMan 2003-10-21 11:12:58
那天在FAQ上看到在純DOS下訪問1M以上內存的匯編代碼,理论上应该是可行的,想拿来试试,运行后无结果输出.(懷疑是himem惹的禍,去掉以後還是一樣)我在DOS下用debug調試,發現單步到 mov eax,cr0處機子就重啟了,請教大家一下為什麼。(我用的是masm6.00,tasm5.0編譯我沒通過)

.386p
gdt segment use16
gdt_begin label byte
null_desc dq 0
scode dd 0000ffffh
dd 00009a00h
sdata dd 0000ffffh
dd 00cf9200h
gdt_end label byte
gdtr dw 3*8-1
dd 0
gdt ends

cseg segment use16
assume cs:cseg,ds:gdt
start:
mov ax,gdt
mov ds,ax
movzx eax,ax
shl eax,4
mov ebx,offset gdtr
mov [ebx]+2,eax
seta20:
in al,64h
test al,2
jnz seta20
mov al,0d1h
out 64h,al
seta201:
in al,64h
test al,2
jnz seta201
mov al,0dfh
out 60h,al

cli
lgdt fword ptr gdtr ;装载GDT
mov eax,cr0
or eax,1
mov cr0,eax ;进入保护模式
jmp protected_mode ;刷新指令队列
protected_mode:
mov ax,10h
mov ds,ax
mov esi,0110000h ;开始探测内存
begin_test:
mov dl,55h
xchg [esi],dl
xchg [esi],dl
cmp dl,55h
jne end_test
mov dl,0aah
xchg [esi],dl
xchg [esi],dl
cmp dl,0aah
jne end_test
add esi,16
putchr1: ;在屏幕上打印
mov ebx,0b8468h

mov ecx,8
mov eax,esi
putchr:
rol eax,4
mov edx,eax
and al,0fh
add al,30h
cmp al,39h
ja add37
jmp disp
add37:
add al,7
disp:
mov ah,07
mov [ebx],ax
mov eax,edx
add ebx,2
loop putchr
jmp begin_test
end_test:
mov ax,0748h
mov [ebx],ax
mov eax,cr0
and eax,0fffffffeh
mov cr0,eax ;返回实模式
jmp $+2
sti
mov ah,4ch
int 21h

cseg ends
end start
...全文
130 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
SoRoMan 2003-11-01
  • 打赏
  • 举报
回复
結帖,謝謝各位。
Areslee 2003-10-27
  • 打赏
  • 举报
回复
不是,小代码可以不用IDT的
csdsjkk 2003-10-27
  • 打赏
  • 举报
回复
试过了实模式下运行正常
bluedreammer 2003-10-27
  • 打赏
  • 举报
回复
你的程序在pure dos下完全可以運行阿.
csdsjkk 2003-10-27
  • 打赏
  • 举报
回复
你的程序里有一条 cli 指令,
因此,
除了非屏蔽中断,
其他所有中断都禁止了
SoRoMan 2003-10-27
  • 打赏
  • 举报
回复
確實,單步到mov cr0,eax就reset了。

今天把環境搞到real mode,a20 disabled.改了下enable a20代碼,原來的好象有錯誤,終於ok了。
 不過當程序處在保護模式時,在處理那些於實模式下有沖突的幾個外部中斷,沒有發生問題,奇怪。比如說,在保護模式時,定時器產生中斷了(int 08h),此時不就麻煩了?
謝謝各位了哈。
csdsjkk 2003-10-27
  • 打赏
  • 举报
回复
终于明白楼主的问题所在了:
这个程序不能调试的,
直接在命令行运行即可
SoRoMan 2003-10-26
  • 打赏
  • 举报
回复
首先發現了一個問題:

我用debug32發現我的dos已在v86模式下。即已屬保護模式了,cr0最低位已為1,GDT,IDT也已經設置。都是emm386搞的鬼,於是廢掉emm386,重進dos,現在已在real mode 下了,a20也由於himem的加載已經打開。但是,在執行到mov cr0,eax時,又reset了,看來cr0改動後出現問題了,看來是IDT表沒設置的問題了, Areslee你指的就是這個吧?
Areslee 2003-10-24
  • 打赏
  • 举报
回复
肯定是代码的问题,这个东西我也做过实验的,可以成功的
SoRoMan 2003-10-23
  • 打赏
  • 举报
回复
多謝二位關注,我回去再試試看,還有看到別的家伙寫的時候

mov eax,cr0
or eax,1
 and al,not 20h ;進protected mode 前加了個這,我也去try一下看看。
mov cr0,eax

沒道理阿,還是dos不夠純??????
csdsjkk 2003-10-22
  • 打赏
  • 举报
回复
程序应该没有问题,
试试改这两句:
mov ebx,offset gdtr
mov [ebx]+2,eax
为:
mov bx,offset gdtr
mov [bx]+2,eax
Areslee 2003-10-22
  • 打赏
  • 举报
回复
关键是GDT中的代码段和数据的描述没有初始化。
这个的原理就是进入保护模式后将段描述限长设为4GB,然后不恢复段寄存器直接回到实模式。
Areslee 2003-10-21
  • 打赏
  • 举报
回复
GDT没有初始化完
SoRoMan 2003-10-21
  • 打赏
  • 举报
回复
GDT的基地址和16位界限都已初始化完成了啊。

mov [ebx]+2,eax ;GDT的基地址,32bit.

21,459

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧