1276 lines
No EOL
38 KiB
HTML
1276 lines
No EOL
38 KiB
HTML
<!DOCTYPE html PUBLIC "-//IETF//DTD HTML//EN">
|
|
<!-- saved from url=(0058)http://www.rcollins.org/articles/loadall/tspec_a3_doc.html -->
|
|
<html><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
|
|
|
<meta name="Author" content="Robert R. Collins">
|
|
<meta name="GENERATOR" content="Microsoft FrontPage 2.0">
|
|
<title>The LOADALL Instruction</title>
|
|
</head>
|
|
|
|
<body bgcolor="#FFFFFF" text="#000000" link="#0000EE" vlink="#551A8B" alink="#FF0000">
|
|
|
|
|
|
<table border="0" cellpadding="0" cellspacing="0" width="800"><tbody><tr><td>
|
|
<h1 align="center"><font color="#0000FF">The <i>LOADALL</i>
|
|
Instruction</font></h1>
|
|
|
|
<h1 align="center"><font color="#0000FF">by</font></h1>
|
|
|
|
<h1 align="center"><font color="#0000FF">Robert Collins</font></h1>
|
|
|
|
<hr>
|
|
|
|
<p>Of the few undocumented instructions in the 80286 and 80386
|
|
microprocessors, the <i>LOADALL </i>instruction is the most
|
|
widely known. Nevertheless, very few people understand how to use
|
|
it. Using <i>LOADALL </i>is not as simp)e as merely knowing the <i>LOADALL
|
|
</i>opcode and its format, because knowing how to use <i>LOADALL </i>requires
|
|
a knowledge of many aspects of the CPUs' behavior that are not
|
|
documented in their respective data sheets.</p>
|
|
|
|
<p>The 286 <i>LOADALL </i>is widely known because a 15-page lntel
|
|
confidential document describing its use was given to many
|
|
developers. 286 <i>LOADALL </i>is so commonly used in production
|
|
code that DOS 3.3 (and above) and OS/2 have provisions for using <i>LOADALL
|
|
</i>built in them. Every 386 and 486 BIOS emulates 286 <i>LOADALL
|
|
</i>and even Microsoft CODEVIEW recognizes the 286 <i>LOADALL </i>opcode
|
|
and disassembles it.</p>
|
|
|
|
<p>On the other hand, the 386 <i>LOADALL </i>is not widely known,
|
|
and very few developers even know it exists. In this article, I
|
|
will explain how to use both the 286 and 386 <i>LOADALL </i>instructions
|
|
and present source code to demonstrate the various aspects of CPU
|
|
behavior that become apparent, or can be proven, when using <i>LOADALL.</i></p>
|
|
<!-- Begin Master Table --><div align="center"><center>
|
|
|
|
<table border="0" cellpadding="8" cellspacing="0">
|
|
<tbody><tr>
|
|
<td valign="top" width="60%">Intel originally included <i>LOADALL
|
|
</i>in the CPU mask for testing purposes and In Circuit
|
|
Emulator (ICE) support. As its name implies, <i>LOADALL </i>loads
|
|
all of the CPU registers, including the
|
|
"hidden" software-invisible registers. At the
|
|
completion of a <i>LOADALL </i>instruction, the entire
|
|
CPU state is defined according to the <i>LOADALL </i>data
|
|
table. <i>LOADALL </i>loads all of the software-visible
|
|
registers such as <i>AX, </i>and all of the
|
|
software-invisible registers such as the <a href="http://www.rcollins.org/articles/loadall/tspec_a3_doc.html#SB1" name="SB1Ptr">segment descriptor caches</a>.<p>By
|
|
manipulating the descriptor cache base registers, you can
|
|
access the entire address space without switching to
|
|
protected mode. In other words, by using <i>LOADALL, </i>you
|
|
can access memory above 1Mb from real mode. Since the
|
|
alternative method for the 286 (switching to protected
|
|
mode, accessing the desired memory, then resetting the
|
|
CPU - the only way to get the 286 back to real mode) has
|
|
a significant performance penalty, <i>LOADALL </i>is most
|
|
significant to 286 programmers. <i>LOADALL </i>provides
|
|
them with a new capability that is not available by any
|
|
other means.</p>
|
|
<p><font color="#FF0000" size="5"><b><i>LOADALL </i></b><b>Details</b></font></p>
|
|
<p><i>LOADALL </i>is closely coupled with the CPU
|
|
hardware. Both the 286 and 386 have different internal
|
|
hardware and Intel implemented <i>LOADALL </i>using
|
|
different opcodes on the 286 and 386. 80286 <i>LOADALL </i>(opcode
|
|
0F05) produces an invalid opcode exception when executed
|
|
on the 386, and 80386 <i>LOADALL </i>(opcode 0F07)
|
|
produces an invalid opcode exception when executed on the
|
|
286.</p>
|
|
<p><i>LOADALL </i>loads all CPU registers (including <i>MSW,
|
|
GDTR, CSBASE, ESACCESS) </i>from a memory image. You can
|
|
execute <i>LOADALL </i>in real or protected mode, but
|
|
only at privilege level 0 (CPL=0). If you execute <i>LOADALL
|
|
</i>at any other privilege level, the CPU generates an
|
|
exception.</p>
|
|
<p>By directly loading the descriptor cache registers
|
|
with <i>LOADALL, </i>a program has explicit control over
|
|
the base address, segment limit, and access rights
|
|
associated with each memory segment. Normally, the CPU
|
|
loads these values each time it loads a segment register,
|
|
but <i>LOADALL </i>allows you to load these hidden
|
|
registers independently of their segment register
|
|
counterparts.</p>
|
|
<p>In real mode, <i>LOADALL </i>makes it possible to
|
|
access a memory segment that is not associated with any
|
|
segment register. Likewise in protected mode, you can
|
|
access memory that has no descriptor table entry.</p>
|
|
<p><i>LOADALL </i>performs no protection checks against
|
|
any of the loaded register values. When you execute it at
|
|
<i>CPL 0, LOADALL </i>can generate no exceptions. The
|
|
segment access rights and limit portions may be values
|
|
that would otherwise be illegal in the context of real
|
|
mode or protected mode, but <i>LOADALL </i>willingly
|
|
loads these values with no checks. Once loaded, however,
|
|
the CPU performs full access checks when accessing a
|
|
segment. For example, you can load a segment whose access
|
|
is marked "not present." Normally, this
|
|
condition would generate exception 11, "segment not
|
|
present", but <i>LOADALL </i>does not generate
|
|
exception 11. Instead, any attempt to access this segment
|
|
will generate exception 13.</p>
|
|
<p><i>LOADALL </i>does not check coherency between the
|
|
software-visible segment registers and the
|
|
software-invisible segment descriptor cache registers.
|
|
Any segment descriptor base register may point to any
|
|
area in the CPU address space, while the software-visible
|
|
segment register may contain any other arbitrary value.
|
|
The CPU makes all memory references according to the
|
|
descriptor cache registers, not the software-visible
|
|
segment registers. All subsequent segment register loads
|
|
will reload the descriptor cache register. Beware of
|
|
using values in CS that do not perfectly match a code
|
|
segment descriptor table entry, or a real mode code
|
|
segment - an interrupt return <i>(IRET) </i>may either
|
|
cause an exception or execution to resume at an
|
|
unexpected location. Likewise, pushing and subsequently
|
|
popping any segment register will force the descriptor
|
|
cache register to reload according to the CPU's
|
|
conventional protocol, thereby inhibiting any further
|
|
real mode extended memory references.</p>
|
|
<p><font color="#FF0000" size="5"><b>80286 </b><b><i>LOADALL</i></b></font></p>
|
|
<p>You encode the 80286 <i>LOADALL </i>as a two-byte
|
|
opcode, 0F05h. <i>LOADALL </i>reads its table from a
|
|
fixed memory location at 800h (80:0 in real-mode
|
|
addressing). <i>LOADALL </i>performs 51 bus cycles <i>(WORD
|
|
</i>cycles), and takes 195 clocks with no wait states. <a href="http://www.rcollins.org/articles/loadall/tspec_a3_doc.html#Tbl1">Table 1</a> shows the format you must
|
|
prepare at location 800h before executing the 286 <i>LOADALL
|
|
</i>instruction. All CPU register entries in the <i>LOADALL
|
|
</i>table conform to the standard Intel format, where the
|
|
least significant byte is at the lowest memory address. <a href="http://www.rcollins.org/articles/loadall/tspec_a3_doc.html#Tbl2a">Table 2</a> shows the 286 format of the
|
|
descriptor cache entries.</p>
|
|
<p><br>
|
|
</p>
|
|
<p><!-- Begin "Table 1" in column 1 of Master Table --> </p>
|
|
<div align="center"><center><table border="0" cellpadding="12" cellspacing="0">
|
|
<caption align="top"><a name="Tbl1"></a><strong>
|
|
Table 1 -- 80286 </strong><strong><i>LOADALL</i></strong><strong>
|
|
Table</strong></caption>
|
|
<tbody><tr>
|
|
<th valign="bottom">Physical Address</th>
|
|
<th valign="bottom">Description</th>
|
|
<th valign="bottom">Data Size</th>
|
|
<th valign="bottom">Data Value</th>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top"><p align="center">[800] <br>
|
|
[802]<br>
|
|
[804]<br>
|
|
[806]<br>
|
|
[808]<br>
|
|
[80A]<br>
|
|
[80C]<br>
|
|
[80E]<br>
|
|
[810]<br>
|
|
[812]<br>
|
|
[814]<br>
|
|
[816]<br>
|
|
[818]<br>
|
|
[81A]<br>
|
|
[81C]<br>
|
|
[81E]<br>
|
|
[820]<br>
|
|
[822]<br>
|
|
[824]<br>
|
|
[826]<br>
|
|
[828]<br>
|
|
[82A]<br>
|
|
[82C]<br>
|
|
[82E]<br>
|
|
[830]<br>
|
|
[832]<br>
|
|
[834]<br>
|
|
[836]<br>
|
|
[83C]<br>
|
|
[842]<br>
|
|
[848]<br>
|
|
[84E]<br>
|
|
[854]<br>
|
|
[85A]<br>
|
|
[860]<br>
|
|
[866] </p>
|
|
</td>
|
|
<td valign="top">None<br>
|
|
None<br>
|
|
MSW<br>
|
|
None<br>
|
|
None<br>
|
|
None<br>
|
|
None<br>
|
|
None<br>
|
|
None<br>
|
|
None<br>
|
|
None<br>
|
|
TR_REG<br>
|
|
FLAGS<br>
|
|
IP<br>
|
|
LDT_REG<br>
|
|
DS_REG<br>
|
|
SS_REG<br>
|
|
CS_REG<br>
|
|
ES_REG<br>
|
|
DI<br>
|
|
SI<br>
|
|
BP<br>
|
|
SP<br>
|
|
BX<br>
|
|
DX<br>
|
|
CX<br>
|
|
AX<br>
|
|
ES_DESC<br>
|
|
CS_DESC<br>
|
|
SS_DESC<br>
|
|
DS_DESC<br>
|
|
GDT_DESC<br>
|
|
LDT_DESC<br>
|
|
IDT_DESC<br>
|
|
TSS_DESC<br>
|
|
ENT OF TABLE</td>
|
|
<td align="center" valign="top">DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DW<br>
|
|
DESC_CACHE286<br>
|
|
DESC_CACHE286<br>
|
|
DESC_CACHE286<br>
|
|
DESC_CACHE286<br>
|
|
DESC_CACHE286<br>
|
|
DESC_CACHE286<br>
|
|
DESC_CACHE286<br>
|
|
DESC_CACHE286<br>
|
|
</td>
|
|
<td align="center" valign="top">0<br>
|
|
0<br>
|
|
0<br>
|
|
?<br>
|
|
0<br>
|
|
0<br>
|
|
0<br>
|
|
0<br>
|
|
0<br>
|
|
0<br>
|
|
0<br>
|
|
?<br>
|
|
?<br>
|
|
?<br>
|
|
?<br>
|
|
?<br>
|
|
?<br>
|
|
?<br>
|
|
?<br>
|
|
?<br>
|
|
?<br>
|
|
?<br>
|
|
?<br>
|
|
?<br>
|
|
?<br>
|
|
?<br>
|
|
?<br>
|
|
<?,?,?><br>
|
|
<?,?,?><br>
|
|
<?,?,?><br>
|
|
<?,?,?><br>
|
|
<?,?,?><br>
|
|
<?,?,?><br>
|
|
<?,?,?><br>
|
|
<?,?,?><br>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="4"><pre><font size="4">DESC_CACHE286 STRUC
|
|
Addr_A15_A00 DW ?
|
|
Addr_A23_A16 DB ?
|
|
Access DB ?
|
|
Limit DW ?
|
|
ENDS</font></pre>
|
|
</td>
|
|
</tr>
|
|
</tbody></table>
|
|
</center></div><p><!-- End "Table 1" within column 1 of Master Table --> Intel recommends some guidelines for
|
|
proper execution following <i>LOADALL. </i>The stack
|
|
segment should be a read/write data segment; the code
|
|
segment can be execute on1y (access=95h), read/execute
|
|
(access=9bh), or read/write/execute (access=93h). Proper
|
|
protected mode operation also requires that the DPL of <i>CS
|
|
</i>and DPL of <i>SS </i>be equal. These attributes
|
|
determine the CPL of the processor. Also, the DPL fields
|
|
of <i>ES </i>and <i>DS </i>should be equal to 3 to
|
|
prevent <i>RETF </i>or <i>IRET </i>instructions from
|
|
zeroing these registers. </p>
|
|
<p>The code in <a href="http://www.rcollins.org/ftp/source/286load/286load.asm">listing 1</a>
|
|
demonstrates how to exp1ore the various operating modes
|
|
with 286 <i>LOADALL </i>and how to access extended memory
|
|
while in real mode. The <i>LOADALL </i>test performs
|
|
various functions that would be impossible to duplicate
|
|
without using <i>LOADALL.</i></p>
|
|
<p><font color="#FF0000" size="5"><b>80386 </b><b><i>LOADALL</i></b></font></p>
|
|
<p>The 386 LOADALL is encoded as a two-byte opcode
|
|
(0F07). Unlike the 286 LOADALL, this LOADALL instruction
|
|
reads its data from a table pointed to by ES:EDI. Segment
|
|
overrides are allowed, but apparently ignored. The 386
|
|
LOADALL performs 51 bus cycles (DWORD cycles) and takes
|
|
122 clocks with no wait states. Table 3 shows the 386
|
|
LOADALL format. However, <a href="http://www.rcollins.org/articles/loadall/tspec_a3_doc.html#Tbl3">Table 3</a> does
|
|
not show that prior to reading the LOADALL table, LOADALL
|
|
reads 10 DWORDs exactly 100h bytes beyond the beginning
|
|
of the table (ES:EDI+100h). This data is not used to load
|
|
any of the registers LOADALL does not load (CR2, CR3,
|
|
DRO-DR3, TR6, TR7), or the Numeric Processor eXtension
|
|
(NPX). At this time, the purpose of reading this data and
|
|
its destination is a mystery. Figure 1 shows an ICE trace
|
|
showing all the bus cycles associated with LOADALL's
|
|
execution.</p>
|
|
<p>As with the 286 LOADALL, all CPU register entries in
|
|
the LOADALL table are in the standard Intel format where
|
|
the least significant byte is at the lowest memory
|
|
address. The 386 descriptor cache entries have the format
|
|
shown in <a href="http://www.rcollins.org/articles/loadall/tspec_a3_doc.html#Tbl4">Table 4</a>.</p>
|
|
<p><a href="http://www.rcollins.org/ftp/source/386load/386load.asm">Listing
|
|
2</a> shows how to test 386 LOADALL. This test is more
|
|
comprehensive than the 286 LOADALL test because of the
|
|
expanded capabilities of the 386 microprocessor. This
|
|
test puts the CPU into various states that are illegal
|
|
and are impossible to duplicate through any other
|
|
software means.</p>
|
|
<p><font color="#FF0000" size="5"><b><i>LOADALL </i></b><b>Emulation</b></font></p>
|
|
<p>Due to the large number of systems programs that use
|
|
286 <i>LOADALL, </i>all 386 and 486 BIOS's must emu1ate
|
|
the 286 <i>LOADALL </i>instruction (opcode 0<i>F05). </i>On
|
|
the 386 and 486, the 286 <i>LOADALL </i>instruction
|
|
generates an invalid opcode exception. The BIOS traps
|
|
this exception and does its best to emulate the
|
|
functionality of the <i>LOADALL </i>instruction, but
|
|
perfect emulation is impossible without using <i>LOADALL </i>itself.
|
|
Using 386 <i>LOADALL </i>to emulate 286 <i>LOADALL </i>can
|
|
be done, but has its risks. First of all, the 486 does
|
|
not have a <i>LOADALL </i>instruction. Second, Intel has
|
|
threatened to remove <i>LOADALL </i>from the 386 mask.</p>
|
|
<p>Perfect emulation is possible on the 386 by using 386 <i>LOADALL
|
|
</i>to emulate 286 <i>LOADALL. </i><a href="http://www.rcollins.org/ftp/source/emuload/emuload.asm">Listing 3</a>
|
|
shows a TSR program that uses 386 <i>LOADALL </i>to
|
|
emulate 286 <i>LOADALL. </i>The program first tests that
|
|
you are a 386 before insta1ling itself. By using this
|
|
emu1ation program, you can guarantee perfect 286 <i>LOADALL
|
|
</i>emulation.</p>
|
|
<p><font color="#FF0000" size="5"><b>Conclusion</b></font></p>
|
|
<p><i>LOADALL </i>is a very powerful instruction, but the
|
|
features that make it so powerful also make it risky. For
|
|
example, <i>LOADALL </i>can put the processor in states
|
|
that are otherwise impossible to duplicate through any
|
|
other software means. Using <i>LOADALL </i>requires a
|
|
thorough understanding of how the CPU processes register
|
|
loads, the ramifications of those register loads, and
|
|
careful planning. The illegally induced processor states
|
|
can easily cause system crashes if not properly planned
|
|
for. The best way to avoid system crashes is to avoid
|
|
using <i>LOADALL </i>unless you are totally confident in
|
|
your understanding of the CPU and in your programming
|
|
skills.</p>
|
|
<p>The 286 <i>LOADALL </i>is described in a 15-page
|
|
Intel-confidential document The document describes in
|
|
detail how to use the instruction, and also describes
|
|
many of its possible uses. <i>LOADALL </i>can be used to
|
|
access extended memory while in real mode, and to emulate
|
|
real mode while in protected mode. Programs such as
|
|
RAMDRIVE, ABOVEDISC, and OS/2 use <i>LOADALL. </i>DOS 3.3
|
|
has provisions for using <i>LOADALL </i>by leaving a
|
|
102-byte 'hole' at 80:0. If you are a systems programmer
|
|
and have a need to know this information, Intel will
|
|
provide it, along with source code to emulate 286 <i>LOADALL
|
|
</i>on the 386 (without using 386 <i>LOADALL).</i></p>
|
|
<p>Unlike the 286 <i>LOADALL, </i>the 386 <i>LOADALL </i>is
|
|
still an Intel top secret. l do not know of any document
|
|
that describes its use, format, or acknowledges its
|
|
existence. Very few people at Intel wil1 acknowledge that
|
|
<i>LOADALL </i>even exists in the 80386 mask. The
|
|
official Intel line is that, due to U.S. Military
|
|
pressure, <i>LOADALL </i>was removed from the 80386 mask
|
|
over a year ago. However, running the program in
|
|
Listing-2 demonstrates that <i>LOADALL </i>is alive,
|
|
well, and still available on the latest stepping of the
|
|
80386.</p>
|
|
<hr>
|
|
|
|
<p align="left">View source code for 286 LOADALL:<br>
|
|
<a href="http://www.rcollins.org/ftp/source/286load/286load.asm">ftp://ftp.x86.org/source/286load/286load.asm<br>
|
|
</a><a href="http://www.rcollins.org/ftp/source/286load/loadfns.286">ftp://ftp.x86.org/source/286load/loadfns.286<br>
|
|
</a><a href="http://www.rcollins.org/ftp/source/286load/macros.286">ftp://ftp.x86.org/source/286load/macros.286<br>
|
|
</a><a href="http://www.rcollins.org/ftp/source/include/cpu_type.asm">ftp://ftp.x86.org/source/include/cpu_type.asm</a></p>
|
|
|
|
<p align="left">View source code for 386 LOADALL:<br>
|
|
<a href="http://www.rcollins.org/ftp/source/386load/386load.asm">ftp://ftp.x86.org/source/386load/386load.asm<br>
|
|
</a><a href="http://www.rcollins.org/ftp/source/386load/loadfns.386">ftp://ftp.x86.org/source/386load/loadfns.386<br>
|
|
</a><a href="http://www.rcollins.org/ftp/source/386load/macros.386">ftp://ftp.x86.org/source/386load/macros.386<br>
|
|
</a><a href="http://www.rcollins.org/ftp/source/include/cpu_type.asm">ftp://ftp.x86.org/source/include/cpu_type.asm</a></p>
|
|
|
|
<p align="left">View source code for EMULOAD (286 LOADALL
|
|
emulation using 386 LOADALL):<br>
|
|
<a href="http://www.rcollins.org/ftp/source/emuload/emuload.asm">ftp://ftp.x86.org/source/emuload/emuload.asm<br>
|
|
</a><a href="http://www.rcollins.org/ftp/source/include/cpu_type.asm">ftp://ftp.x86.org/source/include/cpu_type.asm</a></p>
|
|
|
|
<p align="left">Download entire source code archive for 286LOAD,
|
|
386LOAD, and EMULOAD:<br>
|
|
<a href="http://www.rcollins.org/ftp/dloads/LOADALL.ZIP">ftp://ftp.x86.org/dloads/LOADALL.ZIP</a></p>
|
|
|
|
</td>
|
|
<!-- End column 1 in Master Table --><!-- Begin Column 2 in Master Table --> <td valign="top" width="40%">
|
|
<!-- Begin Sidebar 1 -->
|
|
<!--#exec cmd="/usr/www/users/rcollins/cgi-bin/include.cgi -i/usr/www/users/rcollins/articles/loadall/tspec_a3_sb1.html" -->
|
|
<!-- End Sidebar 1 --> <hr>
|
|
<!-- Begin "Table 2(a)" --> <p></p>
|
|
<div align="center"><center><table border="1" cellpadding="2" cellspacing="0" width="100%">
|
|
<caption align="top"><a name="Tbl2a"></a><strong>
|
|
Table 2 (a) -- 80286 Descriptor Cache Entry Formats </strong></caption>
|
|
<tbody><tr>
|
|
<td align="center"><font size="4"><b>Offset</b></font>
|
|
</td>
|
|
<td><font size="4"><b>Description</b></font></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center">0-2</td>
|
|
<td>24-bit physical address of the segment in
|
|
memory. These bytes are stored in standard Intel
|
|
format with the least significant byte at the
|
|
lowest memory address.</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center">3</td>
|
|
<td>Access rights. The format of this byte is the
|
|
same as that in the descriptor table. This access
|
|
byte is loaded in the descriptor cache register
|
|
regardless of its validity. Therefore the
|
|
"present" bit in the access rights
|
|
field becomes a "descriptor valid" bit.
|
|
When this bit is cleared, the descriptor is
|
|
considered invalid, and any memory reference
|
|
using this descriptor generates exception 13,
|
|
with error code 0. The Descriptor Privilege Level
|
|
(DPL) of the SS and CS descriptor caches
|
|
determines the Current Privilege Level (CPL). The
|
|
CS descriptor cache may be loaded as a read/write
|
|
data segment.</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center">4-5</td>
|
|
<td>Segment limit. The standard 16-bit segment
|
|
limit stored in standard Intel format.</td>
|
|
</tr>
|
|
</tbody></table>
|
|
</center></div><p><!-- End "Table 2(a)" --> <br>
|
|
<br>
|
|
<!-- Begin "Table 2(b)" --> </p>
|
|
<div align="center"><center><table border="1" cellpadding="2" cellspacing="0" width="100%">
|
|
<caption align="top"><a name="Tbl2b"></a><strong>
|
|
Table 2 (b) -- 80286 GDT and IDT Descriptor Cache
|
|
Entry Formats</strong></caption>
|
|
<tbody><tr>
|
|
<td align="center"><font size="4"><b>Offset</b></font></td>
|
|
<td><font size="4"><b>Description</b></font></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center">0-2</td>
|
|
<td>24-bit physical address of the segment in
|
|
memory.</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center">3</td>
|
|
<td>Should be 0.</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center">4-5</td>
|
|
<td>Segment limit.</td>
|
|
</tr>
|
|
</tbody></table>
|
|
</center></div><p><!-- End "Table 2(b)" --> </p><hr>
|
|
<!-- Begin "Table 3" --> <p></p>
|
|
<div align="center"><center><table border="0" cellpadding="8" cellspacing="0">
|
|
<caption align="top"><a name="Tbl3"></a><strong>
|
|
Table 3 -- 80386 </strong><strong><b><i>LOADALL</i></b></strong><strong>
|
|
Table </strong></caption>
|
|
<tbody><tr>
|
|
<th valign="bottom">Offset</th>
|
|
<th valign="bottom">Description</th>
|
|
<th valign="bottom">Data Size</th>
|
|
<th valign="bottom">Data Value</th>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top"><p align="center">[00] <br>
|
|
[04]<br>
|
|
[08]<br>
|
|
[0C]<br>
|
|
[10]<br>
|
|
[14]<br>
|
|
[18]<br>
|
|
[1C]<br>
|
|
[20]<br>
|
|
[24]<br>
|
|
[28]<br>
|
|
[2C]<br>
|
|
[30]<br>
|
|
[34]<br>
|
|
[38]<br>
|
|
[3C]<br>
|
|
[40]<br>
|
|
[44]<br>
|
|
[48]<br>
|
|
[4C]<br>
|
|
[50]<br>
|
|
[54]<br>
|
|
[60]<br>
|
|
[6C]<br>
|
|
[78]<br>
|
|
[84]<br>
|
|
[90]<br>
|
|
[9C]<br>
|
|
[A8]<br>
|
|
[B4]<br>
|
|
[C0]<br>
|
|
[CC] </p>
|
|
</td>
|
|
<td valign="top">CR0<br>
|
|
EFLAGS<br>
|
|
EIP<br>
|
|
EDI<br>
|
|
ESI<br>
|
|
EBP<br>
|
|
ESP<br>
|
|
EBX<br>
|
|
EDX<br>
|
|
ECX<br>
|
|
EAX<br>
|
|
DR6<br>
|
|
DR7<br>
|
|
TR_REG<br>
|
|
LDT_REG<br>
|
|
GS_REG<br>
|
|
FS_REG<br>
|
|
DS_REG<br>
|
|
SS_REG<br>
|
|
CS_REG<br>
|
|
ES_REG<br>
|
|
TSS_DESC<br>
|
|
IDT_DESC<br>
|
|
GDT_DESC<br>
|
|
LDT_DESC<br>
|
|
GS_DESC<br>
|
|
FS_DESC<br>
|
|
DS_DESC<br>
|
|
SS_DESC<br>
|
|
CS_DESC<br>
|
|
ES_DESC<br>
|
|
LENGTH OF TABLE</td>
|
|
<td align="center" valign="top">DD<br>
|
|
DD<br>
|
|
DD<br>
|
|
DD<br>
|
|
DD<br>
|
|
DD<br>
|
|
DD<br>
|
|
DD<br>
|
|
DD<br>
|
|
DD<br>
|
|
DD<br>
|
|
DD<br>
|
|
DD<br>
|
|
REG_STRUC<br>
|
|
REG_STRUC<br>
|
|
REG_STRUC<br>
|
|
REG_STRUC<br>
|
|
REG_STRUC<br>
|
|
REG_STRUC<br>
|
|
REG_STRUC<br>
|
|
REG_STRUC<br>
|
|
DESC_CACHE<br>
|
|
DESC_CACHE<br>
|
|
DESC_CACHE<br>
|
|
DESC_CACHE<br>
|
|
DESC_CACHE<br>
|
|
DESC_CACHE<br>
|
|
DESC_CACHE<br>
|
|
DESC_CACHE<br>
|
|
DESC_CACHE<br>
|
|
DESC_CACHE<br>
|
|
</td>
|
|
<td align="center" valign="top">?<br>
|
|
?<br>
|
|
?<br>
|
|
?<br>
|
|
?<br>
|
|
?<br>
|
|
?<br>
|
|
?<br>
|
|
?<br>
|
|
?<br>
|
|
?<br>
|
|
?<br>
|
|
<?><br>
|
|
<?><br>
|
|
<?><br>
|
|
<?><br>
|
|
<?><br>
|
|
<?><br>
|
|
<?><br>
|
|
<?><br>
|
|
<?><br>
|
|
<?,?,?><br>
|
|
<?,?,?><br>
|
|
<?,?,?><br>
|
|
<?,?,?><br>
|
|
<?,?,?><br>
|
|
<?,?,?><br>
|
|
<?,?,?><br>
|
|
<?,?,?><br>
|
|
<?,?,?><br>
|
|
<?,?,?><br>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" colspan="2"><pre><font size="4">REG_STRUC STRUC
|
|
REG_VAL DW ?
|
|
DW 0
|
|
ENDS</font></pre>
|
|
</td>
|
|
<td colspan="2"><pre><font size="4">DESC_CACHE STRUC
|
|
DB 0
|
|
_Type DB ?
|
|
DB 0
|
|
DB 0
|
|
_Addr DD ?
|
|
_Limit DD ?
|
|
ENDS</font></pre>
|
|
</td>
|
|
</tr>
|
|
</tbody></table>
|
|
</center></div><p><!-- End "Table 3" --> </p><hr>
|
|
<!-- Begin "Table 4(a)" --> <p></p>
|
|
<div align="center"><center><table border="1" cellpadding="3" cellspacing="0" width="100%">
|
|
<caption align="top"><a name="Tbl4"></a><strong>
|
|
Table 4 (a) -- 80386 Descriptor Cache Entries </strong></caption>
|
|
<tbody><tr>
|
|
<td align="center"><font size="4"><b>Offset</b></font>
|
|
</td>
|
|
<td><font size="4"><b>Description</b></font></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center">0-3 </td>
|
|
<td>Access rights. The access rights dword
|
|
consumes 11 bits of this 32-bit field. See <a href="http://www.rcollins.org/articles/loadall/tspec_a3_doc.html#Fig2b" name="F2Ptr">figure 2</a> for a
|
|
complete description of this field.</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center">4-7 </td>
|
|
<td>32-bit base address of the segment in
|
|
memory..</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center">8-11 </td>
|
|
<td>32-bit base address of the segment in memory.</td>
|
|
</tr>
|
|
</tbody></table>
|
|
</center></div><p><!-- End "Table 4(a)" --> <br>
|
|
<br>
|
|
<!-- Begin "Table 4(b)" --> </p>
|
|
<div align="center"><center><table border="1" cellpadding="3" cellspacing="0" width="100%">
|
|
<caption align="top"><strong>Table 4 (b) -- 80386 GDT
|
|
and IDT Descriptor Cache Entry Formats </strong></caption>
|
|
<tbody><tr>
|
|
<td align="center"><font size="4"><b>Offset</b></font>
|
|
</td>
|
|
<td><font size="4"><b>Description</b></font></td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center">0-3 </td>
|
|
<td>Should be 0.</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center">4-7 </td>
|
|
<td>32-bit base address of GDTR or IDTR.</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center">8-11 </td>
|
|
<td>32-bit limit of GDTR or IDTR.</td>
|
|
</tr>
|
|
</tbody></table>
|
|
</center></div><p><!-- End "Table 4(b)" --> </p>
|
|
|
|
<hr>
|
|
|
|
<!-- Begin "Figure 1" -->
|
|
<div align="center"><center>
|
|
|
|
<table border="0" cellpadding="3" cellspacing="0">
|
|
<caption align="top"><strong>Figure 1 -- In-Circuit-Emulator
|
|
Trace of 80386 </strong><em><strong>LOADALL</strong></em><strong>
|
|
Instruction</strong></caption>
|
|
<tbody><tr>
|
|
<td valign="top"><font size="2"><strong>Frame</strong></font></td>
|
|
<td valign="top" colspan="3"><font size="2">The FRAME
|
|
number is like a clock count for the CPU. At every CPU
|
|
clock, the ICE takes a picture. When a valid cycle
|
|
occurs, the ICE records its occurance. Therefore, it is
|
|
possible to determine how many CPU clocks a sequence of
|
|
instructions takes to execute by reading this
|
|
information.</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top"><font size="2"><strong>Type</strong></font></td>
|
|
<td valign="top" colspan="3"><font size="2">Cycle type.
|
|
Shown here are F=Fetch, R=Read, and X=eXecute.</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top"><font size="2"><strong>Address</strong></font></td>
|
|
<td valign="top" colspan="3"><font size="2">The 32-bit
|
|
physical address asserted on the CPU address bus during
|
|
each cycle.</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top"><font size="2"><strong>Data</strong></font></td>
|
|
<td colspan="3"><font size="2">The data asserted on the
|
|
CPU data bus during each cycle.</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td><font size="2"><strong>BE3#<br>
|
|
BE2#<br>
|
|
BE1#<br>
|
|
BE0#</strong></font></td>
|
|
<td colspan="3"><font size="2">Byte enable pins on the
|
|
CPU. These pins determine which bytes of the 32-bits of
|
|
data are valid. These pins are active low, so 8-bits of
|
|
data are valid for each '0.'</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td><font size="2"><strong>W/R#</strong></font></td>
|
|
<td><font size="2">Write/Read.</font></td>
|
|
<td><font size="2">Write = 1</font></td>
|
|
<td><font size="2">Read = 0</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td><font size="2"><strong>D/C#</strong></font></td>
|
|
<td><font size="2">Data/Code.</font></td>
|
|
<td><font size="2">Data = 1</font></td>
|
|
<td><font size="2">Code = 0</font></td>
|
|
</tr>
|
|
<tr>
|
|
<td><font size="2"><strong>M/IO#</strong></font></td>
|
|
<td><font size="2">Memory/IO</font></td>
|
|
<td><font size="2">Memory = 1</font></td>
|
|
<td><font size="2">IO = 0</font></td>
|
|
</tr>
|
|
</tbody></table>
|
|
<table border="0" cellpadding="5" cellspacing="0">
|
|
<tbody><tr>
|
|
<td align="center" valign="bottom"><pre><font size="2"><tt>Frame
|
|
Dec</tt></font><font face="Courier New"> </font></pre>
|
|
</td>
|
|
<td align="center" valign="bottom"><pre><font size="2" face="Courier New">Type</font><font face="Courier New"> </font></pre>
|
|
</td>
|
|
<td align="center" valign="bottom"><pre><font size="2" face="Courier New">Address
|
|
(Hex)</font><font face="Courier New"> </font></pre>
|
|
</td>
|
|
<td align="center" valign="bottom"><pre><font size="2" face="Courier New">Data
|
|
(Hex)</font><font face="Courier New"> </font></pre>
|
|
</td>
|
|
<td align="center" valign="bottom"><pre><font size="2" face="Courier New">BBBB
|
|
EEEE
|
|
3210
|
|
####</font><font face="Courier New"> </font></pre>
|
|
</td>
|
|
<td align="center" valign="bottom"><pre><font size="2">WDM
|
|
///
|
|
RCI
|
|
O
|
|
###</font></pre>
|
|
</td>
|
|
<td valign="bottom"><pre><font size="2">Comments</font></pre>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center" valign="top"><pre><font size="2"><tt>5
|
|
8
|
|
011
|
|
013
|
|
015
|
|
017
|
|
019
|
|
021
|
|
023
|
|
025
|
|
027
|
|
029
|
|
031
|
|
033
|
|
035
|
|
037
|
|
039
|
|
041
|
|
043
|
|
045
|
|
047
|
|
049
|
|
051
|
|
053
|
|
055
|
|
057
|
|
059
|
|
061
|
|
063
|
|
065
|
|
067
|
|
069
|
|
071
|
|
073
|
|
075
|
|
077
|
|
079
|
|
081
|
|
083
|
|
085
|
|
087
|
|
089
|
|
091
|
|
093
|
|
095
|
|
097
|
|
099
|
|
101
|
|
103
|
|
105
|
|
107
|
|
109
|
|
111
|
|
113
|
|
115
|
|
117
|
|
119
|
|
121
|
|
123
|
|
125
|
|
127
|
|
129
|
|
131</tt></font></pre>
|
|
</td>
|
|
<td align="center" valign="top"><pre><font size="2">F
|
|
X
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R
|
|
R</font></pre>
|
|
</td>
|
|
<td align="center" valign="top"><pre><font size="2">0000DE40
|
|
executed
|
|
0000D8F0
|
|
0000D8F4
|
|
0000D8F8
|
|
0000D8FC
|
|
0000D900
|
|
0000D904
|
|
0000D908
|
|
0000D90C
|
|
0000D910
|
|
0000D914
|
|
0000D7F0
|
|
0000D7F4
|
|
0000D7F8
|
|
0000D7FC
|
|
0000D800
|
|
0000D804
|
|
0000D808
|
|
0000D80C
|
|
0000D810
|
|
0000D814
|
|
0000D818
|
|
0000D81C
|
|
0000D820
|
|
0000D824
|
|
0000D828
|
|
0000D82C
|
|
0000D830
|
|
0000D834
|
|
0000D838
|
|
0000D83C
|
|
0000D840
|
|
0000D844
|
|
0000D848
|
|
0000D84C
|
|
0000D850
|
|
0000D854
|
|
0000D858
|
|
0000D85C
|
|
0000D860
|
|
0000D864
|
|
0000D868
|
|
0000D86C
|
|
0000D870
|
|
0000D874
|
|
0000D878
|
|
0000D87C
|
|
0000D880
|
|
0000D884
|
|
0000D888
|
|
0000D88C
|
|
0000D890
|
|
0000D894
|
|
0000D898
|
|
0000D89C
|
|
0000D8A0
|
|
0000D8A4
|
|
0000D8A8
|
|
0000D8AC
|
|
0000D8B0
|
|
0000D8B4
|
|
0000D8B8</font></pre>
|
|
</td>
|
|
<td align="center" valign="top"><pre><font size="2">B490070F
|
|
2bytes
|
|
01010101
|
|
02020202
|
|
03030303
|
|
04040404
|
|
05050505
|
|
06060606
|
|
07070707
|
|
08080808
|
|
09090909
|
|
0A0A0A0A
|
|
7FFFFFE0
|
|
00000002
|
|
00000133
|
|
66666666
|
|
77777777
|
|
55555555
|
|
88888888
|
|
22222222
|
|
44444444
|
|
33333333
|
|
11111111
|
|
FFFF0FF0
|
|
0000D402
|
|
xxxx0000
|
|
xxxx0000
|
|
xxxx5555
|
|
xxxx4444
|
|
xxxx2222
|
|
xxxx6666
|
|
xxxx1111
|
|
xxxx3333
|
|
00008900
|
|
00070000
|
|
00000800
|
|
00000000
|
|
00000000
|
|
000003FF
|
|
00000000
|
|
00000000
|
|
00000000
|
|
00008200
|
|
00090000
|
|
00000088
|
|
00008300
|
|
00050000
|
|
0000FFFF
|
|
00009300
|
|
00040000
|
|
0000FFFF
|
|
00009300
|
|
00020000
|
|
0000FFFF
|
|
00009300
|
|
00060000
|
|
0000FFFF
|
|
00009B00
|
|
0000DD30
|
|
0000FFFF
|
|
00009300
|
|
00030000
|
|
00FFFFFF</font></pre>
|
|
</td>
|
|
<td align="center" valign="top"><pre><font size="2">0000
|
|
at
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
1100
|
|
1100
|
|
1100
|
|
1100
|
|
1100
|
|
1100
|
|
1100
|
|
1100
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000
|
|
0000</font></pre>
|
|
</td>
|
|
<td align="center" valign="top"><pre><font size="2">001
|
|
DE40L
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011
|
|
011</font></pre>
|
|
</td>
|
|
<td valign="top"><pre><font size="2">LOADALLfetched
|
|
LOADALLbeginsexecution
|
|
\</font><font size="2" face="Courier New">
|
|
\
|
|
\ The10"mystery"
|
|
\ reads,exactly
|
|
\ 100hbytesbeyond
|
|
/ thebeginningof
|
|
/ theLOADALLtable.
|
|
/
|
|
/
|
|
/
|
|
CR0
|
|
EFLAGS
|
|
EIP
|
|
EDI
|
|
ESI
|
|
EBP
|
|
ESP
|
|
EBX
|
|
EDX
|
|
ECX
|
|
EAX
|
|
DR6
|
|
DR7
|
|
TRRegister
|
|
LDTRegister
|
|
GSRegister
|
|
FSRegister
|
|
DSRegister
|
|
SSRegister
|
|
CSRegister
|
|
ESRegister
|
|
TSSDescriptorCache
|
|
|
|
|
|
IDTDescriptorCache
|
|
|
|
|
|
GDTDescriptorCache
|
|
|
|
|
|
LDTDescriptorCache
|
|
|
|
|
|
GSDescriptorCache
|
|
|
|
|
|
FSDescriptorCache
|
|
|
|
|
|
DSDescriptorCache
|
|
|
|
|
|
SSDescriptorCache
|
|
|
|
|
|
CSDescriptorCache
|
|
|
|
|
|
ESDescriptorCache
|
|
|
|
</font></pre>
|
|
</td>
|
|
</tr>
|
|
</tbody></table>
|
|
</center></div>
|
|
|
|
<!-- End "Figure 1" -->
|
|
</td>
|
|
</tr>
|
|
</tbody></table>
|
|
</center></div>
|
|
|
|
|
|
<hr>
|
|
|
|
<p align="left"><a href="http://www.rcollins.org/articles/articles.html#LOADALLPtr">Back to
|
|
Books and Articles home page</a></p>
|
|
<!--#exec cmd="/usr/www/users/rcollins/cgi-bin/StdDisclaimer.cgi" -->
|
|
</td></tr></tbody></table>
|
|
|
|
|
|
</body></html> |