ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÄÄ´ This text comes from IMPHOBIA Issue IX - February 1995 ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ THE LOADALL INSTRUCTION In Imphobia Issue #8, Walken/Impact Studios wrote a nice article about memory management. However, for some reason he seems to like flat-real-mode (FRM) which is in my belief a totally wrong way of programming since FRM requires a 'clean' boot. Anyway, the discussion of the advantages and disadvantages of using FRM as oposed to true flat-model protected mode are not at issue here. Besides, there's too many coders who just blindly think FRM or PMode is better whithout ever having performed some serious tests. For those who think PMode is better, I strongly suggest checking the 386/486 references on segment management and memory access. For those who think FRM is better... just speed-test your program on a Pentium . Some info about the LOADALL instruction first. There's a 286 LOADALL instruction and a 386/486/Pen- tium LOADALL instruction, they have different opcodes, and work slightly different. Since no-one wants to code a 286 protected mode program nowadays, I won't cover the 286 variant of the LOADALL instruction. Strangely however some of the BIOSes will 'emulate' the 286 variant, by hooking it into the "bad opcode" interrupt. The LOADALL instruction is not documented by intel in their CPU reference guides. LOADALL is used in the VDISK program by Microsoft, OS/2 and Windows 95, and supposedly also in Windows NT. The 286 variant has opcode 0Fh, 05h. The 386+ variant has opcode 0Fh, 07h. As said before, any further reference to LOADALL assumes the 386 variant unless otherwise mentionned. LOADALL loads a 204-byte table pointed to by ES:EDI into the registers. Note however, that ES:EDI must point to a valid memory location layed out by the current memory model, meaning. When in real mode, ES points to a segment, and EDI points to an offset within that segment (thus, only the lower 16 bit offset is used). When in PMode, ES is a selector, and EDI an offset within that selector page. When in FRM, ES is a segment, and EDI a 32-bit offset within that segment. The table layout is as follows. Offset Size CPU register loaded ------ ---- ------------------------ 0h 4 CR0 4h 4 EFLAGS 8h 4 EIP Ch 4 EDI 10h 4 ESI 14h 4 EBP 18h 4 ESP 1Ch 4 EBX 20h 4 EDX 24h 4 ECX 28h 4 EAX 2Ch 4 DR6 30h 4 DR7 34h 4 TR (Task Register) 38h 4 LDT 3Ch 4 GS (zero-extended) 40h 4 FS (zero-extended) 44h 4 DS (zero-extended) 48h 4 SS (zero-extended) 4Ch 4 CS (zero-extended) 50h 4 ES (zero-extended) 54h 12 TSS descriptor cache 60h 12 IDT descriptor cache 6Ch 12 GDT descriptor cache 78h 12 LDT descriptor cache 84h 12 GS descriptor cache 90h 12 FS descriptor cache 9Ch 12 DS descriptor cache A8h 12 SS descriptor cache B4h 12 CS descriptor cache C0h 12 ES descriptor cache The descriptor cache entries are: Byte 0 Must be 0 Byte 1 Access-rights byte, like access-rights byte in a descriptor Bytes 2-3 Must be 0 Bytes 4-7 32-bit base address of the segment Bytes 8-11 32-bit segment limit I suggest aliging the table on a page boundary (16 bytes, or lower 4 bits of the offset must be zero). While this is not a requirement for the 386 and 486, it may be a requirement when running on a Pentium (which is probably why a pentium-patch was issued for Windows 95 for running DPMI-DOS programs). Now... something the speed guru's might be interested in... how fast is LOADALL. Well. according to some tests I've done, LOADALL clocks in at about 105 clockcycles on a 386, and 125 on a 486 which is bad. But not so bad if you take into account the usual number of clocks it take to switch from PMode to real and back. RESTRICTIONS LOADALL performs no checking on the values loaded into the registers, so no exception will occur even if an illegal value is loaded. Thus, the processor can potential be put into a strange state. If an illegal descriptor value is set, no exception occurs from the execution of LOADALL. An exception will occur, however, when an access using that descriptor is attempted. LOADALL can be executed in protected mode, but only at the most privileged level (level 0). So when you would want to use LOADALL when a memory manager is installed, you would first have to shut-down the memory manager by issuing a VCPI call to request ring 0 privileges. Tasmaniac / ACiD / HypernovA