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

Assembly 如何知道当前模式是实模式还是大实模式?,assembly,x86,bios,real-mode,Assembly,X86,Bios,Real Mode,假设我的API是从一个可能只在实模式或大实模式下工作的系统调用的。我的API应该显示当前的系统模式。那么它怎么知道当前模式是实模式还是大实模式呢 注: 在大实数模式下,CR0中的受保护模式启用位被禁用,因此检查它没有任何区别 即使启用了20地址行,也不意味着它处于大实数模式 在大实模式下,实模式地址别名将失败。让我们假设您处于大实数模式,并且您的DS的值为0x6000。由于DS的描述符缓存已重新加载(即大实数模式的定义),DS:0的物理地址不是0x60000。如果用另一个段寄存器点击0x6000

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

注:

  • 在大实数模式下,
    CR0
    中的受保护模式启用位被禁用,因此检查它没有任何区别
  • 即使启用了20地址行,也不意味着它处于大实数模式

  • 在大实模式下,实模式地址别名将失败。让我们假设您处于大实数模式,并且您的DS的值为0x6000。由于DS的描述符缓存已重新加载(即大实数模式的定义),DS:0的物理地址不是0x60000。如果用另一个段寄存器点击0x60000,则该内存位置将不同

    所以这里有一个食谱。在数据段中创建临时变量。注意其相对于DS的
    偏移量。用DS-1的值加载ES,更改变量的值,然后查看ES是否得到相同的值:(
    offset
    +0x10)。为了防止误报,请重复两次

    这不会检测到虚拟86模式。此外,如果ES也通过缓存描述符指向高内存,则在重新加载ES时,这将丢失。确保调用方代码不依赖于保持完整的ES


    大实数模式本身不是CPU模式——没有表示“我们现在处于大实数”的寄存器位。这只是一种使用i386特定逻辑的香草实数模式访问高内存的方法。上述程序仅检查DS是否以这种方式处理;根据实现的不同,DOS扩展器可能已经通过ES描述符重新加载实现了big real,同时保持DS正常。Wikipedia说,有时甚至CS也会以这种方式出现别名,尽管这是一个棘手的问题,因为存在中断。

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

    所以这里有一个食谱。在数据段中创建临时变量。注意其相对于DS的
    偏移量。用DS-1的值加载ES,更改变量的值,然后查看ES是否得到相同的值:(
    offset
    +0x10)。为了防止误报,请重复两次

    这不会检测到虚拟86模式。此外,如果ES也通过缓存描述符指向高内存,则在重新加载ES时,这将丢失。确保调用方代码不依赖于保持完整的ES

    大实数模式本身不是CPU模式——没有表示“我们现在处于大实数”的寄存器位。这只是一种使用i386特定逻辑的香草实数模式访问高内存的方法。上述程序仅检查DS是否以这种方式处理;根据实现的不同,DOS扩展器可能已经通过ES描述符重新加载实现了big real,同时保持DS正常。Wikipedia说,有时甚至CS也会以这种方式使用别名,尽管这是一个棘手的命题,因为会出现中断。

    如果执行此操作:

    mov ebx, 0x10000
    mov al, [ebx]
    
    并获得一个
    #GP
    ,则
    DS
    的段描述符的原始限制为0xFFFF,这是正常实地址模式和虚拟8086模式的情况

    如果您没有从
    mov al,[ebx]
    获得
    #GP
    ,则原始限制已扩展到0xFFFF之外(通常扩展到0xFFFFFF,但不一定如此)

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

    如果执行此操作:

    mov ebx, 0x10000
    mov al, [ebx]
    
    并获得一个
    #GP
    ,则
    DS
    的段描述符的原始限制为0xFFFF,这是正常实地址模式和虚拟8086模式的情况

    如果您没有从
    mov al,[ebx]
    获得
    #GP
    ,则原始限制已扩展到0xFFFF之外(通常扩展到0xFFFFFF,但不一定如此)


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

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


    因此,如果这就是您所说的,请尝试进入保护模式并检查粒度位的设置。对不起,我所有的旧手册都在阁楼里。如果你需要这些信息,我可以把它们挖出来

    在90年代早期,我们使用了一种未经证明的方法,让我们能够以实模式(现在可以称为大实模式)访问4Gig。方法是进入保护模式,将粒度位更改为1(表示4K粒度,而不是1字节粒度),然后返回到实模式,并将所有段寄存器设置为0。YouC