========================[ MEMORY MODEL              ]=========================
# EFLAGS register -- see <http://en.wikipedia.org/wiki/EFLAGS>
* CF (bit 1) -- carry flag.
* IOPL (bit 12,13) -- modified by POPF and IRET when CPL == 0.

# Control registers -- see <http://en.wikipedia.org/wiki/Control_register>.
%cr0 -- most powerful system flags. (Enable paging/cr3, etc.)
%cr1 -- reserved.
%cr2/PFLA -- contains address of latest page fault.
%cr3/PDBR -- physical address of task's current page directory.
%cr4 -- extension flags, page global enable (PGE) flag.

# Memory management registers -- see <intel-sys:2.4>, <http://home.swipnet.se/smaffy/asm/info/PMODEDetailedApproach.txt>
IDTR register -- constant, stores physical base address (32-bit, fixed memory address at 0x0ish, outside of kernel stack) and length of IDT (16-bit), which contain consecutive 64-bit descriptors.
GDTR register -- constant, same layout and size as IDTR.
LDTR register -- in protected mode, each task gets its own local table of descriptors defining memory ranges and access rights; loads in on task switch.
TR (Task) register -- current task segment descriptor loaded.
* Task state segment (TSS) descriptor -- registers, IOPL, previous TSS.

%cs,%ss,%ds,%es,%fs,%gs -- stores (16-bit) segment selectors, which index into GDTR or LDTR.
* Segment selector -- 13-bit index into descriptor table, 1-bit table selector flag (GDT vs LGT), 2-bit RPL.
* Segment descriptor -- size, starting point, access rights of a segment.
* Memory is ALWAYS referenced %(segment reg):(offset).
* Programmer doesn't usually specify segment, usually implied by "kind of memory access." -L05


========================[ INTERRUPTS AND EXCEPTIONS ]=========================
Interrupts and exceptions are both transparent, forced transfers of execution from a currently running program to a handler. They (misleadingly) are mutually registered in the IDT.
Interrupts -- occur randomly through hardware signals and deliberate INTs in code.
Exceptions -- occur as a result of error conditions in executing an instruction.

Interrupts can be divided into two groups:
1) Hardware interrupts -- only randomly occurring switches in entire kernel; thus, maskability matters. IF in EFLAGS masks these interrupts.
2) Software interrupts -- system calls from user land.

Exceptions can be divided into three groups:
3) Processor-detected program errors:
3a) Faults -- detected before %eip++, can be corrected.
3b) Traps -- detected after %eip++ (only difference from faults), can be corrected.
3c) Aborts -- can't be corrected.
4) Software-generated exceptions -- INTO, INT 3, BOUND.
5) Machine-check exceptions -- hardware errors.

We can handle interrupts and exceptions in two ways:
i) Task-gate descriptor -- hardware switches using TSS descriptors.
ii) Interrupt-gate descriptor -- clears IF flag, thus disabling maskable hardware interrupts.
iii) Trap-gate descriptor -- same as interrupt-gate, except doesn't clear IF.

These descriptors are customizable:
* Segment selector (of code segment) determines handler's permission level.
* Descriptor priviledge level (DPL) required to execute the handler. 0 for ring0 only, 3 for ring0-3 access.

