首页 文章

如何知道当前模式是实模式还是大实模式?

提问于
浏览
1

假设我的API是从一个系统调用的,该系统可能只在实模式或大实模式下工作 . 我的API应该显示当前的系统模式 . 然后怎么知道当前模式是实模式还是大实模式?

注意:

  • 在大实模式下, CR0 中的保护模式使能位被禁用,因此检查它没有任何区别 .

  • 即使启用了A20地址线,也不意味着它处于大实模式 .

3 回答

  • 0

    如果你执行这个:

    mov ebx, 0x10000
    mov al, [ebx]
    

    并获得 #GP ,然后 DS 的段描述符的原始限制为0xFFFF,这是正常实地址模式和虚拟8086模式的情况 .

    如果没有从 mov al, [ebx] 获得 #GP ,则原始限制已扩展到0xFFFF以上(通常为0xFFFFFFFF,但不一定如此) .

    顺便说一句,检查v86模式可以并且可能应该在尝试上述之前完成(如果主机操作系统没有正确反映处理程序的异常) . 执行 smsw 以获取 cr0.pe . 它将在v86模式下设置为1,在实际地址模式下设置为0 . 直接用 mov 读取 cr0 将在v86模式下生成 #GP ,这就是 smsw 是首选方法的原因 .

  • 0

    在大实模式下,实模式地址别名将失败 . 让我们假设你处于大实模式,你的DS值为0x6000 . 由于已重新加载DS的描述符缓存(大实模式的定义),因此DS:0的物理地址不是0x60000 . 如果使用另一个段寄存器命中0x60000,则该内存位置不同 .

    所以这是一个食谱 . 在数据段中创建临时变量 . 注意它相对于DS的 offset . 使用DS-1的值加载ES,更改变量的值,并查看是否在ES处获得相同的值:( offset 0x10) . 为了防止误报,请做两次 .

    这不会检测虚拟86模式 . 此外,如果ES通过缓存的描述符指向高内存,那么当您重新加载ES时,这将丢失 . 确保调用者代码不依赖于ES保持不变 .

    大的实模式本身并不是CPU模式 - 没有寄存器位表示“我们现在处于大的实际状态” . 它只是一种使用香草实模式的i386特定逻辑访问高内存的方法 . 上述程序仅检查DS是否已按此方式处理;根据实现,DOS扩展器可能已经通过ES描述符重新加载实现了大的真实,同时保留了DS vanilla . 维基百科说,有时甚至CS也会以这种方式出现混淆,尽管由于中断,这是一个棘手的提议 .

  • 1

    在90年代早期,我们使用一种未记录的方法让我们在REAL模式下访问4Gig(现在可称为BIG REAL MODE) . 方法是进入保护模式,将粒度位更改为1(表示4K粒度而不是1字节粒度)然后返回实模式并将所有段寄存器设置为0.然后可以使用ebx等访问4Gig的内存 .

    因此,如果您正在讨论这个问题,请尝试进入保护模式并检查粒度位的设置 . 对不起,我所有的旧手册都在阁楼里 . 如果您需要这些信息,我可以将它们挖出来 .

相关问题