GDT Tutorial: Difference between revisions
[unchecked revision] | [unchecked revision] |
Content deleted Content added
Revolution (talk | contribs) |
Revolution (talk | contribs) →How to Set Up The GDT: Changed code examples and added code for long mode and non-flat protected mode. Feel free to check my work. |
||
Line 123:
=== Filling the Table ===
The above structure of the '''GDT''' doesn't show you how to write entries in the correct format. The actual structure of descriptors is a little messy for backwards compatibility with the 286's '''GDT'''. Base address are split across three different fields and you cannot encode any limit you want
<source lang="c">
void encodeGdtEntry(uint8_t *target, struct GDT source)
{
Line 160 ⟶ 156:
=== Telling the CPU Where the Table Is ===
Some assembly
====
The linear address should here be computed as <tt>segment * 16 + offset</tt>. <tt>GDT</tt> and <tt>GDT_end</tt> are assumed to be symbols in the current data segment.
Line 183 ⟶ 179:
</source>
====
"Flat" meaning the base of your
<source lang="asm">
Line 192 ⟶ 188:
setGdt:
MOV
MOV [gdtr], AX
MOV EAX, [ESP + 8]
MOV [gdtr + 2], EAX
</source>
==== Protected Mode, Non-Flat Model ====
If your data segment has a non-zero base, you'll have to adjust the instructions of the sequence above to include the ability to add the base offset of your data segment, which should be a known value to you. You can pass it in as an argument and call this function as <tt>setGdt(limit, base, offset)</tt>.
<source lang="asm">
gdtr DW 0 ; For limit storage
DD 0 ; For base storage
setGdt:
MOV AX, [esp + 4]
MOV [gdtr], AX
MOV EAX, [ESP + 8]
ADD EAX, [ESP + 12]
MOV [gdtr + 2], EAX
LGDT [gdtr]
RET
</source>
====
In '''[[Long Mode]]''', the length of the '''Base''' field is 8 bytes, rather than 4. As well, the '''[[System V ABI]]''' passes the first two arguments via the '''RDI''' and '''RSI''' registers. Thus, this example code can be called as <tt>setGdt(limit, base)</tt>. As well, only a flat model is possible in long mode, so no considerations have to be made otherwise.
<source lang="asm">
gdtr DW 0 ; For limit storage
DQ 0 ; For base storage
setGdt:
MOV [gdtr], DI
MOV [gdtr+2], RSI
LGDT [gdtr]
RET
</source>
=== Reload Segment Registers ===
Whatever you do with the '''GDT''' has no effect on the CPU until you load
==== Protected Mode ====
In this case, reloading '''CS''' is as simple as performing a far jump to the required segment, directly after the jump instruction:
<source lang="asm">
|