假设我的API是从一个系统调用的,该系统可能只在实模式或大实模式下工作。我的API应该显示当前的系统模式。那么它怎么能知道当前模式是实模式还是大实模式呢?
注意:
CR0中的保护模式启用位被禁用,因此检查它没有任何区别。发布于 2013-03-11 22:19:36
如果您执行此操作:
mov ebx, 0x10000
mov al, [ebx]然后得到一个#GP,那么DS的段描述符的初始限制是0xFFFF,这是正常的实地址模式和虚拟的8086模式的情况。
如果您没有从#GP获得mov al, [ebx],那么最初的限制已经超出了0xFFFF (通常扩展到0xFFFFFF,但不一定是这样)。
顺便说一句,在尝试上述操作之前,可以而且很可能应该检查v86模式(以防主机OS没有正确地反映处理程序的异常)。执行smsw以获得cr0.pe。在v86模式下,它将被设置为1,在实际地址模式中设置为0。直接使用mov读取mov将在v86模式下生成#GP,这就是为什么smsw是首选方法。
发布于 2013-03-11 14:24:04
在大实模式下,实模式地址混叠将失败。假设您处于大的实模式,您的DS值为0x6000。由于DS的描述符缓存已经重新加载(大实模式的定义),DS:0的物理地址不是0x60000。如果您使用另一个段寄存器达到0x60000,那将不是相同的内存位置。
这是一个菜谱。在数据段中创建一个划痕变量。注意它的offset相对于DS。用DS-1的值加载ES,更改变量的值,并查看在ES:(offset+0x10)处是否得到相同的值。为了防止虚假的负面影响,请做两次。
这不会检测到虚拟86模式。另外,如果ES也通过缓存描述符指向高内存,那么当您重新加载ES时,这将丢失。确保调用者的代码不会依赖于完整的代码。
大真实模式本身并不是CPU模式--没有一个寄存器位表示“我们现在处于大真实状态”。这只是一种使用i 386特有的普通实模式逻辑访问高内存的方法。上面的过程只检查DS是否被这样对待;根据实现的不同,DOS扩展程序可能通过ES描述符重新加载来实现大的实体,同时保持DS的普通。维基百科说,有时甚至CS也是这样命名的,尽管这是一个棘手的命题,因为中断。
发布于 2014-01-15 21:56:05
在90年代早期,我们使用了一种无文档的方法,允许我们在实模式下访问4Gig (现在可以称为大实模式)。方法是进入保护模式,将粒度位更改为1(意味着4K粒度,而不是1字节粒度),然后返回实际模式,并将所有段寄存器设置为0。然后,您可以使用ebx等来访问4Gig内存。
因此,如果这就是您所谈论的,尝试进入保护模式并检查粒度位的设置。对不起,我所有的旧手册都在阁楼上。如果你需要这些信息,我可以把它们找出来。
https://stackoverflow.com/questions/15340624
复制相似问题