LOADALL

From Infogalactic: the planetary knowledge core
Jump to: navigation, search

LOADALL is the common name for two different, undocumented machine instructions of Intel 80286 and Intel 80386 processors, which allow access to areas normally outside of the IA-32 API scope, like descriptor cache registers. The LOADALL for 286 processors is encoded 0Fh 05h, while the LOADALL for 386 processors is 0Fh 07h.[1]

Both variants – as the name implies – load all CPU internal registers in one operation. LOADALL had the unique ability to set up the visible part of the segment registers (selector) independently of their corresponding cached part, allowing the programmer to bring the CPU into states not otherwise allowed by the official programming model.

As an example of the usefulness of these techniques, LOADALL can set up the CPU to allow access to all memory from real mode, without having to switch it into protected mode (the so-called 'unreal mode'). Programs such as the RAMDRIVE and HIMEM drivers in MS-DOS, AboveDisk (a commercial package by Above Software which converted hard disk or extended memory into expanded memory), and OS/2 used LOADALL. Examination of the virtual machine monitor code in Windows/386 2.1 shows it uses both the 286 and the even less known 386 variant. Microsoft's HIMEM.SYS version 2.06[2] also used LOADALL to quickly copy to and from extended memory on 286 systems.

Another interesting usage of LOADALL, laid out in the book The Design of OS/2,[3] would have been to allow running former real mode programs in 16-bit protected mode, as utilized by Digital Research's Concurrent DOS 286 since 1985 [4] as well as FlexOS 286 and IBM 4680 OS since 1986/1987. Marking all the descriptor caches in the GDT and LDTs "not present" would allow the operating system to trap segment register reloads as well as attempts at performing real-mode specific "segment arithmetic" and emulate the desired behavior by updating the segment descriptors (LOADALL again). This "virtual 8086 mode" for the 80286 was, however, too slow to be practical. The idea had to be mostly discarded, furthermore, due to errata in some early Intel 80286 processors before the E-2 stepping.[4][5] As a result, OS/2 1.x – and Windows in "standard" mode as well – had to run DOS programs in real mode. Nevertheless the idea was not lost; it led Intel to introduce the virtual mode of the 80386, allowing the implementation of "DOS boxes" at last in a relatively efficient and documented way.

Because LOADALL did not perform any checks on the validity of the data loaded into processor registers, it was possible to load a processor state which could not be normally entered, such as using real mode (PE=0) together with paging (PG=1) on 386 class CPUs.[6]

80286

Opcode 0F05. The instruction reads data from addresses 00800–00866, whatever the content of the segment registers.

Address number of bytes register register register register
00800 6 not used
00806 2 MSW (machine status word)
00808 14 not used
00816 2 TR (task register)
00818 2 flags
0081A 2 IP (instruction pointer)
0081C 2 LDTR (local descriptor table register)
0081E 4x2 DS (data segment) SS (stack segment) CS (code segment) ES (extra segment)
00826 4x2 DI (destination index) SI (source index) BP (base pointer) SP (stack pointer)
0082E 4x2 BX DX CX AX
00836 4x6 ES segment descriptor CS segment descriptor SS segment descriptor DS segment descriptor
0084E 4x6 GDT, global descriptor table LDT, local descriptor table IDT, interrupt descriptor table TSS, task state segment

Note that the 80286 LOADALL instruction can not be used to switch from protected back to real mode[7] (it can't clear the PE bit in the MSW). However, use of the LOADALL instruction can avoid the need to switch to protected mode altogether.

80386

Opcode 0F07. The instruction loads data from address ES:EDI. It actually uses ES, not the ES descriptor.

Address number of bytes register register register register
ES:EDI+00 4 CR0, control register 0
ES:EDI+04 4 EFLAGS
ES:EDI+08 4 EIP, instruction pointer
ES:EDI+0C 4x4 EDI, destination index ESI, source index EBP, byte pointer ESP, stack pointer
ES:EDI+1C 4x4 EBX EDX ECX EAX
ES:EDI+2C 2x4 DR6 DR7
ES:EDI+34 4 TR, task state selector
ES:EDI+38 4 LDTR, local descriptor table
ES:EDI+3C 4x2 GS, extra segment not used FS, extra segment not used
ES:EDI+44 4x2 DS, data segment not used SS, stack segment not used
ES:EDI+4C 4x2 CS, code segment not used ES, extra segment not used
ES:EDI+54 4x12 TSS descriptor, task state selector IDT descriptor, interrupt descriptor table GDT descriptor, global descriptor table LDT descriptor, local descriptor table
ES:EDI+84 4x12 GS segment descriptor FS segment descriptor DS segment descriptor SS segment descriptor
ES:EDI+B4 2x12 CS segment descriptor ES segment descriptor

See also

References

  1. Frank Van Gilluwe, The Undocumented PC, 1994, pages 62-70, ISBN 0-201-62277-7
  2. Lua error in package.lua at line 80: module 'strict' not found.
  3. Lua error in package.lua at line 80: module 'strict' not found.
  4. 4.0 4.1 Lua error in package.lua at line 80: module 'strict' not found.
  5. Lua error in package.lua at line 80: module 'strict' not found.
  6. Frank Van Gilluwe, The Undocumented PC, 1994, page 69, ISBN 0-201-62277-7
  7. Lua error in package.lua at line 80: module 'strict' not found.