HIMEM and EMM386

Recently on the FreeDOS mailing list, a user asked how HIMEM and EMM386 are able to address more than 1MB memory. These are the replies:

Neato asks:

I know the CPU can't *address* >1024k except in protected mode. Does that mean HIMEM.SYS and EMM386.EXE use protected mode to provide expanded memory? If not, how can I access >1024k w/o those drivers (or dos for that matter?)

David Lloyd responds:

This is possible on the 80286, 80386, and some 80486 by using an instruction called 'loadall'. Basically, you can load the descriptor base registers for the DS or ES (or FS or GS) segments, thus allowing them to access memory beyond 1MB. There are a lot of caveats though... for instance, you have to have interrupts disabled or weird things will happen.

It is possible but ugly, and not very portable. I've been given to believe that Microsoft's HIMEM.SYS uses this trick on 80286s to access extended RAM. You may want to look at the source with 'debug' or a similar tool.

Arkady writes:

No and yes. Yes, EMM386 switches 386+ CPU into V86 mode to provide access to extended memory as for exapanded through _mapped_ 64K window. No, HIMEM works on both 286 and 386+ in real mode and uses special methods to access extended memory.

Johannes Zwart also writes about Flat Real Mode:

You can address memory beyond 1024k, using the Flat Memory Model. FMM != PM.

So, FMM works like this:
1. Switch to Protected Mode
2. Set FS and GS limits to 4 GB.
3. Switch back to Real Mode.
4. Now you have access to all memory via FS & GS! Can't use lods/stos/movs, though. So you'll have to 'mov fs:[eax]' or so.

Good: Borland Pascal 8.0 supports this model.

- Only possible on a 80386+.
- Not supported by Windows (32 bits), EMM386 and other memory managers, of course. But then, you could borrow some DPMI/VCPI functionality from them to achieve the same goal.

lustina adds:

Go to Simtel and download flat100.zip - this is the best lib I've seen yet for using flat real mode, it's free, and it's written in NASM. I use it with a 16-bit compiler (Force) and it works like a charm, plus you get the source so you can see exactly how it works.

Ralf Quint responds:

[Does that mean HIMEM.SYS and EMM386.EXE use protected mode to provide expanded memory?] Yes. Exactly how, depends on the type of CPU.

For 286, only XMS through HIMEM (and similar 3rd party programs) is available. XMS provides only services to transfer data from and to extended memory. For this transfer call, a lot of special registers need to be set, the CPU is switched into protected mode, the transfer between extended memory and "real" memory is performed, and then the CPU is reset back in to real mode, which is quite a hassle on 286ers. The same goes for the INT15h functions introduced with the IBM PC, but there had been no "security" build in to prevent that two programs access the same memory areas (other than XMS,the functions don't keep track of the allocated memory areas).

On 386er and above, the CPU can be switched into a "Virtual 8086" mode (V86). In this mode, any 4 KB page of memory can be put into the lower 1MB address space. This is the basic way how UMB's are achieved (on 286's, this was only possible through special chip sets, which provided the "bank-switching" (NEAT boards). For XMS support, the 386+ is switched into PM too, but the CPU has an easier way to go back and forth than on 286ers.

EMS memory (Which is provided by EMM386) was available on 808x CPU's through special bank-switching hardware (LIM memory cards), on 386+ CPUs, this is simulated through the paging features of these CPU's in protected mode. To provide easier access for DOS programs to the protected mode capabilities beside XMS (through INT 2F/43xxh) and EMS (through INT 67h), first VCPI, than DPMI services have been created.

The so-called "Flat Real Mode" (FRM) is not quite the same and often conflicts with one of the before mentioned access methods.