中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 搜索 | 上传 | 帮助 »
English/Chinese Fix Translation
作者:
标题: 重要发现,纯DOS下,直接寻址4G 上一主题 | 下一主题
cxdzxc
新手上路





积分 10
发帖 4
注册 2010-6-13
状态 离线
『楼 主』:  重要发现,纯DOS下,直接寻址4G [已使用 LLM 解释]

重要发现,纯DOS下,不操作CR0,不装载描述符,直接寻址4G,欢迎验证

romdizhi equ 0fffffff0h
mov esi,romdizhi
huancun equ 80000h
qushu:
xor ax,ax
mov ds,ax
mov es,ax
mov edi,huancun
mov ecx,10h/4
db 67h ;就是这句,非常关键
rep movsd
mov ax,huancun/10h
mov ds,ax
mov es,ax

Last edited by cxdzxc on 2010-6-14 at 10:09 ]
LLM 解释

代码整体功能及背景介绍

这段代码是一段x86汇编代码,意图在纯DOS环境下实现直接寻址4G内存空间相关操作。首先看代码中的一些常量定义:romdizhi equ 0fffffff0h,这是一个内存地址常量,通常可能与BIOS等相关区域的起始地址有关;huancun equ 80000h是一个内存缓存区域的起始地址定义。

代码逐部分分析

  • 初始化段寄存器
    xor ax,ax
    mov ds,ax
    mov es,ax
    
    这里通过xor ax,axax寄存器置为0,然后将数据段寄存器ds和附加段寄存器es都设置为0。这是为后续内存操作准备段寄存器的初始状态。
  • 设置目标地址等
    mov edi,huancun
    mov ecx,10h/4
    
    mov edi,huancun将目标内存地址设置为huancun所代表的地址(80000h),mov ecx,10h/4将循环次数设置为10h除以4,即4次,因为rep movsd指令每次复制4个字节的数据,这里要复制的数据量相关的循环次数设置为4次。
  • 关键指令db 67h
    • 指令作用及背景db 67h是一个字节数据定义指令,在这里67h对应的机器码是mov cr0, eax指令的一部分?不,其实准确来说,67h是一个操作数大小前缀。在x86汇编中,操作数大小前缀可以改变默认的操作数大小。例如,默认情况下,movsd指令是操作双字(4字节)数据,但是如果有67h前缀的话,会改变为操作字(2字节)数据?不过在这段代码中,结合上下文,这里的67h前缀可能是为了调整内存访问相关的操作数大小,以实现对大内存空间的直接寻址操作。具体来说,在实模式下,常规的内存寻址有局限性,通过一些特殊的操作数大小调整和内存复制操作来尝试突破实模式下的内存寻址限制,进而实现直接寻址4G内存空间相关的内存数据复制等操作。
  • 内存复制操作
    rep movsd
    
    rep movsd指令是重复字符串移动指令,movsd指令是移动双字(4字节)数据,rep前缀会根据ecx寄存器的值重复执行movsd指令。这里ecx被设置为4,所以会执行4次双字数据的移动操作,将源地址(romdizhi所指向的地址)的数据移动到目标地址(huancun所指向的地址)。
  • 重新设置段寄存器
    mov ax,huancun/10h
    mov ds,ax
    mov es,ax
    
    这里将ax寄存器设置为huancun除以10h(即256)的结果,然后将数据段寄存器ds和附加段寄存器es重新设置为这个值,可能是为了后续进一步的内存操作做段寄存器的准备。

多种实现直接寻址4G内存空间的思路

  • 使用PAE(物理地址扩展)模式
    • 原理:PAE模式是x86架构中用于扩展物理地址空间的一种模式。通过设置CR4寄存器中的PAE位等相关控制位,启用PAE模式后,可以使用64位的物理地址寄存器来访问更大的物理内存空间,从而实现对4G甚至更大内存空间的直接寻址。但在纯DOS环境下,启用PAE模式可能需要对系统控制寄存器等进行正确的设置,并且要注意与实模式等的切换等问题。
    • 代码示例(大致示意)
; 开启PAE模式相关设置
mov eax, cr4
or eax, 0x00000010 ; 设置PAE位
mov cr4, eax

; 然后可以通过设置页目录等方式来映射大内存空间进行寻址
  • 使用扩展的内存访问指令
    • 原理:x86的一些高级指令集支持对更大内存空间的访问。例如,在长模式下有更丰富的内存寻址方式,但在纯DOS环境下可能需要考虑如何在实模式基础上逐步过渡到长模式相关的操作来实现大内存空间的直接寻址。不过从实模式直接过渡到长模式需要经过保护模式等步骤,需要正确设置GDT(全局描述符表)、IDT(中断描述符表)等相关描述符表来进入长模式。
    • 代码示例(大致示意,进入保护模式部分)
; 设置GDT
lgdt [gdt_ptr]

; 开启保护模式
mov eax, cr0
or eax, 1
mov cr0, eax

; 进入保护模式后再进一步设置长模式相关等以访问大内存空间

总之,这段代码尝试在纯DOS下通过特定的汇编指令组合来实现直接寻址4G内存空间相关操作,其中db 67h这个字节数据定义指令起到了关键的操作数大小调整等作用来支持后续的内存操作。



2010-6-14 10:06
查看资料  发短消息  网志   编辑帖子  回复  引用回复
cxdzxc
新手上路





积分 10
发帖 4
注册 2010-6-13
状态 离线
『第 2 楼』:   使用 LLM 解释/回答一下

http://topic.csdn.net/u/20100613/14/513861a8-fce6-476e-ab6e-d279ba5dd47f.html?56205


hpsmouse

()鼠()

等 级:

#15楼 得分:0回复于:2010-06-14 09:50:54验证成功,不过这个 0x67 好像只对 movs 有用,对一般的 mov 没用。


2010-6-14 11:01
查看资料  发短消息  网志   编辑帖子  回复  引用回复
cxdzxc
新手上路





积分 10
发帖 4
注册 2010-6-13
状态 离线
『第 3 楼』:   [已使用 LLM 解释]

cnzdgs
(满天星\n技术问题请勿私聊)
等 级:
2
更多勋章
#40楼 得分:0回复于:2010-06-15 01:54:48
16位代码中加上67H前缀就表示使用32位寻址,在实模式下也可以使用32位寻址,但要求相关段寄存器必须已装入适当的描述符,貌似还要求段寄存器的当前值必须为0(这点未验证过)。
在Windows的虚拟DOS环境中不允许使用32位寻址;在虚拟机中则要依赖于“虚拟”的具体实现,能否运行未知。在某些实体机纯DOS环境中可以运行,是由于启动时BIOS程序曾切入过保护模式,并且在ds、es中装入了32位段描述符,而在切回实模式时没有清除,所以在实模式中仍可使用。可以做个简单的验证,自己写一小段程序,切入保护模式,将ds、es装入空描述符,然后再切回实模式,之后再运行这段程序就会出问题了。
LLM 解释

1. 关于16位代码中67H前缀的作用

(1)67H前缀与32位寻址的关系

在x86汇编中,67H是一个地址大小前缀(address - size prefix)。当16位代码中使用67H前缀时,就表示要使用32位寻址方式。例如,正常的16位操作数指令是按照16位来处理内存操作数的地址等情况,而加上67H前缀后,就会按照32位的规则来进行寻址操作。

(2)实模式下32位寻址的条件

  • 段寄存器需装入适当描述符:在实模式下,通常段寄存器是按照实模式的16位段来使用的,但如果要实现32位寻址,相关的段寄存器(如DS、ES等)需要装入32位的段描述符。段描述符是保护模式下用于描述内存段的结构,包含段基址、段限长、段属性等信息。
  • 段寄存器当前值需为0的相关情况:文中提到貌似段寄存器的当前值必须为0,但这一点需要进一步验证。从原理上来说,在实模式向保护模式切换等过程中,可能会涉及到段寄存器状态的调整。比如在保护模式下设置了段描述符后,切回实模式时如果段寄存器没有被正确清理,可能会残留一些保护模式下的状态,从而影响32位寻址的使用。

2. 在不同环境下的表现

(1)Windows虚拟DOS环境

在Windows的虚拟DOS环境中,不允许使用32位寻址。这是因为Windows的虚拟DOS环境有其自身的安全和兼容性限制机制,它会阻止一些可能超出其虚拟环境安全边界或者不符合其规范的32位寻址相关操作,以保证整个系统的稳定和安全。

(2)虚拟机环境

在虚拟机中能否运行依赖于“虚拟”的具体实现。不同的虚拟机软件(如VMware、VirtualBox等)对硬件模拟的方式不同。有些虚拟机可能能够模拟出足够接近实体机的环境来支持在实模式下使用32位寻址,但有些则可能因为模拟的限制而无法正确支持。例如,虚拟机对硬件中断、内存管理等的模拟如果没有完全符合实模式下32位寻址所需的硬件特性,就可能导致无法正常运行相关程序。

(3)实体机纯DOS环境

在某些实体机纯DOS环境中可以运行是由于启动时BIOS程序曾切入过保护模式,并且在DS、ES中装入了32位段描述符,而在切回实模式时没有清除。BIOS(基本输入输出系统)在启动过程中可能会进行一些模式切换操作来获取硬件的更多功能。当BIOS切入保护模式并设置了段描述符后,切回实模式时如果没有完全清理段寄存器等状态,那么在后续的实模式程序中就可以利用这些残留的保护模式下的段描述符信息来实现32位寻址。可以通过编写简单程序来验证这一点:

; 示例程序大致步骤
org 0x100
start:
    ; 切入保护模式的代码
    cli
    lgdt [gdt_ptr]
    mov eax, cr0
    or eax, 1
    mov cr0, eax
    jmp dword 0x08:protected_mode
protected_mode:
    ; 装入32位段描述符到DS、ES等段寄存器
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    ; 切回实模式的代码
    mov eax, cr0
    and eax, ~1
    mov cr0, eax
    jmp start  ; 切回实模式后再次运行该程序看看情况
gdt:
    dd 0, 0
    dd 0x0000FFFF, 0x00CF9A00, 0x00CF9200  ; 示例的段描述符,这里只是简单示意
gdt_ptr:
    dw $ - gdt - 1
    dd gdt
end:

上述程序中,先切入保护模式,设置段描述符,然后切回实模式。之后再次运行该程序时就可以观察是否会出现预期的问题或者是否能正常利用32位寻址相关功能,从而验证实模式下32位寻址在实体机纯DOS环境中的情况。



2010-6-15 10:08
查看资料  发短消息  网志   编辑帖子  回复  引用回复
cxdzxc
新手上路





积分 10
发帖 4
注册 2010-6-13
状态 离线
『第 4 楼』:   [已使用 LLM 解释]

cxdzxc
等 级:
#42楼 得分:0回复于:2010-06-15 09:30:51
经过实验,王老师和DelphiGuy说的是正确的,应该是我的BIOS---在ds、es中装入了32位段描述符,而在切回实模式时没有清除,所以在实模式中仍可使用

下面帖出实验代码:
org 100h
cli

xor eax,eax
mov ax,cs
shl eax,4
add [gdtzhizhen+2],eax
lgdt [gdtzhizhen]
mov eax,cr0
or al,1
mov cr0,eax
mov bx,gdt1-gdt0
mov ds,bx
mov es,bx
and al,0feh
mov cr0,eax

mov ah,4ch
int 21h

gdt0 dd 0,0
gdt1 db 0ffh,0ffh,0,0,0,92h,0fh,0
gdtzhizhen dw $-gdt0,gdt0,0

----------------------------
用NASM编译成一个COM文件,先在DOS下运行这个文件,然后DEBUG 装入先前的实验代码,G命令运行就会死机了
LLM 解释

代码分析

1. 代码起始与初始化

org 100h
cli
  • org 100h:指定程序的起始地址为0x100,这是DOS下COM文件的默认起始地址。
  • cli:清除中断标志位,禁止中断,防止在设置保护模式相关寄存器时被中断干扰。

2. 全局描述符表(GDT)相关操作

xor eax,eax
mov ax,cs
shl eax,4
add [gdtzhizhen+2],eax
lgdt [gdtzhizhen]
  • xor eax,eax:将eax寄存器清零。
  • mov ax,cs:将代码段寄存器cs的值移动到ax寄存器中。
  • shl eax,4:将eax左移4位,因为段基址在保护模式下是32位的,而cs是16位的,左移4位相当于将16位的段基址扩展为20位,再通过后续操作扩展为32位。
  • add [gdtzhizhen+2],eax:将计算得到的段基址添加到全局描述符表地址gdtzhizhen的偏移2的位置。
  • lgdt [gdtzhizhen]:加载全局描述符表寄存器gdtr,根据gdtzhizhen指向的结构来设置GDT的基址和界限。
mov eax,cr0
or al,1
mov cr0,eax
  • mov eax,cr0:将控制寄存器cr0的值移动到eax寄存器中。
  • or al,1:将cr0的最低位(保护模式使能位)置1,开启保护模式。
  • mov cr0,eax:将修改后的eax值写回cr0,使CPU进入保护模式。
mov bx,gdt1-gdt0
mov ds,bx
mov es,bx
  • mov bx,gdt1-gdt0:计算gdt1相对于gdt0的偏移量,并将其移动到bx寄存器中。
  • mov ds,bx:将数据段寄存器ds设置为指向GDT所在的段。
  • mov es,bx:将附加段寄存器es也设置为指向GDT所在的段。
and al,0feh
mov cr0,eax
  • and al,0feh:将cr0的最低位清零,准备切回实模式。
  • mov cr0,eax:将修改后的eax值写回cr0,使CPU切回实模式。
mov ah,4ch
int 21h
  • mov ah,4ch:设置中断调用功能号为4ch,表示程序终止。
  • int 21h:调用DOS中断,终止当前程序。

3. 全局描述符表定义

gdt0 dd 0,0
gdt1 db 0ffh,0ffh,0,0,0,92h,0fh,0
gdtzhizhen dw $-gdt0,gdt0,0
  • gdt0 dd 0,0:定义GDT的第一个描述符,全0表示空描述符。
  • gdt1 db 0ffh,0ffh,0,0,0,92h,0fh,0:定义GDT的第二个描述符,具体的字节值定义了段的权限等信息,例如92h表示段存在、可写等权限,0fh表示段的粒度等信息。
  • gdtzhizhen dw $-gdt0,gdt0,0:定义全局描述符表的指针结构,第一个字是GDT的界限($-gdt0表示从gdt0到当前位置的字节数减1),第二个字是GDT的基址(gdt0的地址),第三个字是0。

死机原因分析

当程序进入保护模式后又切回实模式时,由于之前在保护模式下设置的段描述符等信息没有正确清除,在实模式下继续执行可能会导致内存访问等出现异常情况。具体来说,在保护模式下设置的dses指向了GDT相关的段,切回实模式后这些寄存器的值没有正确恢复,导致后续的内存访问或者其他操作无法正确进行,从而出现死机现象。

可能的解决方案

方案一:正确恢复实模式下的段寄存器

在切回实模式之前,应该将dses等段寄存器恢复为实模式下的默认值(例如dses恢复为0)。修改代码如下:

; 在切回实模式之前添加
mov ds,ax ; ax在之前已经被设置为cs的值,这里可能需要根据实际情况调整,或者直接将ds恢复为0
mov es,ax

方案二:重新初始化GDT相关寄存器

在切回实模式后,重新初始化GDT相关的寄存器,确保在实模式下GDT处于正确的初始状态。例如:

; 切回实模式后重新初始化GDT相关
xor eax,eax
mov ax,cs
shl eax,4
mov [gdtzhizhen+2],eax
lgdt [gdtzhizhen]
; 然后再进行后续操作

方案三:检查保护模式切换过程中的寄存器状态

仔细检查在保护模式切换过程中cr0等寄存器的设置和恢复是否正确,确保没有遗漏的操作或者错误的设置。例如,在进入保护模式时开启保护模式的操作是否正确,切回实模式时清除保护模式使能位的操作是否正确等。

; 检查进入保护模式的操作
mov eax,cr0
or al,1
mov cr0,eax
; 检查切回实模式的操作
mov eax,cr0
and al,0feh
mov cr0,eax

通过以上对代码的分析和可能解决方案的探讨,可以更好地理解程序死机的原因以及如何尝试解决相关问题。```



2010-6-15 10:09
查看资料  发短消息  网志   编辑帖子  回复  引用回复
netwinxp
高级用户





积分 741
发帖 366
注册 2007-7-25
状态 离线
『第 5 楼』:   使用 LLM 解释/回答一下

DOS下访问4G要先打开A20,否则访问偶数地址会出问题。


2010-6-17 20:50
查看资料  发短消息  网志   编辑帖子  回复  引用回复
AlexZhang
系统支持





积分 995
发帖 427
注册 2007-2-8
状态 离线
『第 6 楼』:   使用 LLM 解释/回答一下

Originally posted by netwinxp at 2010-6-17 08:50 PM:
DOS下访问4G要先打开A20,否则访问偶数地址会出问题。

对头,需要打开A20地址线


2010-6-17 22:22
查看资料  访问主页  发短消息  网志   编辑帖子  回复  引用回复
johnsonlam
银牌会员

阿林


积分 1410
发帖 497
注册 2004-6-28
来自 九龍,香港
状态 离线
『第 7 楼』:   使用 LLM 解释/回答一下

Originally posted by AlexZhang at 2010-6-17 10:22 PM:

对头,需要打开A20地址线


根 據 Jack Ellis 兄 所 說 , A20 控 制 原 來 也 挺 『 不 標 準 』 ...

1) Port 92h logic
2) keyboard-port logic

還 要 用 時 上 鎖 和 解 鎖 lock / unlock , 煩 !




我 的 網 站 - http://optimizr.dyndns.org
2010-6-18 23:58
查看资料  发送邮件  访问主页  发短消息  网志   编辑帖子  回复  引用回复
netwinxp
高级用户





积分 741
发帖 366
注册 2007-7-25
状态 离线
『第 8 楼』:   使用 LLM 解释/回答一下

KBC是286以后的标准,92口不标准(它是MAC总线的标准,很多机子不能用,要在在BIOS SETUP把A20 Fast打开(如果有此项的话)才能支持),KBC法对x86通用,不过切换慢,而且有时会和USB键鼠冲突(写KBC A20位时要先禁止KBC数据缓冲区写入,写完后再去掉禁止,否则USB键鼠有可能错误写到KBC命令缓冲区造成USB键鼠失效)。

我最早看到的DOS下利用FS、GS访问4G是梁肇新(就是那个超级结巴的开发者)9x年写的“在DOS实模式下直接存取4GB内存”一文,现在的“砖家”抄袭够狠的,全成了“原创”。

实模式下访问4G的最大问题是——对于FFFF:FFFF以上内存没有管理,所以还是通过INT 15、XMS、EMS、DPMI稳妥。

Last edited by netwinxp on 2010-6-20 at 14:14 ]


2010-6-20 13:59
查看资料  发短消息  网志   编辑帖子  回复  引用回复
gssxd
新手上路





积分 6
发帖 3
注册 2010-5-19
状态 离线
『第 9 楼』:   使用 LLM 解释/回答一下

<img src="images/smilies/face-raspberry.png" align="absmiddle" border="0">

Last edited by gssxd on 2010-6-21 at 22:42 ]


2010-6-21 22:40
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
gssxd
新手上路





积分 6
发帖 3
注册 2010-5-19
状态 离线
『第 10 楼』:   使用 LLM 解释/回答一下

Originally posted by netwinxp at 2010-6-20 13:59:
KBC是286以后的标准,92口不标准(它是MAC总线的标准,很多机子不能用,要在在BIOS SETUP把A20 Fast打开(如果有此项的话)才能支持),KBC法对x86通用,不过切 ...

关于A20 Disable以及Enable,还是要看BIOS里面的实现的。DOS下都是在调用INT15,BIOS提供的接口,属于Rumtime。BIOS在引导OS之前会把A20给Disbale。


2010-6-21 22:47
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
netwinxp
高级用户





积分 741
发帖 366
注册 2007-7-25
状态 离线
『第 11 楼』:   使用 LLM 解释/回答一下

CMOS里面的A20 Fast Enable/Disable是指提不提供92H口来快速切换A20的状态,如果Disable掉就不提供92H口,只能用慢速的KBC来切换,它和A20 Enable/Disable不是一回事。INT 15H事实上也是通过KBC或者92H口来操作。至于所谓的FireWare Runtime其实也就是把总线操作、I/O操作、所需数据用ASL(微软要求的格式)包装起来方便windows acpi操作硬件罢了,本质上和以前的APM差不多,只不过APM通过INT 15H调用,需切换到实模式(比如win98的关机),windows可以在保护模式通过ACPI根据ASL定义来操作硬件而已。ASL是微软提供标准和工具,说白了也就形成变相上的垄断,看看linux在实现ACPI上走了多少弯路不就明白了?其实如果里面放的是没经过“故意编译”的脚本,别的操作系统实现起来也不难了。

Last edited by netwinxp on 2010-6-22 at 18:52 ]


2010-6-22 18:25
查看资料  发短消息  网志   编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: