user1852459
user1852459

Reputation: 21

How to know that current mode is real or big real mode?

Suppose my API is to be called from a system which may work in real mode or big real mode only. My API is supposed to display the current system mode. Then how could it know whether the current mode is real mode or big real mode?

Note:

  1. In Big real mode the protected mode enable bit in CR0 is disabled, hence checking it doesn't make any difference.
  2. Even though A20 address line is enabled it does not mean that it is in big real mode.

Upvotes: 1

Views: 1180

Answers (3)

eddyq
eddyq

Reputation: 909

In the early 90's we used an undocumented method to give us access to 4Gig in REAL mode (may now be called BIG REAL MODE). The method was to go into protected mode, change the granularity bit to 1 (means 4K granularity as opposed to 1 byte granularity) then go back to real mode and set all segment registers to 0. You can then use the ebx, etc to access 4Gig of memory.

So if that is what you are talking about, try going to protected mode and check the setting of the granularity bit. I'm sorry but all of my old manuals are in the attic. If you need that information I could dig them out.

Upvotes: 0

Alexey Frunze
Alexey Frunze

Reputation: 62106

If you execute this:

mov ebx, 0x10000
mov al, [ebx]

and get a #GP, then the segment descriptor for DS has the original limit of 0xFFFF, which is the case for the normal real address mode and for the virtual 8086 mode.

If you don't get a #GP from mov al, [ebx], the original limit has been extended beyond 0xFFFF (usually to 0xFFFFFFFF, but not necessarily so).

Btw, checking for the v86 mode can and probably should be done prior to trying the above (in case your host OS doesn't properly reflect exceptions to your handlers). Execute smsw to obtain cr0.pe. It will be set to 1 in the v86 mode and to 0 in the real address mode. Reading cr0 directly with mov will generate a #GP in the v86 mode, which is why smsw is a preferred method.

Upvotes: 1

Seva Alekseyev
Seva Alekseyev

Reputation: 61386

In the big real mode, real mode address aliasing would fail. Let's imagine you're in big real mode, and your DS has the value of 0x6000. Since the descriptor cache for DS has been reloaded (the very definition of big real mode), the physical address of DS:0 is not 0x60000. If you hit 0x60000 with another segment register, that won't be the same memory location.

So here's a recipe. Create a scratch variable in the data segment. Note its offset relative to DS. Load ES with the value of DS-1, change the value of the variable, and see if you get the same value at ES:(offset+0x10). To protect against false negatives, do it twice.

This won't detect the virtual 86 mode. Also, if ES was pointing at high memory via a cached descriptor, too, this will be lost when you reload ES. Make sure the caller code won't rely on ES staying intact.

The big real mode is not a CPU mode per se - there's no register bit that says "we're in big real now". It's just a way to access high memory using the i386-specific logic of the vanilla real mode. The procedure above only checks if DS has been treated that way; depending on implementation, a DOS extender might've implemented big real via ES descriptor reloading while keeping DS vanilla. Wikipedia says that sometimes even CS is aliased in this way, albeit this is a tricky proposition because of interrupts.

Upvotes: 0

Related Questions