From: James Harris on
I've always found the many different types of 32-bit x86 descriptors
and their fields hard to remember and distinguish. For my own use I've
put together some notes to help me recall their fields and identify
the forms. In case anyone else finds the document useful it is at

http://codewiki.wikispaces.com/x86+descriptors

and there is a linked page on the type codes used.

It may have some inaccuracies as I've just finished it (check the
manuals to be sure) but I think it's a useful breakdown to help
demystify these awkward structures. It's not light reading as there's
a lot in a short space and it may be best read in stages.

Some interesting things have come out that I didn't know. For example,
there are only two fundamental descriptor forms, one for blocks of
memory and one for points in memory. The blocks of memory descriptor
form includes all the memory segment types plus some System types -
those for LDT and TSS blocks. And the points of memory are all gates.
Simple!

As ever, corrections welcome. Also, I've included only 32-bit data.
Should I add 64-bit data to it or will that overload it with too much
information?

James
From: Stargazer on
On Jun 26, 3:36 am, James Harris <james.harri...(a)googlemail.com>
wrote:
> I've always found the many different types of 32-bit x86 descriptors
> and their fields hard to remember and distinguish. For my own use I've
> put together some notes to help me recall their fields and identify
> the forms. In case anyone else finds the document useful it is at
>
>  http://codewiki.wikispaces.com/x86+descriptors
>
> and there is a linked page on the type codes used.
>
> It may have some inaccuracies as I've just finished it (check the
> manuals to be sure) but I think it's a useful breakdown to help
> demystify these awkward structures. It's not light reading as there's
> a lot in a short space and it may be best read in stages.

In my opinion, x86 descriptors are more awkward than, say SPRs or
segment descriptors on PowerPC or cp0 registers with 0 to 3 "selects"
per register on MIPS. All more or less mature architectures have their
bunch of awkwardness due to past and future compatibility issues
and... many attempts to simplify/generalize things (don't laugh).

> Some interesting things have come out that I didn't know. For example,
> there are only two fundamental descriptor forms, one for blocks of
> memory and one for points in memory. The blocks of memory descriptor
> form includes all the memory segment types plus some System types -
> those for LDT and TSS blocks. And the points of memory are all gates.
> Simple!

I think that Intel manuals also refer to two types of descriptors, but
call them "segment" and "gate" descriptors (or it was in earlier
documents, I didn't check that recently). I would also suggest that
your terminology choice is bad even for your own memorizing.

First, the architecture definition also refers to two types of
descriptors, but calls them with different name; you must have some
good reason to suggest a different pair of names which would require
you then remember both pairs and correspondence between them in order
to look up things in specs.

Second, if you wanted to ease remembering you ought to choose more
"talkative" (not even descriptive names) - names that would remind you
the things as they are. "Blocks" have too many options to mix up
(besides segments, MTRR-defined ranges may be refered as "blocks";
pages or page tables may be thought of as "blocks", etc.) Everything
in your "blocks" group is a segment except for LDT, so "segments" or
"segments and tables" may be a better replacement name. "Points" are
better hinting, but apparently not in a way that you assumed, or at
least your definition of "points" is misleading: it's not "points in
memory", but "system entry points"! As such "points" may be more
descriptive than "gates".

> As ever, corrections welcome.

One thing that comes to mind is regarding limits. Unless Intel added a
special treatment for 0-limited segments recently, the limit for 4K-
granular segments is 2**12-1 .. 2**32-1, not 0 .. 2**32-1.

> Also, I've included only 32-bit data.
> Should I add 64-bit data to it or will that overload it with too much
> information?

No (64-bit data belongs to a different architecture), but I think you
should add 16-bit specifications.

Daniel
From: wolfgang kern on

James Harris posted:

> I've always found the many different types of 32-bit x86 descriptors
> and their fields hard to remember and distinguish. For my own use I've
> put together some notes to help me recall their fields and identify
> the forms. In case anyone else finds the document useful it is at

> http://codewiki.wikispaces.com/x86+descriptors

> and there is a linked page on the type codes used.

Me too found it a bit confusing, so I made myself a quick reference
for 32 bit types (16 bit types seem to vary by one bit only).
I'll add my html-source at the end here.

> It may have some inaccuracies as I've just finished it (check the
> manuals to be sure) but I think it's a useful breakdown to help
> demystify these awkward structures. It's not light reading as there's
> a lot in a short space and it may be best read in stages.

Because I use only 93/9B/8E types, there could be errors in the other
fields I'm not even aware of. Please check and confirm before using.

> Some interesting things have come out that I didn't know. For example,
> there are only two fundamental descriptor forms, one for blocks of
> memory and one for points in memory. The blocks of memory descriptor
> form includes all the memory segment types plus some System types -
> those for LDT and TSS blocks. And the points of memory are all gates.
> Simple!

Yes, but it took me once 'some' time to see it this way :)

> As ever, corrections welcome. Also, I've included only 32-bit data.
> Should I add 64-bit data to it or will that overload it with too much
> information?

IMHO I think 64-bit descriptors would be better an apart story,
the difference to 32 bit will add some confusion anyway.
__
wolfgang
I'm not an expert on html, but it shall be readable at least.

_____source of x86-descriptor.html______________________
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Strict//EN"
"http://www.w3.org/TR/html4/strict.dtd">

<html>
<head>
<!--
copied from the "Holy Book of KESYS" Jan.1999,
Author: Wolfgang Kern, Vienna Austria (LEOC, KESYS-development) >

<title>x86descriptors</title>
<style type="text/css">
<!--
tr {nowrap; }
td {nowrap; align:center; }
-->
</style>
</head>


<body bgcolor="#FFFFFF" text="#000000" align="left">
<basefont face="Lucida Console">
<basefont size="2">

<u><b>x86 Protected Mode Descriptors</caption><b/></u>

<table border="1" frame="box" rules="all" bgcolor="#FFFFFF" height="200"
cellspacing="0" cellpadding="0" bordercolor="#808080">
<colgroup>
<col width="8">
<col width="24" align="middle" span=8>
<col width="200" align="left" valign="top">
</colgroup>

<tr> <td>7</td>
<td colspan="8">BASE 31..24</td>
<td rowspan="9">
<pre><b><u>
DATA [93][GDT,LDT]</b></u>
G 4Kb granular limit
B 32-bit stack
P present
E expand down (stack)
W writable
A accessed</pre>
</td>
</tr>

<tr> <td>6</td>
<td><b>G</td>
<td><b>B</td>
<td><b>0</td>
<td>x</td>
<td nowrap colspan="4">LIM 19..16</td> </tr>

<tr> <td>5</td>
<td>P</td>
<td colspan="2">DPL</td>
<td colspan="2" style="border-width:medium;border-color:#000000;
border-style:double;">
<b>1 0</td>
<td><b>E</td>
<td><b>W</td>
<td><b>A</td> </tr>

<tr> <td>4</td>
<td rowspan="3" colspan="8">BASE 0..23</td> </tr>

<tr> <td>3</td></tr>

<tr> <td>2</td></tr>

<tr> <td>1</td>
<td rowspan="2" colspan="8">LIMIT 0..15</td> </tr>

<tr><td>0</td></tr>

<tr style="font-size:7pt;">
<td></td>
<td>7</td>
<td>6</td>
<td>5</td>
<td>4</td>
<td>3</td>
<td>2</td>
<td>1</td>
<td>0</td> </tr>
</table>
<br>
<table border="1" frame="box" rules="all" bgcolor="#FFFFFF" height="200"
cellspacing="0" cellpadding="0" bordercolor="#808080">

<colgroup>
<col width="8">
<col width="24" align="middle" span=8>
<col width="200" align="left" valign="top">
</colgtroup>


<tr> <td>7</td>
<td colspan="8">BASE 31..24</td>
<td rowspan="9">
<pre><b><u>
CODE [9b][GDT,LDT]</u></b>
G 4Kb granular
B 32-bit
P present
C confirming
R readable
A accessed</pre>
</td></tr>

<tr> <td>6</td>
<td><b>G</td>
<td><b>B</td>
<td><b>0</td>
<td>x</td>
<td nowrap colspan="4">LIM 19..16</td> </tr>

<tr> <td>5</td>
<td>P</td>
<td colspan="2">DPL</td>
<td colspan="2" style="border-width:medium;border-color:#000000;
border-style:double; padding:0px;"><b>1 1</td>
<td><b>C</td>
<td><b>R</td>
<td><b>A</td> </tr>

<tr> <td>4</td>
<td rowspan="3" colspan="8">BASE 0..23</td> </tr>

<tr> <td>3</td></tr>

<tr> <td>2</td></tr>

<tr> <td>1</td>
<td rowspan="2" colspan="8">LIMIT 0..15</td> </tr>

<tr><td>0</td></tr>

<tr style="font-size:7pt;">
<td></td>
<td>7</td>
<td>6</td>
<td>5</td>
<td>4</td>
<td>3</td>
<td>2</td>
<td>1</td>
<td>0</td> </tr>
</table>
<br>

<table border="1" frame="box" rules="all" bgcolor="#ffffff" height="200"
cellspacing="0" cellpadding="0" bordercolor="#808080">
<colgroup>
<col width="8">
<col width="24" align="middle" span=8>
<col width="200" align="left" valign="top">
</colgtroup>

<tr> <td>7</td>
<td colspan="8">BASE 31..24</td>
<td rowspan="9"><pre><u><b>
TASK-switch [81/89]</u>
[GDT]</b>
G 4Kb granular limit
P present
BT 32-bit
BS task is busy</pre> </td></tr>

<tr> <td>6</td>
<td><b>G</td>
<td><b>0</td>
<td><b>0</td>
<td>x</td>
<td nowrap colspan="4">LIM 19..16</td> </tr>

<tr> <td>5</td>
<td>P</td>
<td colspan="2">DPL</td>
<td
style="border-color:#000000;border-width:medium;border-style:double"><b>0</td>
<td><b>BT</td>
<td colspan= "3"
style="border-color:#000000;border-width:medium;border-style:double">
<b>0 BS 1</td>

</tr>

<tr> <td>4</td>
<td rowspan="3" colspan="8">BASE 0..23</td> </tr>

<tr> <td>3</td></tr>

<tr> <td>2</td></tr>

<tr> <td>1</td>
<td rowspan="2" colspan="8">LIMIT 0..15</td> </tr>

<tr><td>0</td></tr>

<tr style="font-size:7pt;">
<td></td>
<td>7</td>
<td>6</td>
<td>5</td>
<td>4</td>
<td>3</td>
<td>2</td>
<td>1</td>
<td>0</td> </tr>
</table>

<br>
<table border="1" frame="box" rules="all" bgcolor="#ffffff" height="200"
cellspacing="0" cellpadding="0" bordercolor="#808080">
<colgroup>
<col width="8">
<col width="24" align="middle" span=8>
<col width="200" align="left" valign="top">
</colgtroup>

<tr> <td>7</td>
<td rowspan="2" colspan="8">Linear Address 31..16</td>
<td rowspan="9"><pre><u><b>
LDT [82][GDT]</b></u></td></tr>

<tr> <td>6</td> </tr>

<tr> <td>5</td>
<td>P</td>
<td colspan="2">--</td>
<td style="border-color:#000000;border-width:medium;border-style:double">
<b>0</td>
<td><b>0</td>
<td colspan= "3"
style="border-color:#000000;border-width:medium;border-style:double">
<b>0 1 0</td>
</tr>

<tr> <td>4</td>
<td colspan="8">reserved</td> </tr>
<tr> <td>3</td>
<td colspan="8">SEGMENT-</td> </tr>
<tr> <td>2</td>
<td colspan="5">SELECTOR</td>
<td>x</td>
<td colspan="2">RPL</td> </tr>
<tr> <td>1</td>
<td rowspan="2" colspan="8">Linear Address 15..0</td> </tr>

<tr><td>0</td></tr>
<tr style="font-size:7pt;">
<td></td>
<td>7</td>
<td>6</td>
<td>5</td>
<td>4</td>
<td>3</td>
<td>2</td>
<td>1</td>
<td>0</td> </tr>
</table>
<br>

<br>
<table border="1" frame="box" rules="all" bgcolor="#ffffff" height="200"
cellspacing="0" cellpadding="0" bordercolor="#808080">
<colgroup>
<col width="8">
<col width="24" align="middle" span=8>
<col width="200" align="left" valign="top">
</colgtroup>

<tr> <td>7</td>
<td rowspan="2" colspan="8">Offset 31..16</td>
<td rowspan="9"><pre><u><b>
Call-GATE [84/8c]
[GDT,LDT]</b></u>
T 32-bit
L LDT (else GDT)
Dwords copied from
callers stack.
</td></tr>
<tr> <td>6</td> </tr>

<tr> <td>5</td>
<td>P</td>
<td colspan="2">DPL</td>
<td style="border-color:#000000;border-width:medium;border-style:double">
<b>0</td>
<td><b>T</td>
<td colspan= "3"
style="border-color:#000000;border-width:medium;border-style:double">
<b>1 0 0</td>
</tr>

<tr> <td>4</td>
<td colspan="4">0 0 0 0</td>
<td colspan="4">Dwords </td>
</tr>
<tr> <td>3</td>
<td colspan="8">SEGMENT-</td> </tr>
<tr> <td>2</td>
<td colspan="5">SELECTOR</td>
<td>L</td>
<td colspan="2">RPL</td> </tr>
<tr> <td>1</td>
<td rowspan="2" colspan="8">Offset 15..0</td> </tr>

<tr><td>0</td></tr>
<tr style="font-size:7pt;">
<td></td>
<td>7</td>
<td>6</td>
<td>5</td>
<td>4</td>
<td>3</td>
<td>2</td>
<td>1</td>
<td>0</td> </tr>
</table>
<br>

<table border="1" frame="box" rules="all" bgcolor="#ffffff" height="200"
cellspacing="0" cellpadding="0" bordercolor="#808080">
<colgroup>
<col width="8">
<col width="24" align="middle" span=8>
<col width="200" align="left" valign="top">
</colgtroup>

<tr> <td>7</td>
<td rowspan="2" colspan="8">reserved</td>
<td rowspan="9"><pre><u><b>
TASK-GATE [85/8d]
[GDT,IDT,LDT]</b></u>
T: 32-bit
</td></tr>
<tr> <td>6</td> </tr>
<tr> <td>5</td>
<td>P</td>
<td colspan="2">DPL</td>
<td style="border-color:#000000;border-width:medium;border-style:double">
<b>0</td>
<td><b>T</td>
<td colspan= "3"
style="border-color:#000000;border-width:medium;border-style:double">
<b>1 0 1</td>
</tr>

<tr> <td>4</td>
<td colspan="8">reserved</td> </tr>
<tr> <td>3</td>
<td colspan="8">SEGMENT-</td> </tr>
<tr> <td>2</td>
<td colspan="5">SELECTOR</td>
<td>x</td>
<td colspan="2">RPL</td> </tr>
<tr> <td>1</td>
<td rowspan="2" colspan="8">reserved</td> </tr>

<tr><td>0</td></tr>
<tr style="font-size:7pt;">
<td></td>
<td>7</td>
<td>6</td>
<td>5</td>
<td>4</td>
<td>3</td>
<td>2</td>
<td>1</td>
<td>0</td> </tr>
</table>
<br>


<table border="1" frame="box" rules="all" bgcolor="#ffffff" height="200"
cellspacing="0" cellpadding="0" bordercolor="#808080">
<colgroup>
<col width="8">
<col width="24" align="middle" span=8>
<col width="200" align="left" valign="top">
</colgtroup>

<tr> <td>7</td>
<td rowspan="2" colspan="8">Offset 31..16</td>
<td rowspan="9"><pre><u><b>
INT-GATE [86/8e][IDT]</b></u>
T 32-bit
disables IRQ,
TRAP and NT cleared
until IRET
</td></tr>
<tr> <td>6</td> </tr>
<tr> <td>5</td>
<td>P</td>
<td colspan="2">DPL</td>
<td style="border-color:#000000;border-width:medium;border-style:double">
<b>0</td>
<td><b>T</td>
<td colspan= "3"
style="border-color:#000000;border-width:medium;border-style:double">
<b>1 1 0</td>
</tr>

<tr> <td>4</td>
<td colspan="8">reserved</td> </tr>
<tr> <td>3</td>
<td colspan="8">SEGMENT-</td> </tr>
<tr> <td>2</td>
<td colspan="5">SELECTOR</td>
<td>x</td>
<td colspan="2">RPL</td> </tr>
<tr> <td>1</td>
<td rowspan="2" colspan="8">Offset 15..0</td> </tr>

<tr><td>0</td></tr>
<tr style="font-size:7pt;">
<td></td>
<td>7</td>
<td>6</td>
<td>5</td>
<td>4</td>
<td>3</td>
<td>2</td>
<td>1</td>
<td>0</td> </tr>
</table>
<br>


<table border="1" frame="box" rules="all" bgcolor="#ffffff" height="200"
cellspacing="0" cellpadding="0" bordercolor="#808080">
<colgroup>
<col width="8">
<col width="24" align="middle" span=8>
<col width="200" align="left" valign="top">
</colgtroup>

<tr> <td>7</td>
<td rowspan="2" colspan="8">Offset 31..16</td>
<td rowspan="9"><pre><u><b>
INT-TRAP [87/8f][IDT]</b></u>
T 32-bit
IRQ-status unchanged,
TRAP and NT cleared
until IRET
</td></tr>
<tr> <td>6</td> </tr>
<tr> <td>5</td>
<td>P</td>
<td colspan="2">DPL</td>
<td style="border-color:#000000;border-width:medium;border-style:double">
<b>0</td>
<td><b>T</td>
<td colspan= "3"
style="border-color:#000000;border-width:medium;border-style:double">
<b>1 1 1</td>
</tr>

<tr> <td>4</td>
<td colspan="8">reserved</td> </tr>
<tr> <td>3</td>
<td colspan="8">SEGMENT-</td> </tr>
<tr> <td>2</td>
<td colspan="5">SELECTOR</td>
<td>x</td>
<td colspan="2">RPL</td> </tr>
<tr> <td>1</td>
<td rowspan="2" colspan="8">Offset 15..0</td> </tr>

<tr><td>0</td></tr>
<tr style="font-size:7pt;">
<td></td>
<td>7</td>
<td>6</td>
<td>5</td>
<td>4</td>
<td>3</td>
<td>2</td>
<td>1</td>
<td>0</td> </tr>
</table>
<br>

</font>
</body>
</html>


From: James Harris on
On 26 June, 09:48, Stargazer <stargazer3...(a)gmail.com> wrote:

....

> > Some interesting things have come out that I didn't know. For example,
> > there are only two fundamental descriptor forms, one for blocks of
> > memory and one for points in memory. The blocks of memory descriptor
> > form includes all the memory segment types plus some System types -
> > those for LDT and TSS blocks. And the points of memory are all gates.
> > Simple!
>
> I think that Intel manuals also refer to two types of descriptors, but
> call them "segment" and "gate" descriptors (or it was in earlier
> documents, I didn't check that recently). I would also suggest that
> your terminology choice is bad even for your own memorizing.

That there are basically only two forms of descriptor is is one of
those pieces of information that once you know it it seems obvious.
Where I've seen them in the Intel manuals, however, they refer to many
types.

> First, the architecture definition also refers to two types of
> descriptors, but calls them with different name; you must have some
> good reason to suggest a different pair of names which would require
> you then remember both pairs and correspondence between them in order
> to look up things in specs.
>
> Second, if you wanted to ease remembering you ought to choose more
> "talkative" (not even descriptive names) - names that would remind you
> the things as they are. "Blocks" have too many options to mix up
> (besides segments, MTRR-defined ranges may be refered as "blocks";
> pages or page tables may be thought of as "blocks", etc.) Everything
> in your "blocks" group is a segment except for LDT, so "segments" or
> "segments and tables" may be a better replacement name. "Points" are
> better hinting, but apparently not in a way that you assumed, or at
> least your definition of "points" is misleading: it's not "points in
> memory", but "system entry points"! As such "points" may be more
> descriptive than "gates".

Isn't an LDT a segment? Maybe it isn't. I haven't checked.

I take your point about names. I don't want to call the first type
"segment descriptors" as the term segment has a lot of baggage and
means specific things to many people. I want the reader to see the
first descriptor type as identifying a block/range/region/space of
memory and contrast that with the second type which identifies a
single location, not a range. I think that aids remembering because it
highlights *why* they are different.

Any term has baggage but I agree that "block" is not good. I've
changed it to "range." Maybe that's a bit better?

> > As ever, corrections welcome.
>
> One thing that comes to mind is regarding limits. Unless Intel added a
> special treatment for 0-limited segments recently, the limit for 4K-
> granular segments is 2**12-1 .. 2**32-1, not 0 .. 2**32-1.

Thanks. I've corrected it.

> > Also, I've included only 32-bit data.
> > Should I add 64-bit data to it or will that overload it with too much
> > information?
>
> No (64-bit data belongs to a different architecture), but I think you
> should add 16-bit specifications.

That's a surprise! Aren't the 16-bit forms needed only on the 80286?
Again, I haven't checked. They are listed in the type codes. I think
that's enough. To add breakdowns of them as well would cause
confusion.

James
From: Mike Gonta on
On Jun 26, 9:08 am, James Harris <james.harri...(a)googlemail.com>
wrote:
> On 26 June, 09:48, Stargazer <stargazer3...(a)gmail.com> wrote:

> > No (64-bit data belongs to a different architecture), but I think you
> > should add 16-bit specifications.
>
> That's a surprise! Aren't the 16-bit forms needed only on the 80286?

A valid 16 bit segment descriptor must be moved to the segment
registers prior to entering real mode from protected mode.


Mike Gonta
look and see - many look but few see

http://mikegonta.com/pdBIOS32
 |  Next  |  Last
Pages: 1 2
Prev: what timer?
Next: the general server is not sufficient