commit - a1cd4b7fc7a060a817c404ca38994a604035281d
commit + 095d0ed35c3587d68ee65e3d1fd5024c2d3109fc
blob - /dev/null
blob + 55f590d145a547fe0f84ffddaa4724b8c559a9ee (mode 644)
--- /dev/null
+++ doc/286intel-utf8.txt
+INTEL 80286 PROGRAMMER'S REFERENCE MANUAL 1987
+
+Intel Corporation makes no warranty for the use of its products and
+assumes no responsibility for any errors which may appear in this document
+nor does it make a commitment to update the information contained herein.
+
+Intel retains the right to make changes to these specifications at any
+time, without notice.
+
+Contact your local sales office to obtain the latest specifications before
+placing your order.
+
+The following are trademarks of Intel Corporation and may only be used to
+identify Intel Products:
+
+Above, BITBUS, COMMputer, CREDIT, Data Pipeline, FASTPATH, Genius, i, î,
+ICE, iCEL, iCS, iDBP, iDIS, I²ICE, iLBX, im, iMDDX, iMMX, Inboard, Insite,
+Intel, intel, intelBOS, Intelevision, inteligent Identifier, inteligent
+Programming, Intellec, Intellink, iOSP, iPDS, iPSC, iRMX, iSBC, iSBX, iSDM,
+iSXM, KEPROM, Library Manager, MAP-NET, MCS, Megachassis, MICROMAINFRAME,
+MULTIBUS, MULTICHANNEL, MULTIMODULE, MultiSERVER, ONCE, OpenNET, OTP,
+PC-BUBBLE, Plug-A-Bubble, PROMPT, Promware, QUEST, QueX, Quick-Pulse
+Programming, Ripplemode, RMX/80, RUPI, Seamless, SLD, UPI, and VLSiCEL, and
+the combination of ICE, iCS, iRMX, iSBC, iSBX, MCS, or UPI and a numerical
+suffix, 4-SITE.
+
+MDS is an ordering code only and is not used as a product name or
+trademark. MDS(R) is a registered trademark of Mohawk Data Sciences
+Corporation.
+
+*MULTIBUS is a patented Intel bus.
+
+Additional copies of this manual or other Intel literature may be obtained
+from:
+
+Intel Corporation
+Literature Distribution
+Mail Stop SC6-59
+3065 Bowers Avenue
+Santa Clara, CA 95051
+
+(c)INTEL CORPORATION 1987 CG-10/86
+
+
+Preface
+
+───────────────────────────────────────────────────────────────────────────────────────────────────
+
+
+This manual describes the 80286, the most powerful 16-bit microprocessor in
+the 8086 family, and the 80287 Numeric Processor Extension (NPX).
+
+Organization of This Manual
+
+80286
+
+The 80286 contains a table of contents, eleven chapters, four appendices,
+and an index. For more information on the 80286 book's organization, see its
+first chapter, Chapter 1, "Introduction to the 80286." Section 1.4 in that
+chapter explains the organization in detail.
+
+Notational Conventions
+This manual uses special notation to represent sub- and superscript
+characters. Subscript characters are surrounded by {curly brackets}, for
+example 10{2} = 10 base 2. Superscript characters are preceeded by a caret
+and enclosed within (parentheses), for example 10^(3) = 10 to the third
+power.
+
+Table of Contents
+
+───────────────────────────────────────────────────────────────────────────────────────────────────
+
+
+Chapter 1 Introduction to the 80286
+
+1.1 General Attributes
+1.2 Modes of Operation
+1.3 Advanced Features
+ 1.3.1 Memory Management
+ 1.3.2 Task Management
+ 1.3.3 Protection Mechanisms
+ 1.3.4 Support for Operating Systems
+
+1.4 Organization of This Book
+1.5 Related Publications
+
+Chapter 2 80286 Base Architecture
+
+2.1 Memory Organization and Segmentation
+2.2 Data Types
+2.3 Registers
+ 2.3.1 General Registers
+ 2.3.2 Memory Segmentation and Segment Registers
+ 2.3.3 Index, Pointer, and Base Registers
+ 2.3.4 Status and Control Registers
+
+2.4 Addressing Modes
+ 2.4.1 Operands
+ 2.4.2 Register and Immediate Modes
+ 2.4.3 Memory Addressing Modes
+ 2.4.3.1 Segment Selection
+ 2.4.3.2 Offset Computation
+ 2.4.3.3 Memory Mode
+
+2.5 Input/Output
+ 2.5.1 I/O Address Space
+ 2.5.2 Memory-Mapped I\0
+
+2.6 Interrupts and Exceptions
+2.7 Hierarchy of Instruction Sets
+
+Chapter 3 Basic Instruction Set
+
+3.1 Data Movement Instructions
+ 3.1.1 General-Purpose Data Movement Instructions
+ 3.1.2 Stack Manipulation Instructions
+
+3.2 Flag Operation with the Basic Instruction Set
+ 3.2.1 Status Flags 4
+ 3.2.2 Control Flags 4
+
+3.3 Arithmetic Instructions
+ 3.3.1 Addition Instructions
+ 3.3.2 Subtraction Instructions
+ 3.3.3 Muitiplication Instructions
+ 3.3.4 Division Instructions
+
+3.4 Logical Instructions
+ 3.4.1 Boolean Operation Instructions
+ 3.4.2 Shift and Rotate Instructions
+ 3.4.2.1 Shift Instructions
+ 3.4.2.2 Rotate Instructions
+
+ 3.4.3 Type Conversion and No-Operation Instructions
+
+3.5 Test and Compare Instructions
+3.6 Control Transfer Instructions
+ 3.6.1 Unconditional Transfer Instructions
+ 3.6.1.1 Jump instruction
+ 3.6.1.2 Call Instruction
+ 3.6.1.3 Return and Return from interrupt Instruction
+
+ 3.6.2 Conditional Transfer Instructions
+ 3.6.2.1 Conditional Jump Instructions
+ 3.6.2.2 Loop Instructions
+ 3.6.2.3 Executing a Loop or Repeat Zero Times
+
+ 3.6.3 Software-Generated Interrupts
+ 3.6.3.1 Software Interrupt Instruction
+
+3.7 Character Translation and String Instructions
+ 3.7.1 Translate Instruction
+ 3.7.2 String Manipulation Instructions and Repeat Prefixes
+ 3.7.2.1 String Movement Instructions
+ 3.7.2.2 Other String Operations
+
+3.8 Address Manipulation Instructions
+3.9 Flag Control instructions
+ 3.9.1 Carry Flag Control Instructions
+ 3.9.2 Direction Flag Control Instructions
+ 3.9.3 Flag Transfer Instructions
+
+3.10 Binary-Coded Decimal Arithmetic Instructions
+ 3.10.1 Packed BCD Adjustment Instructions
+ 3.10.2 Unpacked BCD Adjustment Instructions
+
+3.11 Trusted Instructions
+ 3.11.1 Trusted and Privileged Restrictions on POPF and IRET
+ 3.11.2 Machine State Instructions
+ 3.11.3 Inputand Output Instructions
+
+3.12 Processor Extension Instructions
+ 3.12.1 Processor Extension Synchronization Instructions
+ 3.12.2 Numeric Data Processor Instructions
+ 3.12.2.1 Arithmetic Instructions
+ 3.12.2.2 Comparison Instructions
+ 3.12.2.3 Transcendental Instructions
+ 3.12.2.4 Data Transfer Instructions
+ 3.12.2.5 Constant Instructions
+
+Chapter 4 Extended Instruction Set
+
+4.1 Block I\O Instructions
+4.2 High-Level Instructions
+
+Chapter 5 Real Address Mode
+
+5.1 Addressing and Segmentation
+5.2 Interrupt Handling
+ 5.2.1 Interrupt Vector Table
+ 5.2.1.1 Interrupt Procedures
+ 5.2.2 Interrupt Priorities
+ 5.2.3 Reserved and Dedicated Interrupt Vectors
+
+5.3 System Initialization.
+
+Chapter 6 Memory Management and Virtual Addressing
+
+6.1 Memory Management Overview
+6.2 Virtual Addresses
+6.3 Descriptor Tables
+6.4 Virtual-to-Physical Address Translation
+6.5 Segments and Segment Descriptors
+6.6 Memory Management Registers
+ 6.6.1 Segment Address Translation Registers
+ 6.6.2 System Address Registers
+
+Chapter 7 Protection
+
+7.1 Introduction
+ 7.1.1 Types of Protection
+ 7.1.2 Protection Implementation
+
+7.2 Memory Management and Protection
+ 7.2.1 Separation of Address Spaces
+ 7.2.2 LDT and GDT Access Checks
+ 7.2.3 Type Validation
+
+7.3 Privilege Levels and Protection
+ 7.3.1 Example of Using Four Privilege Levels
+ 7.3.2 Privilege Usage
+
+7.4 Segment Descriptor
+ 7.4.1 Data Accesses
+ 7.4.2 Code Segment Access
+ 7.4.3 Data Access Restriction by Privilege Level
+ 7.4.4 Pointer Privilege Stamping via ARPL
+
+7.5 Control Transfers
+ 7.5.1 Gates
+ 7.5.1.1 Call Gates
+ 7.5.1.2 Intra-Level Transfers via Call Gate
+ 7.5.1.3 Inter-Level Control Transfer via Call Gates
+ 7.5.1.4 Stack Changes Caused by Call Gates
+
+ 7.5.2 Inter-Level Returns
+
+Chapter 8 Tasks and State Transitions
+
+8.1 Introduction
+8.2 Task State Segments and Descriptors
+ 8.2.1 Task State Segment Descriptors
+
+8.3 Task Switching
+8.4 Task Linking
+8.5 Task Gates
+
+Chapter 9 Interrupts and Exceptions
+
+9.1 Interrupt Descriptor Table
+9.2 Hardware Initiated Interrupts
+9.3 Software Initiated Interrupts
+9.4 Interrupt Gates and Trap Gates
+9.5 Task Gates and Interrupt Tasks
+ 9.5.1 Scheduling Considerations
+ 9.5.2 Deciding Between Task, Trap, and Interrupt Gates
+
+9.6 Protection Exceptions and Reserved Vectors
+ 9.6.1 Invalid OP-Code (Interrupt 6)
+ 9.6.2 Double Fault (Interrupt 8)
+ 9.6.3 Processor Extension Segment Overrun (Interrupt 9)
+ 9.6.4 Invalid Task State Segment (Interrupt 10)
+ 9.6.5 Not Present (Interrupt 11)
+ 9.6.6 Stack Fault (Interrupt 12)
+ 9.6.7 General Protection Fault (Interrupt 13)
+
+9.7 Additional Exceptions and Interrupts
+ 9.7.1 Single Step Interrupt (Interrupt 1)
+
+Chapter 10 System Control and Initialization
+
+10.1 System Flags and Registers
+ 10.1.1 Descriptor Table Registers
+
+10.2 System Control Instructions
+ 10.2.1 Machine Status Word
+ 10.2.2 Other Instructions
+
+10.3 Privileged and Trusted Instructions
+
+10.4 Initialization
+ 10.4.1 Real Address Mode
+ 10.4.2 Protected Mode
+
+Chapter 11 Advanced Topics
+
+11.1 Virtual Memory Management
+11.2 Special Segment Attributes
+ 11.2.1 Conforming Code Segments
+ 11.2.2 Expand-Down Data Segments
+
+11.3 Pointer Validation
+ 11.3.1 Descriptor Validation
+ 11.3.2 Pointer Integrity: RPL and the"Trojan Horse Problem"
+
+11.4 NPX Context Switching
+11.5 Multiprocessor Considerations
+11.6 Shutdown
+
+Appendix A 80286 System Initialization
+
+Appendix B The 80286 Instruction Set
+
+Appendix C 8086/8088 Compatibility Considerations
+
+Appendix D 80286/80386 Software Compatibility Considerations
+
+Index
+
+Figures
+
+1-1 Four Privilege Levels
+
+2-1 Segmented Virtual Memory
+2-2 Bytes and Words in Memory.
+2-3 80286/80287 Supported Data Types
+2-4 80286 Base Architecture Register Set
+2-5 Real Address Mode Segment Selector Interpretation
+2-6 Protected Mode Segment Selector Interpretation
+2-7 80286 Stack
+2-8 Stack Operation
+2-9 BP Usage as a Stack Frame Base Pointer
+2-10 Flags Register.
+2-11 Two-Component Address
+2-12 Use of Memory Segmentation
+2-13 Complex Addressing Modes
+2-14 Memory-Mapped I/O
+2-15 Hierarchy of Instructions
+
+3-1 PUSH
+3-2 PUSHA
+3-3 POP
+3-4 POPA.
+3-5 Flag Word Contents
+3-6 SAL and SHL
+3-7 SHR
+3-8 SAR
+3-9 ROL
+3-10 ROR
+3-11 RCL
+3-12 RCR
+3-13 LAHF and SAHF
+3-14 PUSHF and POPF
+
+4-1 Formal Definition of the ENTER Instruction
+4-2 Variable Access in Nested Procedures
+4-2a Stack Frame for MAIN at Level 1
+4-2b Stack Frame for Procedure A
+4-2c Stack Frame for Procedure B at Level 3 Called from A
+4-2d Stack Frame for Procedure C at Level 3 Called from B
+
+5-1a Forming the Segment Base Address
+5-1b Forming the 20-Bit Physical Address in the Real Address Mode
+5-2 Overlapping Segments to Save Physical Memory
+5-3 Interrupt Vector Table for Real Address Mode
+5-4 Stack Structure after Interrupt (Real Address Mode)
+
+6-1 Format of the Segment Selector Component
+6-2 Address Spaces and Task Isolation
+6-3 Segment Descriptor (S=1)
+6-4 Special Purpose Descriptors or System Segment Descriptors (S=O)
+6-5 LDT Descriptor
+6-6 Virtual-to-Physical Address Translation
+6-7 Segment Descriptor Access Bytes
+6-8 Memory Management Registers
+6-9 Descriptor Loading
+
+7-1 Addressing Segments of a Module within a Task
+7-2 Descriptor Cache Registers
+7-3 80286 Virtual Address Space
+7-4 Local and Global Descriptor Table Definitions
+7-5 Error Code Format (on the stack)
+7-6 Code and Data Segments Assigned to a Privilege Level.
+7-7 Selector Fields
+7-8 Access Byte Examples.
+7-9 Pointer Privilege Stamping
+7-10 Gate Descriptor Format.
+7-11 Call Gate
+7-12 Stack Contents after an Inter-Level Call
+
+8-1 Task State Segment and TSS Registers
+8-2 TSS Descriptor
+8-3 Task Gate Descriptor
+8-4 Task Switch Through a Task Gate
+
+9-1 Interrupt Descriptor Table Definition
+9-2 IDT Selector Error Code.
+9-3 Trap/Interrupt Gate Descriptors
+9-4 Stack Layout after an Exception with an Error Code
+
+10-1 Local and Global Descriptor Table Definition
+10-2 Interrupt Descriptor Table Definition
+10-3 Data Type for Global Descriptor Table and Interrupt Descriptor Table
+
+11-1 Expand-Down Segment
+11-2 Dynamic Segment Relocation and Expansion of Segment Limit
+11-3 Example of NPX Context Switching
+
+B-1 /n Instruction Byte Format
+B-2 /r Instruction Byte Format
+
+Tables
+
+2-1 Implied Segment Usage by Index, Pointer, and Base Registers
+2-2 Segment Register Selection Rules
+2-3 Memory Operand Addressing Modes
+2-4 80286 Interrupt Vector Assignments (Real Address Mode)
+
+3-1 Status Flags' Functions
+3-2 Control Flags' Functions
+3-3 Interpretation of Conditional Transfers
+
+5-1 Interrupt Processing Order
+5-2 Dedicated and Reserved Interrupt Vectors in Real Address Mode
+5-3 Processor State after RESET
+
+7-1 Segment Access Rights Byte Format
+7-2 Allowed Segment Types in Segment Registers
+7-3 Call Gate Checks
+7-4 Inter-Level Return Checks
+
+8-1 Checks Made during a Task Switch
+8-2 Effect of a Task Switch on BUSY and NT Bits and the Link Word
+
+9-1 Trap and Interrupt Gate Checks
+9-2 Interrupt and Gate Interactions
+9-3 Reserved Exceptions and Interrupts
+9-4 Interrupt Processing Order
+9-5 Conditions That Invalidate the TSS
+
+10-1 MSW Bit Functions
+10-2 Recommended MSW Encodings for Processor Extension Control
+
+11-1 NPX Context Switching
+
+B-1 ModRM Values
+B-2 Protection Exceptions of the 80286
+B-3 Hexadecimal Values for the Access Rights Byte
+
+C-1 New 80286 Interrupts
+
+
+
+Chapter 1 Introduction to the 80286
+
+───────────────────────────────────────────────────────────────────────────
+
+The 80286 is the most powerful 16-bit processor in the 8086 series of
+microprocessors, which includes the 8086, the 8088, the 80186, the 80188,
+and the 80286. It is designed for applications that require very high
+performance. It is also an excellent choice for sophisticated "high end"
+applications that will benefit from its advanced architectural features:
+memory management, protection mechanisms, task management, and virtual
+memory support. The 80286 provides, on a single VLSI chip, computational
+and architectural characteristics normally associated with much larger
+minicomputers.
+
+Sections 1.1, 1.2, and 1.3 of this chapter provide an overview of the 80286
+architecture. Because the 80286 represents an extension of the 8086
+architecture, some of this overview material may be new and unfamiliar to
+previous users of the 8086 and similar microprocessors. But the 80286 is
+also an evolutionary development, with the new architecture superimposed
+upon the industry standard 8086 in such a way as to affect only the design
+and programming of operating systems and other such system software.
+Section 1.4 of this chapter provides a guide to the organization of this
+manual, suggesting which chapters are relevant to the needs of particular
+readers.
+
+
+1.1 General Attributes
+
+The 80286 base architecture has many features in common with the
+architecture of other members of the 8086 family, such as byte addressable
+memory, I/O interfacing hardware, interrupt vectoring, and support for both
+multiprocessing and processor extensions. The entire family has a common
+set of addressing modes and basic instructions. The 80286 base architecture
+also includes a number of extensions which add to the versatility of the
+computer.
+
+The 80286 processor can function in two modes of operation (see section 1.2
+of this chapter, Modes of Operation). In one of these modes only the base
+architecture is available to programmers, whereas in the other mode a number
+of very powerful advanced features have been added, including support for
+virtual memory, multitasking, and a sophisticated protection mechanism.
+These advanced features are described in section 1.3 of this chapter.
+
+The 80286 base architecture was designed to support programming in
+high-level languages, such as Pascal, C or PL/M. The register set and
+instructions are well suited to compiler-generated code. The addressing
+modes (see section 2.4.3 in Chapter 2) allow efficient addressing
+of complex data structures, such as static and dynamic arrays, records,
+and arrays within records, which are commonly supported by high-level
+languages. The data types supported by the architecture include, along with
+bytes and words, high level language constructs such as strings, BCD, and
+floating point.
+
+The memory architecture of the 80286 was designed to support modular
+programming techniques. Memory is divided into segments, which may be of
+arbitrary size, that can be used to contain procedures and data structures.
+Segmentation has several advantages over more conventional linear memory
+architectures. It supports structured software, since segments can contain
+meaningful program units and data, and more compact code, since references
+within a segment can be shorter (and locality of reference usually insures
+that the next few references will be within the same segment). Segmentation
+also lends itself to efficient implementation of sophisticated memory
+management, virtual memory, and memory protection.
+
+In addition, new instructions have been added to the base architecture to
+give hardware support for procedure invocations, parameter passing, and
+array bounds checking.
+
+
+1.2 Modes of Operation
+
+The 80286 can be operated in either of two different modes: Real Address
+Mode or Protected Virtual Address Mode (also referred to as Protected Mode).
+In either mode of operation, the 80286 represents an upwardly compatible
+addition to the 8086 family of processors.
+
+In Real Address Mode, the 80286 operates essentially as a very
+high-performance 8086. Programs written for the 8086 or the 80186 can be
+executed in this mode without any modification (the few exceptions are
+described in Appendix C, "Compatibility Considerations"). Such upward
+compatibility extends even to the object code level; for example, an 8086
+program stored in read-only memory will execute successfully in 80286 Real
+Address Mode. An 80286 operating in Real Address Mode provides a number of
+instructions not found on the 8086. These additional instructions, also
+present with the 80186, allow for efficient subroutine linkage, parameter
+validation, index calculations, and block I/O transfers.
+
+The advanced architectural features and full capabilities of the 80286 are
+realized in its native Protected Mode. Among these features are
+sophisticated mechanisms to support data protection, system integrity, task
+concurrency, and memory management, including virtual storage.
+Nevertheless, even in Protected Mode, the 80286 remains upwardly compatible
+with most 8086 and 80186 application programs. Most 8086 applications
+programs can be re-compiled or re-assembled and executed on the 80286 in
+Protected Mode.
+
+
+1.3 Advanced Features
+
+The architectural features described in section 1.1 of this chapter
+are common to both operating modes of the processor. In addition to these
+common features, Protected Mode provides a number of advanced features,
+including a greatly extended physical and logical address space, new
+instructions, and support for additional hardware-recognized data
+structures. The Protected Mode 80286 includes a sophisticated memory
+management and multilevel protection mechanism. Full hardware support is
+included for multitasking and task switching operations.
+
+
+1.3.1 Memory Management
+
+The memory architecture of the Protected Mode 80286 represents a
+significant advance over that of the 8086. The physical address space has
+been increased from 1 megabyte to 16 megabytes (2^(24) bytes), while the
+virtual address space (i.e., the address space visible to a program) has
+been increased from 1 megabyte to 1 gigabyte (2^(30) bytes). Moreover,
+separate virtual address spaces are provided for each task in a
+multi-tasking system (see the next section, 1.3.2, "Task Management").
+
+The 80286 supports on-chip memory management instead of relying on an
+external memory management unit. The one-chip solution is preferable because
+no software is required to manage an external memory management unit,
+performance is much better, and hardware designs are significantly simpler.
+
+Mechanisms have been included in the 80286 architecture to allow the
+efficient implementation of virtual memory systems. (In virtual memory
+systems, the user regards the combination of main and external storage as a
+single large memory. The user can write large programs without worrying
+about the physical memory limitations of the system. To accomplish this, the
+operating system places some of the user programs and data in external
+storage and brings them into main memory only as they are needed.) All
+instructions that can cause a segment-not-present fault are fully
+restartable. Thus, a not-present segment can be loaded from external
+storage, and the task can be restarted at the point where the fault
+occurred.
+
+The 80286, like all members of the 8086 series, supports a segmented memory
+architecture. The 80286 also fully integrates memory segmentation into a
+comprehensive protection scheme. This protection scheme includes
+hardware-enforced length and type checking to protect segments from
+inadvertent misuse.
+
+
+1.3.2 Task Management
+
+The 80286 is designed to support multi-tasking systems. The architecture
+provides direct support for the concept of a task. For example, task state
+segments (see section 8.2 in Chapter 8) are hardware-recognized and
+hardware-manipulated structures that contain information on the current
+state of all tasks in the system.
+
+Very efficient context-switching (task-switching) can be invoked with a
+single instruction. Separate logical address spaces are provided for each
+task in the system. Finally, mechanisms exist to support intertask
+communication, synchronization, memory sharing, and task scheduling. Task
+Management is described in Chapter 8.
+
+
+1.3.3 Protection Mechanisms
+
+The 80286 allows the system designer to define a comprehensive protection
+policy to be applied, uniformly and continuously, to all ongoing operations
+of the system. Such a policy may be desirable to ensure system reliability,
+privacy of data, rapid error recovery, and separation of multiple users.
+
+The 80286 protection mechanisms are based on the notion of a "hierarchy of
+trust." Four privilege levels are distinguished, ranging from Level 0 (most
+trusted) to Level 3 (least trusted). Level 0 is usually reserved for the
+operating system kernel. The four levels may be visualized as concentric
+rings, with the most privileged level in the center (see figure 1-1).
+
+This four-level scheme offers system reliability, flexibility, and design
+options not possible with the typical two-level (supervisor/user) separation
+provided by other processors. A four-level division is capable of separating
+kernel, executive, system services, and application software, each with
+different privileges.
+
+At any one time, a task executes at one of the four levels. Moreover, all
+data segments and code segments are also assigned to privilege levels. A
+task executing at one level cannot access data at a more privileged level,
+nor can it call a procedure at a less privileged level (i.e., trust a less
+privileged procedure to do work for it). Thus, both access to data and
+transfer of control are restricted in appropriate ways.
+
+A complete separation can exist between the logical address spaces local to
+different tasks, providing users with automatic protection against
+accidental or malicious interference by other users. The hardware also
+provides immediate detection of a number of fault and error conditions, a
+feature that can be useful in the development and maintenance of software.
+
+Finally, these protection mechanisms require relatively little system
+overhead because they are integrated into the memory management and
+protection hardware of the processor itself.
+
+
+Figure 1-1. Four Privilege Levels
+
+ ╔═══════════════════════════╗
+ ║ LEVEL 3 ◄────────╫──LEAST TRUSTED
+ ║ ╔═════════════════════╗ ║
+ ║ ║ LEVEL 2 ║ ║
+ ║ ║ ╔═══════════════╗ ║ ║
+ ║ ║ ║ LEVEL 1 ║ ║ ║
+ ║ ║ ║ ╔═════════╗ ║ ║ ║
+ ║ ║ ║ ║ LEVEL 0 ║ ║ ║ ║
+ ║ ║ ║ ║ ▲ ║ ║ ║ ║
+ ║ ║ ║ ╚═══════╪═╝ ║ ║ ║
+ ║ ║ ║ │ ║ ║ ║
+ ║ ║ ╚══════════╪════╝ ║ ║
+ ║ ║ │ ║ ║
+ ║ ╚═════════════╪═══════╝ ║
+ ║ │ ║
+ ╚════════════════╪══════════╝
+ │
+ └MOST TRUSTED
+
+
+1.3.4 Support for Operating Systems
+
+Most operating systems involve some degree of concurrency, with multiple
+tasks vying for system resources. The task management mechanisms described
+above provide the 80286 with inherent support for such multi-tasking
+systems. Moreover, the advanced memory management features of the 80286
+allow the implementation of sophisticated virtual memory systems.
+
+Operating system implementors have found that a multi-level approach to
+system services provides better security and more reliable systems. For
+example, a very secure kernel might implement critical functions such as
+task scheduling and resource allocation, while less fundamental functions
+(such asI/O) are built around the kernel. This layered approach also makes
+program development and enhancement simpler and facilitates error detection
+and debugging. The 80286 supports the layered approach through its
+four-level privilege scheme.
+
+
+1.4 Organization of This Book
+
+To facilitate the use of this book both as an introduction to the 80286
+architecture and as a reference guide, the remaining chapters are divided
+into three major parts.
+
+Part I, comprising chapters 2 through 4, should be read by all those who
+wish to acquire a basic familiarity with the 80286 architecture. These
+chapters provide detailed information on memory segmentation, registers,
+addressing modes and the general (application level) 80286 instruction set.
+In conjunction with the 80286 Assembly Language Reference Manual, these
+chapters provide sufficient information for an assembly language programmer
+to design and write application programs.
+
+The chapters in Part I are:
+
+Chapter 2, "Architectural Features." This chapter discusses those features
+of the 80286 architecture that are significant for application programmers.
+The information presented can also function as an introduction to the
+machine for system programmers. Memory organization and segmentation,
+processor registers, addressing modes, and instruction formats are all
+discussed.
+
+Chapter 3, "Basic Instruction Set." This chapter presents the core
+instructions of the 8086 family.
+
+Chapter 4, "Extended Instruction Set." This chapter presents the extended
+instructions shared by the 80186 and 80286 processors.
+
+Part II of the book consists of a single chapter:
+
+Chapter 5, "Real Address Mode." This chapter presents the system
+programmer's view of the 80286 when the processor is operated in Real
+Address Mode.
+
+Part III of the book comprises chapters 6 through 11. Aimed primarily at
+system programmers, these chapters discuss the more advanced architectural
+features of the 80286, which are available when the processor is in
+Protected Mode. Details on memory management, protection mechanisms, and
+task switching are provided.
+
+The chapters in Part III are:
+
+Chapter 6, "Virtual Memory." This chapter describes the 80286 address
+translation mechanisms that support virtual memory. Segment descriptors,
+global and local descriptor tables, and descriptor caches are discussed.
+
+Chapter 7, "Protection." This chapter describes the protection features of
+the 80286. Privilege levels, segment attributes, access restrictions, and
+call gates are discussed.
+
+Chapter 8, "Tasks and State Transitions." This chapter describes the 80286
+mechanisms that support concurrent tasks. Context-switching, task state
+segments, task gates, and interrupt tasks are discussed.
+
+Chapter 9, "Interrupts, Traps and Faults." This chapter describes interrupt
+and trap handling. Special attention is paid to the exception traps, or
+faults, which may occur in Protected Mode. Interrupt gates, trap gates, and
+the interrupt descriptor table are discussed.
+
+Chapter 10, "System Control and Initialization." This chapter describes the
+actual instructions used to implement the memory management, protection, and
+task support features of the 80286. System registers, privileged
+instructions, and the initial machine state are discussed.
+
+Chapter 11, "Advanced Topics." This chapter completes Part III with a
+description of several advanced topics, including special segment attributes
+and pointer validation.
+
+
+1.5 Related Publications
+
+The following manuals also contain information of interest to programmers
+of 80287 systems:
+
+ ■ Introduction to the 80286, order number 210308
+ ■ ASM286 Assembly Language Reference Manual, order number 121924
+ ■ 80286 Operating System Writer's Guide, order number 121960
+ ■ 80286 Hardware Reference Manual, order number 210760
+ ■ Microprocessor and Peripheral Handbook, order number 230843
+ ■ PL/M-286 User's Guide, order number 121945
+ ■ 80287 Support Library Reference Manual, order number 122129
+ ■ 8086 Software Toolbox Manual, order number 122203 (includes
+ information about 80287 Emulator Software)
+
+
+Chapter 2 80286 Base Architecture
+
+───────────────────────────────────────────────────────────────────────────
+
+This chapter describes the 80286 application programming environment as
+seen by assembly language programmers. It is intended to introduce the
+programmer to those features of the 80286 architecture that directly affect
+the design and implementation of 80286 application programs.
+
+
+2.1 Memory Organization and Segmentation
+
+The main memory of an 80286 system makes up its physical address space.
+This address space is organized as a sequence of 8-bit quantities, called
+bytes. Each byte is assigned a unique address ranging from 0 up to a maximum
+of 2^(20) (1 megabyte) in Real Address Mode, and up to 2^(24) (16 megabytes)
+in Protected Mode.
+
+A virtual address space is the organization of memory as viewed by a
+program. Virtual address space is also organized in units of bytes. (Other
+addressable units such as words, strings, and BCD digits are described below
+in section 2.2, "Data Types.") In Real Address Mode, as with the 8086
+itself, programs view physical memory directly, inasmuch as they manipulate
+pure physical addresses. Thus, the virtual address space is identical to the
+physical address space (1 megabyte).
+
+In Protected Mode, however, programs have no direct access to physical
+addresses. Instead, memory is viewed as a much larger virtual address space
+of 2^(30) bytes (1 gigabyte). This 1 gigabyte virtual address is mapped onto
+the Protected Mode's 16-megabyte physical address space by the address
+translation mechanisms described in Chapter 6.
+
+The programmer views the virtual address space on the 80286 as a collection
+of up to sixteen thousand linear subspaces, each with a specified size or
+length. Each of these linear address spaces is called a segment. A segment
+is a logical unit of contiguous memory. Segment sizes may range from one
+byte up to 64K (65,536) bytes.
+
+80286 memory segmentation supports the logical structure of programs and
+data in memory. Programs are not written as single linear sequences of
+instructions and data, but rather as modules of code and data. For example,
+program code may include a main routine and several separate procedures.
+Data may also be organized into various data structures, some private and
+some shared with other programs in the system. Run-time stacks constitute
+yet another data requirement. Each of these several modules of code and
+data, moreover, may be very different in size or vary dynamically with
+program execution.
+
+Segmentation supports this logical structure (see figure 2-1). Each
+meaningful module of a program may be separately contained in individual
+segments. The degree of modularization, of course, depends on the
+requirements of a particular application. Use of segmentation benefits
+almost all applications. Programs execute faster and require less space.
+Segmentation also simplifies the design of structured software.
+
+
+2.2 Data Types
+
+Bytes and words are the fundamental units in which the 80286 manipulates
+data, i.e., the fundamental data types.
+
+A byte is 8 contiguous bits starting on an addressable byte boundary. The
+bits are numbered 0 through 7, starting from the right. Bit 7 is the most
+significant bit:
+
+ 7 0
+ ┌───┬───┬───┬───┬───┬───┬───┬───┐
+ │ BYTE │
+ └───┴───┴───┴───┴───┴───┴───┴───┘
+
+A word is defined as two contiguous bytes starting on an arbitrary byte
+boundary; a word thus contains 16 bits. The bits are numbered 0 through 15,
+starting from the right. Bit 15 is the most significant bit. The byte
+containing bit 0 of the word is called the low byte; the byte containing
+bit 15 is called the high byte.
+
+ 15 0
+ ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
+ │ HIGH BYTE │ LOW BYTE │
+ └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
+ LOCATION N + 1 LOCATION N
+
+Each byte within a word has its own particular address, and the smaller of
+the two addresses is used as the address of the word. The byte at this lower
+address contains the eight least significant bits of the word, while the
+byte at the higher address contains the eight most significant bits. The
+arrangement of bytes within words is illustrated in figure 2-2.
+
+Note that a word need not be aligned at an even-numbered byte address. This
+allows maximum flexibility in data structures (e.g., records containing
+mixed byte and word entries) and efficiency in memory utilization. Although
+actual transfers of data between the processor and memory take place at
+physically aligned word boundaries, the 80286 converts requests for
+unaligned words into the appropriate sequences of requests acceptable to the
+memory interface. Such odd aligned word transfers, however, may impact
+performance by requiring two memory cycles to transfer the word rather than
+one. Data structures (e.g., stacks) should therefore be designed in such a
+way that word operands are aligned on word boundaries whenever possible for
+maximum system performance. Due to instruction prefetching and queueing
+within the CPU, there is no requirement for instructions to be aligned on
+word boundaries and no performance loss if they are not.
+
+Although bytes and words are the fundamental data types of operands, the
+processor also supports additional interpretations on these bytes or words.
+Depending on the instruction referencing the operand, the following
+additional data types can be recognized:
+
+Integer:
+A signed binary numeric value contained in an 8-bit byte or a 16-bit word.
+All operations assume a 2's complement representation. (Signed 32- and
+64-bit integers are supported using the 80287 Numeric Data Processor.)
+
+Ordinal:
+An unsigned binary numeric value contained in an 8-bit byte or 16-bit word.
+
+Pointer:
+A 32-bit address quantity composed of a segment selector component and an
+offset component. Each component is a 16-bit word.
+
+String:
+A contiguous sequence of bytes or words. A string may contain from 1 byte
+to 64K bytes.
+
+ASCII:
+A byte representation of alphanumeric and control characters using the
+ASCII standard of character representation.
+
+BCD:
+A byte (unpacked) representation of the decimal digits (0-9).
+
+Packed BCD:
+A byte (packed) representation of two decimal digits (0-9). One digit is
+stored in each nibble of the byte.
+
+Floating Point:
+A signed 32-, 64-, or 80-bit real number representation. (Floating operands
+are supported using the 80287 Numeric Processor Configuration.)
+
+Figure 2-3 graphically represents the data types supported by the 80286.
+80286 arithmetic operations may be performed on five types of numbers:
+unsigned binary, signed binary (integers), unsigned packed decimal, unsigned
+unpacked decimal, and floating point. Binary numbers may be 8 or 16 bits
+long. Decimal numbers are stored in bytes; two digits per byte for packed
+decimal, one digit per byte for unpacked decimal. The processor always
+assumes that the operands specified in arithmetic instructions contain data
+that represent valid numbers for the type of instruction being performed.
+Invalid data may produce unpredictable results.
+
+Unsigned binary numbers may be either 8 or 16 bits long; all bits are
+considered in determining a number's magnitude. The value range of an 8-bit
+unsigned binary number is 0-255; 16 bits can represent values from 0 through
+65,535. Addition, subtraction, multiplication and division operations are
+available for unsigned binary numbers.
+
+Signed binary numbers (integers) may be either 8 or 16 bits long. The
+high-order (leftmost) bit is interpreted as the number's sign: 0 = positive
+and 1 = negative. Negative numbers are represented in standard two's
+complement notation. Since the high-order bit is used for a sign, the range
+of an 8-bit integer is -128 through +127; 16-bit integers may range from
+-32,768 through +32,767. The value zero has a positive sign.
+
+Separate multiplication and division operations are provided for both
+signed and unsigned binary numbers. The same addition and subtraction
+instructions are used with signed or unsigned binary values. Conditional
+jump instructions, as well as an "interrupt on overflow" instruction, can
+be used following an unsigned operation on an integer to detect overflow
+into the sign bit.
+
+Unpacked decimal numbers are stored as unsigned byte quantities. One digit
+is stored in each byte. The magnitude of the number is determined from the
+low-order half-byte; hexadecimal values 0-9 are valid and are interpreted as
+decimal numbers. The high-order half-byte must be zero for multiplication
+and division; it may contain any value for addition and subtraction.
+
+Arithmetic on unpacked decimal numbers is performed in two steps. The
+unsigned binary addition, subtraction and multiplication operations are used
+to produce an intermediate result. An adjustment instruction then changes
+the value to a final correct unpacked decimal number. Division is performed
+similarly, except that the adjustment is carried out on the two digit
+numerator operand in register AX first, followed by an unsigned binary
+division instruction that produces a correct result.
+
+Unpacked decimal numbers are similar to the ASCII character representations
+of the digits 0-9. Note, however, that the high-order half-byte of an ASCII
+numeral is always 3. Unpacked decimal arithmetic may be performed on ASCII
+numeric characters under the following conditions:
+
+ ■ the high-order half-byte of an ASCII numeral must be set to 0H prior
+ to multiplication or division.
+
+ ■ unpacked decimal arithmetic leaves the high-order half-byte set to 0H;
+ it must be set to 3 to produce a valid ASCII numeral.
+
+Packed decimal numbers are stored as unsigned byte quantities. The byte is
+treated as having one decimal digit in each half-byte (nibble); the digit in
+the high-order half-byte is the most significant. Values 0-9 are valid in
+each half-byte, and the range of a packed decimal number is 0-99. Additions
+and subtractions are performed in two steps. First, an addition or
+subtraction instruction is used to produce an intermediate result. Then, an
+adjustment operation is performed which changes the intermediate value to a
+final correct packed decimal result. Multiplication and division
+adjustments are only available for unpacked decimal numbers.
+
+Pointers and addresses are described below in section 2.3.3, "Index,
+Pointer, and Base Registers," and in section 3.8, "Address Manipulation
+Instructions."
+
+Strings are contiguous bytes or words from 1 to 64K bytes in length. They
+generally contain ASCII or other character data representations. The 80286
+provides string manipulation instructions to move, examine, or modify a
+string (see section 3.7, "Character Translation and String Instructions").
+
+If the 80287 numeric processor extension (NPX) is present in the system ──
+see the 80287 NPX book──the 80286 architecture also supports floating point
+numbers, 32- and 64-bit integers, and 18-digit BCD data types.
+
+The 80287 Numeric Data Processor supports and stores real numbers in a
+three-field binary format as required by IEEE standard 754 for floating
+point numerics (see figure 2-3). The number's significant digits are held
+in the significand field, the exponent field locates the binary point within
+the significant digits (and therefore determines the number's magnitude),
+and the sign field indicates whether the number is positive or negative.
+(The exponent and significand are analogous to the terms "characteristic"
+and "mantissa," typically used to describe floating point numbers on some
+computers.) This format is used by the 80287 with various length
+significands and exponents to support single precision, double precision and
+extended (80-bit) precision floating point data types. Negative numbers
+differ from positive numbers only in their sign bits.
+
+
+Figure 2-1. Segmented Virtual Memory
+
+┌─ ── ── ── ── ── ── ── ── ┐
+ 20000╔════════════════╗ 8000╔═══════════════╗
+│ ║CS ║ │ ║ ║ 8600╔═══════════════╗
+ ║ MAIN ║ ║ PROCEDURE A ║ ║ PROCEDURE ║
+│ ║ PROCEDURE ║ │ ║ ║ ║ B ║
+ 0╚════════════════╝ 0╚═══════════════╝ 0╚═══════════════╝
+│ │
+ ╔════════════════╗ 72535╔═══════════════╗ ╔═══════════════╗
+│ ║DS ║ │ ║ ║ ║ ║
+ ║ DATA (MAIN) ║ ║ DATA (A) ║ ║ DATA (B) ║
+│ 0╚════════════════╝ │ 0╚═══════════════╝ 0╚═══════════════╝
+ 2000╔════════════════╗
+│ ║SS PROCESS ║ │
+ ║ STACK ║
+│ 0╚════════════════╝ │
+ ╔════════════════╗
+│ ║ES PROCESS-WIDE ║ │
+ ║ DATA ║
+│ 0╚════════════════╝ │
+└─ ── ── ── ── ── ── ── ── ┘
+ CURRENTLY ACCESSIBLE
+
+
+Figure 2-2. Bytes and Words in Memory
+
+BYTE
+ADDRESS
+All values in hexadecimal. MEMORY VALUES
+ • •
+ ╠═══════════════════════╣
+ E ║ ║
+ ╠═══════════════════════╣
+ D ║ ║
+ ╠═══════════════════════╣
+ C ║ FE ║─┐
+ ╠═══════════════════════╣ ├─ WORD AT ADDRESS B CONTAINS FE06
+ B ║ 06 ║─┘
+ ╠═══════════════════════╣
+ A ║ ║
+ ╠═══════════════════════╣─┐
+ 9 ║ 1F ║ ├─BYTE AT ADDRESS 9 CONTAINS 1F
+ ╠═══════════════════════╣─┘
+ 8 ║ ║
+ ╠═══════════════════════╣
+ 7 ║ 23 ║─┐
+ ╠═══════════════════════╣ ├─ WORD AT ADDRESS 6 CONTAINS 23OB
+ 6 ║ OB ║─┘
+ ╠═══════════════════════╣
+ 5 ║ ║
+ ╠═══════════════════════╣
+ 4 ║ ║
+ ╠═══════════════════════╣
+ 3 ║ 74 ║ ─┐
+ ╠═══════════════════════╣─┐├─ WORD AT ADDRESS 2 CONTAINS 74CB
+ 2 ║ CB ║ ─┘
+ ╠═══════════════════════╣ ├─ WORD AT ADDRESS 1 CONTAINS CB31
+ 1 ║ 31 ║ │
+ ╠═══════════════════════╣─┘
+ 0 ║ ║
+ ╚═══════════════════════╝
+
+
+Figure 2-3. 80286/80287 Supported Data Types
+
+ +1 0
+ 7 0 7 0 15 14 8 7 0
+ SIGNED ╔╤╤╤╤╤╤╤╗ UNSIGNED ╔╤╤╤╤╤╤╤╗ SIGNED ╔╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╗
+ BYTE ║│ │ ║ BYTE ║ │ ║ WORD ║│ │ │ │ ║
+ ╚╧══════╝ ╚═══════╝ ╚╧══════╧═══════╝
+ SIGN BIT┘└──────┘ │└MSB │ SIGN BIT┘└MSB │
+ MAGNITUDE └───────┘ └───────────────┘
+ MAGNITUDE MAGNITUDE
+
+ +3 +2 +1 0
+ 31 16 15 0
+ SIGNED DOUBLE WORD
+Supported by 80287 numeric data processor configuration.
+ ╔╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╗
+ ║│ │ │ │ │ │ │ │ ║
+ ╚╧══════╧═══════╧═══════╧═══════╝
+ SIGN BIT┘└MBS │
+ └───────────────────────────────┘
+ MAGNITUDE
+
+ +7 +6 +5 +4 +3 +2 +1 0
+ 63 48 47 32 31 16 15 0
+ SIGNED QUAD WORD
+Supported by 80287 numeric data processor configuration.
+ ╔╤══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╗
+ ║│ │ │ │ │ │ │ │ ║
+ ╚╧══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╝
+ SIGN BIT┘└MSB │
+ └──────────────────────────────┘
+ MAGNITUDE
+
+ +1 0
+ 15 0
+ UNSIGNED WORD ╔╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╗
+ ║│ │ │ │ ║
+ ╚╧══════╧═══════╝
+ │└MSB │
+ └───────────────┘
+ MAGNITUDE
+
+ +N +1 0
+ 7 0 7 0 7 0
+ BINARY CODED DECIMAL ╔╤╤╤╤╤╤╤╗ ╔╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╗
+ (BCD) ║ │ ║ ••• ║ │ │ │ ║
+ ╚═══════╝ ╚═══════╧═══════╝
+ BCD BCD BCD
+ DIGIT N DIGIT 1 DIGIT 0
+
+ +N +1 0
+ 7 0 7 0 7 0
+ ASCII ╔╤╤╤╤╤╤╤╗ ╔╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╗
+ ║ │ ║ ••• ║ │ │ │ ║
+ ╚═══════╝ ╚═══════╧═══════╝
+ ASCII ASCII ASCII
+ CHARACTER[N] CHARACTER{1} CHARACTER{0}
+
+ +N +1 0
+ 7 0 7 0 7 0
+ PACKED BCD ╔╤╤╤╤╤╤╤╗ ╔╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╗
+ ║ │ ║ ••• ║ │ │ │ ║
+ ╚═══════╝ ╚═══════╧═══════╝
+ └───┘ └───┘
+ MOST LEAST
+ SIGNIFICANT SIGNIFICANT
+ DIGIT DIGIT
+
+ +N +1 0
+ 7/15 0 7/15 0 7/15 0
+ STRING ╔╤╤╤╤╤╤╤╗ ╔╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╗
+ ║ │ ║ ••• ║ │ │ │ ║
+ ╚═══════╝ ╚═══════╧═══════╝
+ BYTE/WORD N BYTE/WORD BYTE/WORD
+ 1 0
+
+ +3 +2 +1 0
+ 31 16 15 0
+ POINTER ╔╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╗
+ ║│ │ │ │ │ │ │ │ ║
+ ╚╧══════╧═══════╧═══════╧═══════╝
+ └───────────────┴───────────────┘
+ SELECTOR OFFSET
+
+ +9 +8 +7 +6 +5 +4 +3 +2 +1 0
+ 79 0
+ FLOATING POINT
+Supported by 80287 numeric data processor configuration.
+ ╔╤══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╗
+ ║│ │ │ │ │ │ │ │ │ │ ║
+ ╚╧══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╝
+ SIGN BIT┘└──────────┴───────────────────────────┘
+ EXPONENT MAGNITUDE
+
+
+2.3 Registers
+
+The 80286 contains a total of fourteen registers that are of interest to
+the application programmer. (Five additional registers used by system
+programmers are covered in section 10.1.) As shown in figure 2-4, these
+registers may be grouped into four basic categories:
+
+ ■ General registers. These eight 16-bit general-purpose registers are
+ used primarily to contain operands for arithmetic and logical
+ operations.
+
+ ■ Segment registers. These four special-purpose registers determine, at
+ any given time, which segments of memory are currently addressable.
+
+ ■ Status and Control registers. These three special-purpose registers
+ are used to record and alter certain aspects of the 80286 processor
+ state.
+
+
+2.3.1 General Registers
+
+The general registers of the 80286 are the 16-bit registers AX, BX, CX, DX,
+SP, BP, SI, and DI. These registers are used interchangeably to contain the
+operands of logical and arithmetic operations.
+
+Some instructions and addressing modes (see section 2.4), however, dedicate
+certain general registers to specific uses. BX and BP are often used to
+contain the base address of data structures in memory (for example, the
+starting address of an array); for this reason, they are often referred to
+as the base registers. Similarly, SI and DI are often used to contain an
+index value that will be incremented to step through a data structure; these
+two registers are called the index registers. Finally, SP and BP are used
+for stack manipulation. Both SP and BP normally contain offsets into the
+current stack. SP generally contains the offset of the top of the stack and
+BP contains the offset or base address of the current stack frame. The use
+of these general-purpose registers for operand addressing is discussed in
+section 2.3.3, "Index, Pointer, and Base Registers." Register usage for
+individual instructions is discussed in chapters 3 and 4.
+
+As shown in figure 2-4, eight byte registers overlap four of the 16-bit
+general registers. These registers are named AH, BH, CH, and DH (high
+bytes); and AL, BL, CL, and DL (low bytes); they overlap AX, BX, CX, and DX.
+These registers can be used either in their entirety or as individual 8-bit
+registers. This dual interpretation simplifies the handling of both 8- and
+16-bit data elements.
+
+
+Figure 2-4. 80286 Base Architecture Register Set
+
+ 16-BIT SPECIAL
+ REGISTER REGISTER
+ NAME FUNCTIONS
+GENERAL REGISTERS 7 0 7 0
+ ┌─ ╔══════╤══════╗─┐
+ │ AX ║ AH │ AL ║ │
+ BYTE │ ╟──────┼──────╢ ├─MULTIPLY/DIVIDE
+ ADDRESSABLE │ DX ║ DH │ DL ║ │ I/O INSTRUCTIONS
+ (8-BIT─┤ ╟──────┼──────╢═╡
+ REGISTER │ CX ║ CH │ CL ║ ├─LOOP/SHIFT/REPEAT COUNT
+ NAMES │ ╟──────┼──────╢═╡
+ SHOWN) │ BX ║ BH │ BL ║ │
+ └─ ╟──────┴──────╢ ├─BASE REGISTERS
+ BP ║ ║ │
+ ╟─────────────╢═╡
+ SI ║ ║ │
+ ╟─────────────╢ ├─INDEX REGISTERS
+ DI ║ ║ │
+ ╟─────────────╢═╡
+ SP ║ ║ ├─STACK POINTER
+ ╚═════════════╝─┘
+ 15 0
+
+SEGMENT REGISTERS 15 0
+ ╔═════════════╗
+ CS ║ ║ CODE SEGMENT SELECTOR
+ ╟─────────────╢
+ DS ║ ║ DATA SEGMENT SELECTOR
+ ╟─────────────╢
+ SS ║ ║ STACK SEGMENT SELECTOR
+ ╟─────────────╢
+ ES ║ ║ EXTRA SEGMENT SELECTOR
+ ╚═════════════╝
+
+STATUS AND CONTROL 15 0
+ REGISTERS ╔═════════════╗
+ F ║ ║ FLAGS
+ ╟─────────────╢
+ IP ║ ║ INSTRUCTION POINTER
+ ╟─────────────╢
+ MSW ║ ║ MACHINE STATUS WORD
+ ╚═════════════╝
+
+
+2.3.2 Memory Segmentation and Segment Registers
+
+Complete programs generally consist of many different code modules (or
+segments), and different types of data segments. However, at any given time
+during program execution, only a small subset of a program's segments are
+actually in use. Generally, this subset will include code, data, and
+possibly a stack. The 80286 architecture takes advantage of this by
+providing mechanisms to support direct access to the working set of a
+program's execution environment and access to additional segments on
+demand.
+
+At any given instant, four segments of memory are immediately accessible to
+an executing 80286 program. The segment registers DS, ES, SS, and CS are
+used to identify these four current segments. Each of these registers
+specifies a particular kind of segment, as characterized by the associated
+mnemonics ("code," "stack," "data," or "extra") shown in figure 2-4.
+
+An executing program is provided with concurrent access to the four
+individual segments of memory──a code segment, a stack segment, and two
+data segments──by means of the four segment registers. Each may be said to
+select a segment, since it uniquely determines the one particular segment
+from among the numerous segments in memory, which is to be immediately
+accessible at highest speed. Thus, the 16-bit contents of a segment register
+is called a segment selector.
+
+Once a segment is selected, a base address is associated with it. To
+address an element within a segment, a 16-bit offset from the segment's base
+address must be supplied. The 16-bit segment selector and the 16-bit offset
+taken together form the high and low order halves, respectively, of a
+32-bit virtual address pointer. Once a segment is selected, only the lower
+16-bits of the pointer, called the offset, generally need to be specified by
+an instruction. Simple rules define which segment register is used to form
+an address when only a 16-bit offset is specified.
+
+An executing program requires, first of all, that its instructions reside
+somewhere in memory. The segment of memory containing the currently
+executing sequence of instructions is known as the current code segment; it
+is specified by means of the CS register. All instructions are fetched from
+this code segment, using as an offset the contents of the instruction
+pointer (IP). The CS:IP register combination therefore forms the full 32-bit
+pointer for the next sequential program instruction. The CS register is
+manipulated indirectly. Transitions from one code segment to another (e.g.,
+a procedure call) are effected implicitly as the result of control-transfer
+instructions, interrupts, and trap operations.
+
+Stacks play a fundamental role in the 80286 architecture; subroutine calls,
+for example, involve a number of implicit stack operations. Thus, an
+executing program will generally require a region of memory for its stack.
+The segment containing this region is known as the current stack segment,
+and it is specified by means of the SS register. All stack operations are
+performed within this segment, usually in terms of address offsets contained
+in the stack pointer (SP) and stack frame base (BP) registers. Unlike CS,
+the SS register can be loaded explicitly for dynamic stack definition.
+
+Beyond their code and stack requirements, most programs must also fetch and
+store data in memory. The DS and ES registers allow the specification of two
+data segments, each addressable by the currently executing program.
+Accessibility to two separate data areas supports differentiation and
+access requirements like local procedure data and global process data. An
+operand within a data segment is addressed by specifying its offset either
+directly in an instruction or indirectly via index and/or base registers
+(described in the next subsection).
+
+Depending on the data structure (e.g., the way data is parceled into one or
+more segments), a program may require access to multiple data segments. To
+access additional segments, the DS and ES registers can be loaded under
+program control during the course of a program's execution. This simply
+requires loading the appropriate data pointer prior to accessing the data.
+
+The interpretation of segment selector values depends on the operating mode
+of the processor. In Real Address Mode, a segment selector is a physical
+address (figure 2-5). In Protected Mode, a segment selector selects a
+segment of the user's virtual address space (figure 2-6). An intervening
+level of logical-to-physical address translation converts the logical
+address to a physical memory address. Chapter 6, "Memory Management,"
+provides a detailed discussion of Protected Mode addressing. In general,
+considerations of selector formats and the details of memory mapping need
+not concern the application programmer.
+
+
+2.3.3 Index, Pointer, and Base Registers
+
+Five of the general-purpose registers are available for offset address
+calculations. These five registers, shown in figure 2-4, are SP, BP, BX,
+SI, and DI. SP is called a pointer register; BP and BX are called base
+registers; SI and DI are called index registers.
+
+As described in the previous section, segment registers define the set of
+four segments currently addressable by a program. A pointer, base, or index
+register may contain an offset value relative to the start of one of these
+segments; it thereby points to a particular operand's location within that
+segment. To allow for efficient computations of effective address offsets,
+all base and index registers may participate interchangeably as operands in
+most arithmetical operations.
+
+Stack operations are facilitated by the stack pointer (SP) and stack frame
+base (BP) registers. By specifying offsets into the current stack segment,
+each of these registers provides access to data on the stack. The SP
+register is the customary top-of-stack pointer, addressing the uppermost
+datum on a push-down stack. It is referenced implicitly by PUSH and POP
+operations, subroutine calls, and interrupt operations. The BP register
+provides yet another offset into the stack segment. The existence of this
+stack relative base register, in conjunction with certain addressing modes
+described in section 2.4.3, is particularly useful for accessing data
+structures, variables and dynamically allocated work space within the stack.
+
+Stacks in the 80286 are implemented in memory and are located by the stack
+segment register (SS) and the stack pointer register (SP). A system may have
+an unlimited number of stacks, and a stack may be up to 64K bytes long, the
+maximum length of a segment.
+
+One stack is directly addressable at a time; this is the current stack,
+often referred to simply as "the" stack. SP contains the current top of the
+stack (TOS). In other words, SP contains the offset to the top of the push
+down stack from the stack segment's base address. Note, however, that the
+stack's base address (contained in SS) is not the "bottom" of the stack
+(figure 2-7).
+
+80286 stack entries are 16 bits wide. Instructions operate on the stack by
+adding and removing stack items one word at a time. An item is pushed onto
+the stack (see figure 2-8) by decrementing SP by 2 and writing the item at
+the new TOS. An item is popped off the stack by copying it from TOS and then
+incrementing SP by 2. In other words, the stack grows down in memory toward
+its base address. Stack operations never move items on the stack; nor do
+they erase them. The top of the stack changes only as a result of updating
+the stack pointer.
+
+The stack frame base pointer (BP) is often used to access elements on the
+stack relative to a fixed point on the stack rather than relative to the
+current TOS. It typically identifies the base address of the current
+stack frame established for the current procedure (figure 2-9). If an index
+register is used relative to BP (e.g., base + index addressing mode using BP
+as the base), the offset will be calculated automatically in the current
+stack segment.
+
+Accessing data structures in data segments is facilitated by the BX
+register, which has the same function in addressing operands within data
+segments that BP does for stack segments. They are called base registers
+because they may contain an offset to the base of a data structure. The
+similar usage of these two registers is especially important when discussing
+addressing modes (see section 2.4, "Addressing Modes").
+
+Operations on data are also facilitated by the SI and DI registers. By
+specifying an offset relative to the start of the currently addressable data
+segment, an index register can be used to address an operand in the segment.
+If an index register is used in conjunction with the BX base register
+(i.e., base + index addressing) to form an offset address, the data is also
+assumed to reside in the current data segment. As a rule, data referenced
+through an index register or BX is presumed to reside in the current data
+segment. That is, if an instruction invokes addressing for one of its
+operands using either BX, DI, SI, or BX with SI or DI, the contents of the
+register(s) (BX, DI, or SI) implicitly specify an offset in the current data
+segment. As previously mentioned, data referenced via SP, BP or BP with SI
+or DI implicitly specify an operand in the current stack segment (refer to
+table 2-1).
+
+There are two exceptions to the rules listed above. The first concerns the
+operation of certain 80286 string instructions. For the most flexibility,
+these instructions assume that the DI register addresses destination strings
+not in the data segment, but rather in the extra segment (ES register).
+This allows movement of strings between different segments. This has led to
+the descriptive names "source index" and "destination index." In all cases
+other than string instructions, however, the SI and DI registers may be used
+interchangeably to reference either source or destination operands.
+
+A second more general override capability allows the programmer complete
+control of which segment is used for a specific operation. Segment-override
+prefixes, discussed in section 2.4.3, allow the index and base registers to
+address data in any of the four currently addressable segments.
+
+
+Table 2-1. Implied Segment Usage by Index, Pointer, and Base Registers
+
+ Register Implied Segment
+ SP SS
+ BP SS
+ BX DS
+ DI DS, ES for String Operations
+ BP + SI, DI SS
+ BX + SI, DI DS
+
+────────────────────────────────────────────────────────────────────────────
+NOTE
+ All implied Segment usage, except SP to SS and DI to ES for String
+ Operations, may be explicitly specified with a segment override prefix for
+ any of the four segments. The prefix precedes the instruction for which
+ explicit reference is desired.
+────────────────────────────────────────────────────────────────────────────
+
+
+Figure 2-5. Real Address Mode Segment Selector Interpretation
+
+ ╔═══════════════╗─┐
+ ║ ║ │
+ ║ ║ │
+ ┌─╠═══════════════╣ │ 1 MEGABYTE
+ SEGMENT 64K BYTES ─┤ ║ SEG 1 ║ ├─ PHYSICAL
+ ┌──────────────────────►└─╠═══════════════╣ │ ADDRESS
+ │ BASE ADDRESS ║ ║ │ SPACE
+ │ ║ ║ │
+ ╔═════╧══════╤══════╗ ║ ║ │
+ ║ SELECTOR │ 0000 ║ ╚═══════════════╝─┘
+ ╚════════════╧══════╝
+
+───────────────────────────────────────────────────────────────────────────
+NOTES:
+ 1. The selector inentifies a segment in physical memory.
+ 2. A selector specifies the segments base address, Modulo 16, within
+ the 1 Megabyte address space.
+ 3. The selector is the 16 most significant bits of a segments physical
+ base address.
+ 4. The values of selectors determines the amount they overlap in real
+ memory.
+ 5. Segments may overlap by increments of 16 bytes. Overlap ranges from
+ complete (SEG 1 = SEG 1) to none (SEG 1 ╪ SEG 2 ± 64K).
+───────────────────────────────────────────────────────────────────────────
+
+
+Figure 2-6. Protected Mode Segment Selector Interpretation
+
+ ╔════════════╗─┐
+ ║ SEG 3FFF ║ │
+ ╠════════════╣ │
+ ║ SEG 3FFE ║ │
+ ┌───────────────────────────►╠════════════╣ │
+ ╔═══════╧══════╗ ║ SEG 3FFD ║ │
+ ║ SELECTOR ║ ┌─╠════════════╣ │
+ ╚══════════════╝ 1 TO 64K BYTES─┤ ║ SEG 3FFC ║ │
+ └─╠════════════╣ │
+ ║ SEG 3FFB ║ │
+ ╠════════════╣ │ 1 GIGABYTE
+ ≈ ≈ ├─ VIRTUAL
+ ╠════════════╣ │ ADDRESS
+ ║ SEG 4 ║ │ SPACE
+ ╠════════════╣ │
+ ║ SEG 3 ║ │
+ ╠════════════╣ │
+ ║ SEG 2 ║ │
+ ╠════════════╣ │
+ ║ SEG 1 ║ │
+ ╠════════════╣ │
+ ║ SEG 0 ║ │
+ ╚════════════╝─┘
+
+───────────────────────────────────────────────────────────────────────────
+NOTES:
+ 1. A selector uniquely identifies (names) one of 16K possible segments
+ in the task's virtual address space.
+ 2. The selector value does not specify the segment's location in
+ physical memory.
+ 3. The selector does not imply any overlap with other segments (This
+ depends on the base address of the segment via the memory management
+ and protection information).
+───────────────────────────────────────────────────────────────────────────
+
+
+Figure 2-7. 80286 Stack
+
+ ╔═════════════════╗ LOGICAL
+ ║ ║◄─── BOTTOM OF STACK
+ ╠═════════════════╣ (initial SP value)
+ ║ ║
+ ╠═════════════════╣
+ ║ ║
+ ╠═════════════════╣
+ ║ ║ ▲ POP-UP
+ ╠═════════════════╣ │
+ ┌───────────►║ ║◄─── LOGICAL TOP OF STACK
+ │ ╠═════════════════╣ │
+ │ ║ ║ ▼ PUSH-DOWN
+ ╔══════╤═══╧══╗ ║ ║
+ ║ SS │ SP ║ ║ ║
+ ╚══╤═══╧══════╝ ║ ║
+ │ ║ ║
+ │ ║ ║
+ │ ║ ║
+ └───────────────────►╚═════════════════╝ STACK SEGMENT BASE ADDRESS
+
+
+Figure 2-8. Stack Operation
+
+ STACK OPERATION FOR CODE SEQUENCE:
+ PUSH AX STACK
+ POP AX SEGMENT
+ POP BX ┌──────────────┐ • • ▲
+ │EXISTING STACK│ ╟─────────╢ │ BOTTOM
+ │ BEFORE PUSH │ 1062 ║ 0 0 0 0 ║ │ OF
+ └──────────────┘ ╟─────────╢ │ STACK
+ 1060 ║ 1 1 1 1 ║
+ ╟─────────╢
+ 105E ║ 2 2 2 2 ║
+ ╟─────────╢
+ 105C ║ 3 3 3 3 ║
+ ╟─────────╢
+ 105A ║ 4 4 4 4 ║
+ ╟─────────╢
+ ┌──────────────► 1058 ║ 5 5 5 5 ║
+ SS │ SP ╟─────────╢─┐
+ ╔══════════╤═════╧════╗ 1056 ║ 6 6 6 6 ║ │
+ ║ SELECTOR │ OFFSET ║ ╟─────────╢ │ NOT
+ ╚════╤═════╧══════════╝ 1054 ║ 7 7 7 7 ║ ├─ PRESENTLY
+ │ ╟─────────╢ │ USED
+ │ 1052 ║ 8 8 8 8 ║ │
+ │ ╟─────────╢─┘
+ │ 1050 ║ 9 9 9 9 ║
+ │ ≈ ≈
+ └──────────────────────────► 0000 ╟─────────╢
+ • •
+
+ STACK
+ SEGMENT
+ • •
+ ╟─────────╢
+ 1062 ║ 0 0 0 0 ║
+ ╟─────────╢
+ 1060 ║ 1 1 1 1 ║
+ ╟─────────╢
+ 105E ║ 2 2 2 2 ║
+ ╟─────────╢
+ 105C ║ 3 3 3 3 ║
+ ╟─────────╢
+ 105A ║ 4 4 4 4 ║ PUSH AX
+ ╟─────────╢╔═════════╗
+ ┌──────────────► 1058 ║ 5 5 5 5 ║║ A A A A ║
+ SS │ SP ╟─────────╢╚══╤══════╝
+ ╔══════════╤═════╧════╗ 1056 ║ A A A A ║◄──┘
+ ║ SELECTOR │ OFFSET ║ ╟─────────╢
+ ╚════╤═════╧══════════╝ 1054 ║ 7 7 7 7 ║
+ │ ╟─────────╢
+ │ 1052 ║ 8 8 8 8 ║
+ │ ╟─────────╢
+ │ 1050 ║ 9 9 9 9 ║
+ │ ≈ ≈
+ └──────────────────────────► 0000 ╟─────────╢
+ • •
+
+ STACK
+ SEGMENT
+ • •
+ ╟─────────╢
+ 1062 ║ 0 0 0 0 ║
+ ╟─────────╢
+ 1060 ║ 1 1 1 1 ║
+ ╟─────────╢
+ 105E ║ 2 2 2 2 ║
+ ╟─────────╢ POP BX
+ 105C ║ 3 3 3 3 ║ ╔═════════╗
+ ╟─────────╢ ║ 5 5 5 5 ║
+ 105A ║ 4 4 4 4 ║ ╚═════════╝
+ ╟─────────╢ ▲
+ ┌──────────────► 1058 ║ 5 5 5 5 ║──────┘
+ SS │ SP ╟─────────╢
+ ╔══════════╤═════╧════╗ 1056 ║ A A A A ║──────┐
+ ║ SELECTOR │ OFFSET ║ ╟─────────╢ ▼
+ ╚════╤═════╧══════════╝ 1054 ║ 7 7 7 7 ║ ╔═════════╗
+ │ ╟─────────╢ ║ A A A A ║
+ │ 1052 ║ 8 8 8 8 ║ ╚═════════╝
+ │ ╟─────────╢ POP AX
+ │ 1050 ║ 9 9 9 9 ║
+ │ ≈ ≈
+ └──────────────────────────► 0000 ╟─────────╢
+ • •
+
+
+Figure 2-9. BP Usage as a Stack Frame Base Pointer
+
+BP is a constant pointer to stack based variables and work space. All
+references use BP and are independent of SP, which may vary during a routine
+execution.
+
+PROC N
+ PUSH AX
+ PUSH ARRAY_SIZE
+ CALL PROC_N 1 ─────────► PROC_N+1
+ ◄───────┐ PUSH BP
+ │ PUSH CX
+ │ MOVE BP, SP
+ │ SUB SP, WORK_SPACE
+ │ ∙
+ │ ∙
+ │ ∙
+ │ "PROCEDURE BODY"
+ │ ∙
+ │ ∙
+ │ ∙
+ │ MOV SP, BP
+ │ POP CX
+ │ POP BP
+ └─── RET
+
+ • •
+ ╠═════════════╣─┐
+ ║ PARAMETERS ║ │
+ ╟─────────────╢ │
+ ║ RETURN ADDR ║ │
+ ╟─────────────╢ ├─PROCEDURE N
+ ╔ ═ ═╗ ║ REGISTERS ║ │ STACK FRAME
+ BP ─────────►╟─────────────╢ │
+ ╚═ ═ ╝ ║ ║ │ PROCEDURE
+ ▲ ║ WORK_SPACE ║ │ N+1 STACK
+ BOTTOM │ ╟─────────────╢═╡ FRAME
+ OF │ ║ PARAMETERS ║ ├──────┘
+ STACK │ ╟─────────────╢ │ DYNAMICALLY
+ ║ RETURN ADDR ║ │ ALLOCATED
+ ╟─────────────╢ │ ON DEMAND
+ ╔════╗ ║ REGISTERS ║ │ RATHER THAN
+ ║ BP ╟─────────►╟─────────────╢ │┐STATICALLY
+ ╚════╝ ║ ║ │├─────┘
+ ║ WORK_SPACE ║ ││
+ ┌─ ── ── ── ─►╟─────────────╢─┘┘ ◄───┐
+ ├─ ── ── ── ─►║ ║ TOP OF STACK
+ ╔══════╤═══╧══╗ ║ ║
+ ║ SS │ SP ║ ╚═════════════╝ STACK SEGMENT BASE
+ ╚══════╧══════╝
+
+
+2.3.4 Status and Control Registers
+
+Two status and control registers are of immediate concern to applications
+programmers: the instruction pointer and the FLAGS registers.
+
+The instruction pointer register (IP) contains the offset address, relative
+to the start of the current code segment, of the next sequential instruction
+to be executed. Together, the CS:IP registers thus define a 32-bit
+program-counter. The instruction pointer is not directly visible to the
+programmer; it is controlled implicitly, by interrupts, traps, and
+control-transfer operations.
+
+The FLAGS register encompasses eleven flag fields, mostly one-bit wide, as
+shown in figure 2-10. Six of the flags are status flags that record
+processor status information. The status flags are affected by the execution
+of arithmetic and logical instructions. The carry flag is also modifiable
+with instructions that will clear, set or complement this flag bit. See
+Chapters 3 and 4.
+
+The carry flag (CF) generally indicates a carry or borrow out of the most
+significant bit of an 8- or 16-bit operand after performing an arithmetic
+operation; this flag is also useful for bit manipulation operations
+involving the shift and rotate instructions. The effect on the remaining
+status flags, when defined for a particular instruction, is generally as
+follows: the zero flag (ZF) indicates a zero result when set; the sign flag
+(SF) indicates whether the result was negative (SF=1) or positive (SF=0);
+when set, the overflow flag (OF) indicates whether an operation results in
+a carry into the high order bit of the result but not a carry out of the
+high-order bit, or vice versa; the parity flag (PF) indicates whether the
+modulo 2 sum of the low-order eight bits of the operation is even (PF=0) or
+odd (PF=1) parity. The auxiliary carry flag (AF) represents a carry out of
+or borrow into the least significant 4-bit digit when performing binary
+coded decimal (BCD) arithmetic.
+
+The FLAGS register also contains three control flags that are used, under
+program control, to direct certain processor operations. The
+interrupt-enable flag (IF), if set, enables external interrupts; otherwise,
+interrupts are disabled. The trap flag (TF), if set, puts the processor
+into a single-step mode for debugging purposes where the target program is
+automatically interrupted to a user supplied debug routine after the
+execution of each target program instruction. The direction flag (DF)
+controls the forward or backward direction of string operations: 0 = forward
+or auto increment the address register(s) (SI, DI or SI and DI),
+1 = backward or auto-decrement the address register(s) (SI, DI or SI
+and DI).
+
+In general, the interrupt enable flag may be set or reset with special
+instructions (STI = set, CLI = clear) or by placing the flags on the stack,
+modifying the stack, and returning the flag image from the stack to the flag
+register. If operating in Protected Mode, the ability to alter the IF bit
+is subject to protection checks to prevent non-privileged programs from
+effecting the interrupt state of the CPU. This applies to both instruction
+and stack options for modifying the IF bit.
+
+The TF flag may only be modified by copying the flag register to the stack,
+setting the TF bit in the stack image, and returning the modified stack
+image to the flag register. The trap interrupt occurs on completion of the
+next instruction. Entry to the single step routine saves the flag register
+on the stack with the TF bit set, and resets the TF bit in the register.
+After completion of the single step routine, the TF bit is automatically set
+on return to the program being single stepped to interrupt the program again
+after completion of the next instruction. Use of TF is not inhibited by the
+protection mechanism in Protected Mode.
+
+The DF flag, like the IF flag, is controlled by instructions (CLD = clear,
+STD = set) or flag register modification through the stack. Typically,
+routines that use string instructions will save the flags on the stack,
+modify DF as necessary via the instructions provided, and restore DF to its
+original state by restoring the Flag register from the stack before
+returning. Access or control of the DF flag is not inhibited by the
+protection mechanism in Protected Mode.
+
+The Special Fields bits are only relevant in Protected Mode. Real Address
+Mode programs should treat these bits as don't-care's, making no assumption
+about their status. Attempts to modify the IOPL and NT fields are subject to
+protection checking in Protected Mode. In general, the application's
+programmer will not be able to and should not attempt to modify these bits.
+(See section 10.3, "Privileged and Trusted Instructions" for more details.)
+
+
+Figure 2-10. Flags Register
+
+ STATUS FLAGS:
+ CARRY────────────────────────────────────────────────┐
+ PARITY─────────────────────────────────────────┐ │
+ AUXILLIARY CARRY─────────────────────────┐ │ │
+ ZERO───────────────────────────────┐ │ │ │
+ SIGN────────────────────────────┐ │ │ │ │
+ OVERFLOW────────────┐ │ │ │ │ │
+ │ │ │ │ │ │
+ 15 14 13 12▼11 10 9 8▼ 7▼ 6 5▼ 4 3▼ 2 1▼ 0
+ ╔══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╗
+ FLAGS:║▒▒│NT│IOPL │OF│DF│IF│TF│SF│ZF│▒▒│AF│▒▒│PF│▒▒│CF║
+ ╚══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╝
+ ▲ ▲ ▲ ▲ ▲
+ │ │ │ │ │ CONTROL FLAGS:
+ │ │ │ │ └───────────TRAP FLAG
+ │ │ │ └──────────────INTERRUPT ENABLE
+ │ │ └─────────────────DIRECTION FLAG
+ │ │ SPECIAL FIELDS:
+ │ └─────────────────────────I/O PRIVILEGE LEVEL
+ └─────────────────────────────NESTED TASK FLAG
+
+
+2.4 Addressing Modes
+
+The information encoded in an 80286 instruction includes a specification of
+the operation to be performed, the type of the operands to be manipulated,
+and the location of these operands. If an operand is located in memory, the
+instruction must also select, explicitly or implicitly, which of the
+currently addressable segments contains the operand. This section covers the
+operand addressing mechanisms; 80286 operators are discussed in Chapter 3.
+
+The five elements of a general instruction are briefly described below. The
+exact format of 80286 instructions is specified in Appendix B.
+
+ ■ The opcode is present in all instructions; in fact, it is the only
+ required element. Its principal function is the specification of the
+ operation performed by the instruction.
+
+ ■ A register specifier.
+
+ ■ The addressing mode specifier, when present, is used to specify the
+ addressing mode of an operand for referencing data or performing
+ indirect calls or jumps.
+
+ ■ The displacement, when present, is used to compute the effective
+ address of an operand in memory.
+
+ ■ The immediate operand, when present, directly specifies one operand of
+ the instruction.
+
+Of the four elements, only one, the opcode, is always present. The other
+elements may or may not be present, depending on the particular operation
+involved and on the location and type of the operands.
+
+
+2.4.1 Operands
+
+Generally speaking, an instruction is an operation performed on zero, one,
+or two operands, which are the data manipulated by the instruction. An
+operand can be located either in a register (AX, BX, CX, DX, SI, DI, SP, or
+BP in the case of 16-bit operands; AH, AL, BH, BL, CH, CL, DH, or DL in the
+case of 8-bit operands; the FLAG register for flag operations in the
+instruction itself (as an immediate operand)), or in memory or an I/O port.
+Immediate operands and operands in registers can be accessed more rapidly
+than operands in memory since memory operands must be fetched from memory
+while immediate and register operands are available in the processor.
+
+An 80286 instruction can reference zero, one, or two operands. The three
+forms are as follows:
+
+ ■ Zero-operand instructions, such as RET, NOP, and HLT. Consult Appendix
+ B.
+
+ ■ One-operand instructions, such as INC or DEC. The location of the
+ single operand can be specified implicitly, as in AAM (where the
+ register AX contains the operand), or explicitly, as in INC (where
+ the operand can be in any register or memory location). Explicitly
+ specified operands are accessed via one of the addressing modes
+ described in section 2.4.2.
+
+ ■ Two operand instructions such as MOV, ADD, XOR, etc., generally
+ overwrite one of the two participating operands with the result. A
+ distinction can thus be made between the source operand (the one left
+ unaffected by the operation) and the destination operand (the one
+ overwritten by the result). Like one-operand instructions, two-operand
+ instructions can specify the location of operands either explicitly or
+ implicitly. If an instruction contains two explicitly specified
+ operands, only one of them──either the source or the destination──can
+ be in a register or memory location. The other operand must be in a
+ register or be an immediate source operand. Special cases of
+ two-operand instructions are the string instructions and stack
+ manipulation. Both operands of some string instructions are in memory
+ and are explicitly specified. Push and pop stack operations allow
+ transfer between memory operands and the memory based stack.
+
+Thus, the two-operand instructions of the 80286 permit operations of the
+following sort:
+
+ ■ Register-to-register
+ ■ Register-to-memory
+ ■ Memory-to-register
+ ■ Immediate-to-register
+ ■ Immediate-to-memory
+ ■ Memory-to-memory
+
+Instructions can specify the location of their operands by means of eight
+addressing modes, which are described in sections 2.4.2 and 2.4.3.
+
+
+2.4.2 Register and Immediate Modes
+
+Two addressing modes are used to reference operands contained in registers
+and instructions:
+
+ ■ Register Operand Mode. The operand is located in one of the 16-bit
+ registers (AX, BX, CX, DX, SI, DI, SP, or BP) or in one of the 8-bit
+ general registers (AH, BH, CH, DH, AL, BL, CL, or DL).
+
+Special instructions are also included for referencing the CS, DS, ES, SS,
+and Flag registers as operands also.
+
+ ■ Immediate Operand Mode. The operand is part of the instruction itself
+ (the immediate operand element).
+
+
+2.4.3 Memory Addressing Modes
+
+Six modes are used to access operands in memory. Memory operands are
+accessed by means of a pointer consisting of a segment selector (see section
+2.3.2) and an offset, which specifies the operand's displacement in bytes
+from the beginning of the segment in which it resides. Both the segment
+selector component and the offset component are 16-bit values. (See section
+2.1 for a discussion of segmentation.) Only some instructions use a full
+32-bit address.
+
+Most memory references do not require the instruction to specify a full
+32-bit pointer address. Operands that are located within one of the
+currently addressable segments, as determined by the four segment registers
+(see section 2.3.2, "Segment Registers"), can be referenced very
+efficiently simply by means of the 16-bit offset. This form of address is
+called by short address. The choice of segment (CS, DS, ES, or SS) is either
+implicit within the instruction itself or explicitly specified by means of
+a segment override prefix (see below).
+
+See figure 2-11 for a diagram of the addressing process.
+
+
+2.4.3.1 Segment Selection
+
+All instructions that address operands in memory must specify the segment
+and the offset. For speed and compact instruction encoding, segment
+selectors are usually stored in the high speed segment registers. An
+instruction need specify only the desired segment register and an offset in
+order to address a memory operand.
+
+Most instructions need not explicitly specify which segment register is
+used. The correct segment register is automatically chosen according to the
+rules of table 2-1 and table 2-2. These rules follow the way programs are
+written (see figure 2-12) as independent modules that require areas for
+code and data, a stack, and access to external data areas.
+
+There is a close connection between the type of memory reference and the
+segment in which that operand resides (see the next section for a
+discussion of how memory addressing mode calculations are performed). As a
+rule, a memory reference implies the current data segment (i.e., the
+implicit segment selector is in DS) unless the BP register is involved in
+the address specification, in which case the current stack segment is
+implied (i.e, SS contains the selector).
+
+The 80286 instruction set defines special instruction prefix elements (see
+Appendix B). One of these is SEG, the segment-override prefix.
+Segment-override prefixes allow an explicit segment selection. Only in two
+special cases──namely, the use of DI to reference destination strings in
+the ES segment, and the use of SP to reference stack locations in the SS
+segment──is there an implied segment selection which cannot be overridden.
+The format of segment override prefixes is shown in Appendix B.
+
+
+Table 2-2 Segment Register Selection Rules
+
+Memory Reference Segment Register Implicit Segment
+ Needed Used Selection Rule
+
+Instructions Code (CS) Automatic with
+ instruction prefetch.
+
+Stack Stack (SS) All stack pushes and
+ pops. Any memory reference
+ which uses BP as a base
+ register.
+
+Local Data Data (DS) All data references
+ except when relative to
+ stack or string destination.
+
+External (Global) Extra (ES) Alternate data segment
+ Data and destination of string
+ operation.
+
+
+Figure 2-11. Two-Component Address
+
+ • •
+ POINTER ║ ║
+ ┌───────────┴───────────┐ ╠═════════════╣─┐
+ ╔═══════════╤═══════════╗ ║ ║ │
+ ║ SEGMENT │ OFFSET ║ ║ ║ │
+ ╚═══════════╧═══════════╝ ║ ║ │
+ 31 16 15 0 ╟─────────────╢ │
+ └────┬────┘ └────┬────┘ ║ OPERAND ║ │ SELECTED
+ │ │ ║ SELECTED ║ ├─ SEGMENT
+ │ └───────────────────►╟─────────────╢ │
+ │ ║ ║ │
+ │ ║ ║ │
+ │ ║ ║ │
+ │ ║ ║ │
+ └───────────────────────────────►╠═════════════╣─┘
+ ║ ║
+ • MEMORY •
+
+
+2.4.3.2 Offset Computation
+
+The offset within the desired segment is calculated in accordance with the
+desired addressing mode. The offset is calculated by taking the sum of up to
+three components:
+
+ ■ the displacement element in the instruction
+ ■ the base (contents of BX or BP──a base register)
+ ■ the index (contents of SI or DI──an index register)
+
+Each of the three components of an offset may be either a positive or
+negative value. Offsets are calculated modulo 2^(16).
+
+The six memory addressing modes are generated using various combinations of
+these three components. The six modes are used for accessing different types
+of data stored in memory:
+
+addressing mode offset calculation
+direct address displacement alone
+register indirect base or index alone
+based base + displacement
+indexed index + displacement
+based indexed base + index
+based indexed with displacement base + index + disp
+
+In all six modes, the operand is located at the specified offset within the
+selected segment. All displacements, except direct address mode, are
+optionally 8- or 16-bit values. 8-bit displacements are automatically
+sign-extended to 16 bits. The six addressing modes are described and
+demonstrated in the following section on memory addressing modes.
+
+
+Figure 2-12. Use of Memory Segmentation
+
+ ┌─ ── ─┐
+ ╔══════╗
+ ║ CODE ║
+ ╟──────╢ MODULE A
+ ║ DATA ║
+ ╚══════╝
+ CPU │ │
+ ┌───────────┐ ╔══════╗
+ │ ╔═══════╗ │ ║ CODE ║
+ │ ║ CODE ╟─┼─────────────────────────►╟──────╢ MODULE B
+ │ ╟───────╢ │ ║ DATA ║
+ │ ║ DATA ╟─┼─────────────────────────►╚══════╝
+ │ ╟───────╢ │ │ │
+ │ ║ STACK ╟─┼───────────────┐ ╔══════╗
+ │ ╟───────╢ │ │ ║ ║ PROCESS STACK
+ │ ║ EXTRA ╟─┼───────────┐ └─────────►╚══════╝
+ │ ╚═══════╝ │ │ │ │
+ │ SEGMENT │ │ ╔══════╗ PROCESS
+ │ REGISTERS │ │ ║ ║ DATA
+ └───────────┘ └─────────────►╚══════╝ BLOCK 1
+ │ │
+ ╔══════╗ PROCESS
+ ║ ║ DATA
+ ╚══════╝ BLOCK 2
+ └─ ── ─┘
+ MEMORY
+
+
+2.4.3.3 Memory Mode
+
+Two modes are used for simple scalar operands located in memory:
+
+ ■ Direct Address Mode. The offset of the operand is contained in the
+ instruction as the displacement element. The offset is a 16-bit
+ quantity.
+
+ ■ Register Indirect Mode. The offset of the operand is in one of the
+ registers SI, DI, or BX. (BP is excluded; if BP is used as a stack
+ frame base, it requires an index or displacement component to reference
+ either parameters passed on the stack or temporary variables allocated
+ on the stack. The instruction level bit encoding for the BP only
+ address mode is used to specify Direct Address mode.)
+
+The following four modes are used for accessing complex data structures in
+memory (see figure 2-13):
+
+ ■ Based Mode. The operand is located within the selected segment at an
+ offset computed as the sum of the displacement and the contents of a
+ base register (BX or BP). Based mode is often used to access the same
+ field in different copies of a structure (often called a record). The
+ base register points to the base of the structure (hence the term
+ "base" register), and the displacement selects a particular field.
+ Corresponding fields within a collection of structures can be accessed
+ simply by changing the base register. (See figure 2-13, example 1.)
+
+ ■ Indexed Mode. The operand is located within the selected segment at an
+ offset computed as the sum of the displacement and the contents of an
+ index register (SI or DI). Indexed mode is often used to access
+ elements in a static array (e.g., an array whose starting location is
+ fixed at translation time). The displacement locates the beginning of
+ the array, and the value of the index register selects one element.
+ Since all array elements are the same length, simple arithmetic on the
+ index register will select any element. (See figure 2-13, example 2.)
+
+ ■ Based Indexed Mode. The operand is located within the selected segment
+ at an offset computed as the sum of the base register's contents and an
+ index register's contents. Based Indexed mode is often used to access
+ elements of a dynamic array (i.e., an array whose base address can
+ change during execution). The base register points to the base of the
+ array, and the value of the index register is used to select one
+ element. (See figure 2-13, example 3.)
+
+ ■ Based Indexed Mode with Displacement. The operand is located with the
+ selected segment at an offset computed as the sum of a base register's
+ contents, an index register's contents, and the displacement. This mode
+ is often used to access elements of an array within a structure. For
+ example, the structure could be an activation record (i.e., a region
+ of the stack containing the register contents, parameters, and
+ variables associated with one instance of a procedure); and one
+ variable could be an array. The base register points to the start of
+ the activation record, the displacement expresses the distance from the
+ start of the record to the beginning of the array variable, and the
+ index register selects a particular element of the array. (See figure
+ 2-13, example 4.)
+
+Table 2-3 gives a summary of all memory operand addressing options.
+
+
+Table 2-3. Memory Operand Addressing Modes
+
+Addressing Mode Offset Calculation
+
+Direct 16-bit Displacement in the instruction
+Register Indirect BX, SI, DI
+Based (BX or BP) + Displacement
+The displacement can be a 0, 8 or 16-bit value.
+Indexed (SI or DI) + Displacement
+The displacement can be a 0, 8 or 16-bit value.
+Based Indexed (BX or BP) + (SI or DI)
+Based Indexed + Displacement (BX or BP) + (SI or DI) + Displacement
+The displacement can be a 0, 8 or 16-bit value.
+
+
+Figure 2-13. Complex Addressing Modes
+
+1. BASED MODE 2. INDEXED MODE
+
+MOV AX, [BP + DATE_CODE] MOV ID[SI], DX
+ADD[BX + BALANCE], CX SUB BX, DATA_TBL[SI]
+
+ • • • • F
+ ╠═══════════╣─┐ ╠═══════════╣─┐ I
+ ║ ║ │ ║ ║ │ X
+╔═══════════╗ ╟───────────╢ │ ╔═══════════╗ ╟───────────╢ │ E
+║ DISPL ╟────►║ OPERAND ║ ├─ ║ INDEX ╟────►║ OPERAND ║ ├─D
+╚═══════════╝ ╟───────────╢ │ ╚═══════════╝ ╟───────────╢ │
+ + ║ ║ │ + ║ ║ │ A
+╔═══════════╗ ┌──►╟───────────╢─┘ ╔═══════════╗ ┌──►╟───────────╢─┘ R
+║ BASE ╟─┘ ║ ║ ║ DISPL ╟─┘ ║ ║ R
+╚═══════════╝ ║ ║ ╚═══════════╝ ║ ║ A
+ + ║ ║ + ║ ║ Y
+╔═══════════╗ ║ ║ ╔═══════════╗ ║ ║
+║ SEGMENT ╟────►╚═══════════╝ ║ SEGMENT ╟────►╚═══════════╝
+╚═══════════╝ ╚═══════════╝
+
+3. BASED INDEXED 4. BASED INDEXED MODE
+ WITH DISPLACEMENT BASED
+MOV DX, [BP][DI] STRUCTURE
+AND [BX + SI], 3FFH MOV CX, [BP][SI + CNT] CONTAINING
+ SHR[BX + DI + MASK] ARRAY
+ • • B • • └─┐
+ ╠═══════════╣─┐ A ╠═══════════╣ ──┐│
+ ║ ║ │ S ║ ║ ││
+╔═══════════╗ ╟───────────╢ │ E ╔═══════════╗ ╟───────────╢─┐ ││
+║ INDEX ╟────►║ OPERAND ║ ├─D ║ INDEX ╟───┐ ║▒▒▒▒▒▒▒▒▒▒▒║ │ A ││
+╚═══════════╝ ╟───────────╢ │ ╚═══════════╝ │ ╟───────────╢ │ R ││
+ + ║ ║ │ A + └►║ OPERAND ║ ├─R ├┘
+╔═══════════╗ ┌──►╟───────────╢─┘ R ╔═══════════╗ ┌──►╟───────────╢ │ A │
+║ BASE ╟─┘ ║ ║ R ║ DISPL ╟─┘ ║▒▒▒▒▒▒▒▒▒▒▒║ │ Y │
+╚═══════════╝ ║ ║ A ╚═══════════╝ ┌►╟───────────╢─┘ │
+ + ║ ║ Y + │ ║ ║ │
+╔═══════════╗ ║ ║ ╔═══════════╗ │ ╟───────────╢ ──┘
+║ SEGMENT ╟────►╚═══════════╝ ║ BASE ╟───┘ ║ ║
+╚═══════════╝ ╚═══════════╝ ║ ║
+ + ║ ║
+ ╔═══════════╗ ║ ║
+ ║ SEGMENT ╟────►╚═══════════╝
+ ╚═══════════╝
+
+
+2.5 Input/Output
+
+The 80286 allows input/output to be performed in either of two ways: by
+means of a separate I/O address space (using specific I/O instructions) or
+by means of memory-mapped I/O (using general-purpose operand manipulation
+instructions).
+
+
+2.5.1 I/O Address Space
+
+The 80286 provides a separate I/O address space, distinct from physical
+memory, to address the input/output ports that are used for external
+devices. The I/O address space consists of 2^(16) (64K) individually
+addressable 8-bit ports. Any two consecutive 8-bit ports can be treated as
+a 16-bit port. Thus, the I/O address space can accommodate up to 64K 8-bit
+ports or up to 32K 16-bit ports. I/O port addresses 00F8H to 00FFH are
+reserved by Intel.
+
+The 80286 can transfer either 8 or 16 bits at a time to a device located in
+the I/O space. Like words in memory, 16-bit ports should be aligned at
+even-numbered addresses so that the 16 bits will be transferred in a single
+access. An 8-bit port may be located at either an even or odd address. The
+internal registers in a given peripheral controller device should be
+assigned addresses as shown below.
+
+Port Register Port Addresses Example
+
+16-bit even word addresses OUT FE,AX
+8-bit; device on
+lower half of 16-bit
+
+data bus even byte addresses IN AL,FE
+
+8-bit; device on upper
+half of 16-bit data bus odd byte addresses OUT FF,AL
+
+The I/O instructions IN and OUT (described in section 3.11.3) are provided
+to move data between I/O ports and the AX (16-bit I/O) or AL (8-bit I/O)
+general registers. The block I/O instructions INS and OUTS (described in
+section 4.1) move blocks of data between I/O ports and memory space (as
+shown below). In Protected Mode, an operating system may prevent a program
+from executing these I/O instructions. Otherwise, the function of the I/O
+instructions and the structure of the I/O space are identical for both modes
+of operation.
+
+INS es:byte ptr [di], DX
+OUTS DX, byte ptr [si]
+
+IN and OUT instructions address I/O with either a direct address to one of
+up to 256 port addresses, or indirectly via the DX register to one of up to
+64K port addresses. Block I/O uses the DX register to specify the I/O
+address and either SI or DI to designate the source or destination memory
+address. For each transfer, SI or DI are either incremented or decremented
+as specified by the direction bit in the flag word while DX is constant to
+select the I/O device.
+
+
+2.5.2 Memory-Mapped I/O
+
+I/O devices also may be placed in the 80286 memory address space. So long
+as the devices respond like memory components, they are indistinguishable to
+the processor.
+
+Memory-mapped I/O provides additional programming flexibility. Any
+instruction that references memory may be used to access an I/O port located
+in the memory space. For example, the MOV instruction can transfer data
+between any register and a port; and the AND, OR, and TEST instructions may
+be used to manipulate bits in the internal registers of a device (see
+figure 2-14). Memory-mapped I/O performed via the full instruction set
+maintains the full complement of addressing modes for selecting the desired
+I/O device.
+
+Memory-mapped I/O, like any other memory reference, is subject to access
+protection and control when executing in protected mode.
+
+
+Figure 2-14. Memory-Mapped I/O
+
+ MEMORY
+ ADDRESS SPACE
+ ╔════════════════╗ I/O DEVICE 1
+ ║ ║ ╔═════════════════════╗
+ ║ ║ ║ INTERNAL REGISTER ║
+ ╟────────────────╢─ ── ─ ── ─ ── ─║─╔═════════════════╗ ║
+ ║ ║ ║ ║ ║ ║
+ ╟────────────────╢─ ── ─ ── ─ ── ─║─╚═════════════════╝ ║
+ ║ ║ ╚═════════════════════╝
+ ║ ║
+ ║ ║ I/O DEVICE 2
+ ║ ║ ╔═════════════════════╗
+ ║ ║ ║ INTERNAL REGISTER ║
+ ║────────────────║─ ── ─ ── ─ ── ─║─╔═════════════════╗ ║
+ ║ ║ ║ ║ ║ ║
+ ║────────────────║─ ── ─ ── ─ ── ─║─╚═════════════════╝ ║
+ ║ ║ ╚═════════════════════╝
+ ║ ║
+ ╚════════════════╝
+
+
+2.6 Interrupts and Exceptions
+
+The 80286 architecture supports several mechanisms for interrupting program
+execution. Internal interrupts are synchronous events that are the responses
+of the CPU to certain events detected during the execution of an
+instruction. External interrupts are asynchronous events typically
+triggered by external devices needing attention. The 80286 supports both
+maskable (controlled by the IF flag) and non-maskable interrupts. They cause
+the processor to temporarily suspend its present program execution in order
+to service the requesting device. The major distinction between these two
+kinds of interrupts is their origin: an internal interrupt is always
+reproducible by re-executing with the program and data that caused the
+interrupt, whereas an external interrupt is generally independent of the
+currently executing task.
+
+Interrupts 0-31 are reserved by Intel.
+
+Application programmers will normally not be concerned with servicing
+external interrupts. More information on external interrupts for system
+programmers may be found in Chapter 5, section 5.2, "Interrupt Handling for
+Real Address Mode," and in Chapter 9, "Interrupts, Traps and Faults for
+Protected Virtual Address Mode."
+
+In Real Address Mode, the application programmer is affected by two kinds
+of internal interrupts. (Internal interrupts are the result of executing an
+instruction which causes the interrupt.) One type of interrupt is called an
+exception because the interrupt only occurs if a particular fault condition
+exists. The other type of interrupt generates the interrupt every time the
+instruction is executed.
+
+The exceptions are: divide error, INTO detected overflow, bounds check,
+segment overrun, invalid operation code, and processor extension error (see
+table 2-4). A divide error exception results when the instructions DIV or
+IDIV are executed with a zero denominator; otherwise, the quotient will be
+too large for the destination operand (see section 3.3.4 for a discussion
+of DIV and IDIV). An overflow exception results when the INTO instruction is
+executed and the OF flag is set (after an arithmetic operation that set the
+overflow (OF) flag). (See section 3.6.3, "Software Generated Interrupts,"
+for a discussion of INTO.) A bounds check exception results when the BOUND
+instruction is executed and the array index it checks falls outside the
+bounds of the array. (See section 4.2 for a discussion of the BOUND
+instruction.) The segment overrun exception occurs when a word memory
+reference is attempted which extends beyond the end of a segment. An invalid
+operation code exception occurs if an attempt is made to execute an
+undefined instruction operation code. A processor extension error is
+generated when a processor extension detects an illegal operation. Refer to
+Chapter 5 for a more complete description of these exception conditions.
+
+The instruction INT generates an internal interrupt whenever it is
+executed. The effects of this interrupt (and the effects of all interrupts)
+is determined by the interrupt handler routines provided by the application
+program or as part of the system software (provided by system programmers).
+See Chapter 5 for more on this topic. The INT instruction itself is
+discussed in section 3.6.3.
+
+In Protected Mode, many more fault conditions are detected and result in
+internal interrupts. Protected Mode interrupts and faults are discussed in
+Chapter 9.
+
+
+2.7 Hierarchy of Instruction Sets
+
+For descriptive purposes, the 80286 instruction set is partitioned into
+three distinct subsets: the Basic Instruction Set, the Extended Instruction
+Set, and the System Control Instruction Set. The "hierarchy" of instruction
+sets defined by this partitioning helps to clarify the relationships
+between the various processors in the 8086 family (see figure 2-15).
+
+The Basic Instruction Set, presented in Chapter 3, comprises the common
+subset of instructions found on all processors of the 8086 family. Included
+are instructions for logical and arithmetic operations, data movement,
+input/output, string manipulation, and transfer of control.
+
+The Extended Instruction Set, presented in Chapter 4, consists of those
+instructions found only on the 80186, 80188, and 80286 processors. Included
+are instructions for block structured procedure entry and exit, parameter
+validation, and block I/O transfers.
+
+The System Control Instruction Set, presented in Chapter 10, consists of
+those instructions unique to the 80286. These instructions control the
+memory management and protection mechanisms of the 80286.
+
+
+Table 2-4. 80286 Interrupt Vector Assignments (Real Address Mode)
+
+
+Function Interupt Related Return Address
+ Number Instructions Before Instruction
+ Causing Exception?
+Divide error exception 0 DIV, IDIV Yes
+Single step interrupt 1 All
+NMI interrupt 2 All
+Breakpoint interrupt 3 INT
+INTO detected overflow exception 4 INTO No
+BOUND range exceeded exception 5 BOUND Yes
+Invalid opcode exception 6 Any undefined Yes
+ opcode
+Processor extension 7 ESC or WAIT Yes
+not available exception
+Interrupt table limit 8 INT vector Yes
+too small exception is not within
+ table limit
+Processor extension segment 9 ESC with memory No
+overrun interrupt operand extending
+ beyond offset
+ FFFF(H)
+Reserved 10-12
+Segment overrun exception 13 Word memory Yes
+ reference with
+ offset = FFFF(H)
+ or an attempt to
+ execute past the
+ end of a segment
+Reserved 14, 15
+Processor extension 16 ESC or WAIT
+error interrupt
+Reserved 17-31
+User defined 32-255
+
+
+
+Figure 2-15. Hierarchy of Instructions
+
+ ╔══════════════════════╗
+ ║ ║
+ ║ ║
+ ║ ╔════════════════╗ ║
+ ║ ║ ║ ║
+ ║ ║ ╔══════════╗ ║ ║
+ ║ ║ ║ 8086 ◄╫──╫──╫──BASIC INSTRUCTION SET
+ ║ ║ ║ 8088 ║ ║ ║
+ ║ ║ ╚══════════╝ ║ ║
+ ║ ║ 80186 ◄───╫──╫──EXTENDED INSTRUCTION SET
+ ║ ║ 80188 ║ ║
+ ║ ╚════════════════╝ ║
+ ║ 80286 ◄──────╫──SYSTEM CONTROL INSTRUCTION SET
+ ║ ║
+ ╚══════════════════════╝
+
+
+Chapter 3 Basic Instruction Set
+
+───────────────────────────────────────────────────────────────────────────
+
+The base architecture of the 80286 is identical to the complete instruction
+set of the 8086, 8088, 80188, and 80186 processors. The 80286 instruction
+set includes new forms of some instructions. These new forms reduce program
+size and improve the performance and ease of implementation of source code.
+
+This chapter describes the instructions which programmers can use to write
+application software for the 80286. The following chapters describe the
+operation of more complicated I/O and system control instructions.
+
+All instructions described in this chapter are available for both Real
+Address Mode and Protected Virtual Address Mode operation. The instruction
+descriptions note any differences that exist between the operation of an
+instruction in these two modes.
+
+This chapter also describes the operation of each application
+program-relative instruction and includes an example of using the
+instruction. The Instruction Dictionary in Appendix B contains formal
+descriptions of all instructions. Any opcode pattern that is not described
+in the Instruction Dictionary is undefined and results in an opcode
+violation trap (interrupt 6).
+
+
+3.1 Data Movement Instructions
+
+These instructions provide convenient methods for moving bytes or words of
+data between memory and the registers of the base architecture.
+
+
+3.1.1 General-Purpose Data Movement Instructions
+
+MOV (Move) transfers a byte or a word from the source operand to the
+destination operand. The MOV instruction is useful for transferring data to
+a register from memory, to memory from a register, between registers,
+immediate-to-register, or immediate-to-memory. Memory-to-memory or segment
+register-to-segment register moves are not allowed.
+
+Example:
+ MOV DS,AX. Replaces the contents of register DS with the contents of
+ register AX.
+
+XCHG (Exchange) swaps the contents of two operands. This instruction takes
+the place of three MOV instructions. It does not require a temporary memory
+location to save the contents of one operand while you load the other.
+
+The XCHG instruction can swap two byte operands or two word operands, but
+not a byte for a word or a word for a byte. The operands for the XCHG
+instruction may be two register operands, or a register operand with a
+memory operand. When used with a memory operand, XCHG automatically
+activates the LOCK signal.
+
+Example:
+ XCHG BX,WORDOPRND. Swaps the contents of register BX with the contents
+ of the memory word identified by the label WORDOPRND after asserting
+ bus lock.
+
+
+3.1.2 Stack Manipulation Instructions
+
+PUSH (Push) decrements the stack pointer (SP) by two and then transfers a
+word from the source operand to the top of stack indicated by SP. See figure
+3-1. PUSH is often used to place parameters on the stack before calling a
+procedure; it is also the basic means of storing temporary variables on the
+stack. The PUSH instruction operates on memory operands, immediate operands
+(new with the 80286), and register operands (including segment registers).
+
+Example:
+ PUSH WORDOPRND. Transfers a 16-bit value from the memory word identified
+ by the label WORDOPRND to the memory location which represents the current
+ top of stack (byte transfers are not allowed).
+
+PUSHA (Push All Registers) saves the contents of the eight general
+registers on the stack. See figure 3-2. This instruction simplifies
+procedure calls by reducing the number of instructions required to retain
+the contents of the general registers for use in a procedure. PUSHA is
+complemented by POPA (see below).
+
+The processor pushes the general registers on the stack in the following
+order: AX, CX, DX, BX, the initial value of SP before AX was pushed, BP, SI,
+and DI.
+
+Example:
+ PUSHA. Pushes onto the stack the contents of the eight general registers.
+
+POP (Pop) transfers the word at the current top of stack (indicated by SP)
+to the destination operand, and then increments SP by two to point to the
+new top of stack. See figure 3-3. POP moves information from the stack to
+either a register or memory. The only restriction on POP is that it cannot
+place a value in register CS.
+
+Example:
+ POP BX. Replaces the contents of register BX with the contents of the
+ memory location at the top of stack.
+
+POPA (Pop All Registers) restores the registers saved on the stack by
+PUSHA, except that it ignores the value of SP. See figure 3-4.
+
+Example:
+ POPA. Pops from the stack the saved contents of the general registers,
+ and restores the registers (except SP) to their original state.
+
+
+Figure 3-1. PUSH
+
+ • • • •
+HIGH ADDRESS ║ ║ ║ ║
+ ╠═══════════════╣ ╠═══════════════╣ SS LIMIT
+OPERANDS FROM ║▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒║ ║▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒║
+PREVIOUS PUSH ╠═══════════════╣ ╠═══════════════╣
+INSTRUCTIONS SP─►║▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒║ ║▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒║
+ ╠═══════════════╣ ╠═══════════════╣ SP ALWAYS POINTS
+ ║ ║ ║ OPERAND ║◄─TO THE LAST WORD
+ ╠═══════════════╣ ╠═══════════════╣ PUSHED ONTO THE
+ ║ ║ ║ ║ STACK (TOS)
+ ╠═══════════════╣ ╠═══════════════╣
+ ≈ ≈ ≈ ≈
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ ║ ║ ║ SS ALWAYS POINTS
+ LOW ADDRESS ╠═══════════════╣ ╠═══════════════╣ TO LOWEST ADDRESS
+ ║ ║ ║ ║ USED BY THE STACK
+ • BEFORE • • AFTER •
+ PUSH OPERAND PUSH OPERAND
+
+ PUSH decrements SP by 2 bytes and places the operand in the stack at the
+ location to which SP points.
+
+
+Figure 3-2. PUSHA
+
+ • • • •
+ HIGH ADDRESS ║ ║ ║ ║
+ ╠═══════════════╣ ╠═══════════════╣ SS LIMIT
+OPERANDS FROM ║▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒║ ║▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒║
+PREVIOUS PUSH ╠═══════════════╣ ╠═══════════════╣
+INSTRUCTIONS ┌──►║▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒║ ║▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒║
+ │ ╠═══════════════╣ ╠═══════════════╣
+ SP──┘ ║ ║ ║ AX ║
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ ║ ║ CX ║
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ ║ ║ DX ║
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ ║ ║ BX ║
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ ║ ║ OLD SP ║
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ ║ ║ BP ║
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ ║ ║ SI ║
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ ║ ║ DI ║◄───SP
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ ║ ║ ║
+ ╠═══════════════╣ ╠═══════════════╣
+ ≈ ≈ ≈ ≈
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ ║ ║ ║
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ ║ ║ ║
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ ║ ║ ║
+ LOW ADDRESS ╠═══════════════╣ ╠═══════════════╣ SS
+ ║ ║ ║ ║
+ • • • •
+ BEFORE AFTER
+ PUSHA PUSHA
+
+ PUSHA copies the contents of the eight general registers to the stack in
+ the above order. The instruction decrements SP by 16 bytes (8 words) to
+ point to the last word pushed on the stack.
+
+
+Figure 3-3. POP
+
+ • • • •
+ HIGH ADDRESS ║ ║ ║ ║
+ ╠═══════════════╣ ╠═══════════════╣ SS LIMIT
+ OPERANDS FROM ║▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒║ ║▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒║
+ PREVIOUS PUSH ╠═══════════════╣ ╠═══════════════╣
+ INSTRUCTIONS ║▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒║ ║▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒║◄───SP
+ ╠═══════════════╣ ╠═══════════════╣
+ SP───►║ OPERAND ║ ║ ║
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ ║ ║ ║
+ ╠═══════════════╣ ╠═══════════════╣
+ ≈ ≈ ≈ ≈
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ ║ ║ ║
+ LOW ADDRESS ╠═══════════════╣ ╠═══════════════╣ SS
+ ║ ║ ║ ║
+ • BEFORE • • AFTER •
+ POP OPERAND POP OPERAND
+
+ POP copies the contents of the stack location before SP to the operand in
+ the instruction. POP then increments SP by 2 bytes (1 word).
+
+Figure 3-4. POPA
+
+ • • • •
+ HIGH ADDRESS ║ ║ ║ ║
+ ╠═══════════════╣ ╠═══════════════╣ SS LIMIT
+ OPERANDS FROM ║▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒║ ║▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒║
+ PREVIOUS PUSH ╠═══════════════╣ ╠═══════════════╣
+ INSTRUCTIONS ║▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒║ ║▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒║◄───SP
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ AX ║ ║ ║
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ CX ║ ║ ║
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ DX ║ ║ ║
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ BX ║ ║ ║
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ SP ║ ║ ║
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ BP ║ ║ ║
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ SI ║ ║ ║
+ ╠═══════════════╣ ╠═══════════════╣
+ SP───►║ DI ║ ║ ║
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ ║ ║ ║
+ ╠═══════════════╣ ╠═══════════════╣
+ ≈ ≈ ≈ ≈
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ ║ ║ ║
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ ║ ║ ║
+ ╠═══════════════╣ ╠═══════════════╣
+ ║ ║ ║ ║
+ LOW ADDRESS ╠═══════════════╣ ╠═══════════════╣ SS
+ • BEFORE • • AFTER •
+ POPA POPA
+
+ POPA copies the contents of seven stack locations to the corresponding
+ general registers. POPA discards the stored value of SP.
+
+
+3.2 Flag Operation With the Basic Instruction Set
+
+
+3.2.1 Status Flags
+
+The status flags of the FLAGS register reflect conditions that result from
+a previous instruction or instructions. The arithmetic instructions use OF,
+SF, ZF, AF, PF, and CF.
+
+The SCAS (Scan String), CMPS (Compare String), and LOOP instructions use ZF
+to signal that their operations are complete. The base architecture includes
+instructions to set, clear, and complement CF before execution of an
+arithmetic instruction. See figure 3-5 and tables 3-1 and 3-2.
+
+
+3.2.2 Control Flags
+
+The control flags of the FLAGS register determine processor operations for
+string instructions, maskable interrupts, and debugging.
+
+Setting DF (direction flag) causes string instructions to auto-decrement;
+that is, to process strings from high addresses to low addresses, or from
+"right-to-left." Clearing DF causes string instructions to auto-increment,
+or to process strings from "left-to-right."
+
+Setting IF (interrupt flag) allows the CPU to recognize external (maskable)
+interrupt requests. Clearing IF disables these interrupts. IF has no effect
+on either internally generated interrupts, nonmaskable external interrupts,
+or processor extension segment overrun interrupts.
+
+Setting TF (trap flag) puts the processor into single-step mode for
+debugging. In this mode, the CPU automatically generates an internal
+interrupt after each instruction, allowing a program to be inspected as it
+executes each instruction, instruction by instruction.
+
+
+Table 3-1. Status Flags' Functions
+
+Bit Position Name Function
+
+ 0 CF Carry Flag--Set on high-order bit carry or borrow;
+ cleared otherwise
+
+ 2 PF Parity Flag--Set if low-order eight bits of result
+ contain an even number of 1 bits; cleared otherwise
+
+ 4 AF Set on carry from or borrow to the low order four
+ bits of AL; cleared otherwise
+
+ 6 ZF Zero Flag--Set if result is zero; cleared otherwise
+
+ 7 SF Sign Flag--Set equal to high-order bit of result (0
+ if positive, 1 if negative)
+
+ 11 OF Overflow Flag--Set if result is too-large a positive
+ number or too-small a negative number (excluding
+ sign-bit) to fit in destination operand; cleared
+ otherwise
+
+
+Table 3-2. Control Flags' Functions
+
+Bit Position Name Function
+
+ 8 TF Trap (Single Step) Flag--Once set, a single step
+ interrupt occurs after the next instruction executes.
+ TF is cleared by the single step interrupt.
+
+ 9 IF Interrupt-enable Flag--When set, maskable interrupts
+ will cause the CPU to transfer control to an interrupt
+ vector-specified location.
+
+10 DF Direction Flag--Causes string instructions to auto
+ decrement the appropriate index registers when set.
+ Clearing DF causes auto increment.
+
+
+Figure 3-5. Flag Word Contents
+
+ STATUS FLAGS:
+ CARRY────────────────────────────────────────────────┐
+ PARITY─────────────────────────────────────────┐ │
+ AUXILLIARY CARRY─────────────────────────┐ │ │
+ ZERO───────────────────────────────┐ │ │ │
+ SIGN────────────────────────────┐ │ │ │ │
+ OVERFLOW────────────┐ │ │ │ │ │
+ │ │ │ │ │ │
+ 15 14 13 12▼11 10 9 8▼ 7▼ 6 5▼ 4 3▼ 2 1▼ 0
+ ╔══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╗
+ FLAGS:║▒▒│NT│IOPL │OF│DF│IF│TF│SF│ZF│▒▒│AF│▒▒│PF│▒▒│CF║
+ ╚══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╝
+ ▲ ▲ ▲ ▲ ▲
+ │ │ │ │ │ CONTROL FLAGS:
+ │ │ │ │ └───────────TRAP FLAG
+ │ │ │ └──────────────INTERRUPT ENABLE
+ │ │ └─────────────────DIRECTION FLAG
+ │ │ SPECIAL FIELDS:
+ │ └─────────────────────────I/O PRIVILEGE LEVEL
+ └─────────────────────────────NESTED TASK FLAG
+
+
+3.3 Arithmetic Instructions
+
+The arithmetic instructions of the 8086-family processors simplify the
+manipulation of numerical data. Multiplication and division instructions
+ease the handling of signed and unsigned binary integers as well as unpacked
+decimal integers.
+
+An arithmetic operation may consist of two register operands, a general
+register source operand with a memory destination operand, a memory source
+operand with a register destination operand, or an immediate field with
+either a register or memory destination operand, but not two memory
+operands. Arithmetic instructions can operate on either byte or word
+operands.
+
+
+3.3.1 Addition Instructions
+
+ADD (Add Integers) replaces the destination operand with the sum of the
+source and destination operands. ADD affects OF, SF, AF, PF, CF, and ZF.
+
+Example:
+ ADD BL, BYTEOPRND. Adds the contents of the memory byte labeled
+ BYTEOPRND to the contents of BL, and replaces BL with the resulting sum.
+
+ADC (Add Integers with Carry) sums the operands, adds one if CF is set, and
+replaces the destination operand with the result. ADC can be used to add
+numbers longer than 16 bits. ADC affects OF, SF, AF, PF, CF, and ZF.
+
+Example:
+ ADC BX, CX. Replaces the contents of the destination operand BX with
+ the sum of BX, CS, and 1 (if CF is set). If CF is cleared, ADC
+ performs the same operation as the ADD instruction.
+
+INC (Increment) adds one to the destination operand. The processor treats
+the operand as an unsigned binary number. INC updates AF, OF, PF, SF, and
+ZF, but it does not affect CF. Use ADD with an immediate value of 1 if an
+increment that updates carry (CF) is needed.
+
+Example:
+ INC BL. Adds 1 to the contents of BL.
+
+
+3.3.2 Subtraction Instructions
+
+SUB (Subtract Integers) subtracts the source operand from the destination
+operand and replaces the destination operand with the result. If a borrow is
+required, carry flag is set. The operands may be signed or unsigned bytes or
+words. SUB affects OF, SF, ZF, AF, PF, and CF.
+
+Example:
+ SUB WORDOPRND, AX. Replaces the contents of the destination operand
+ WORDOPRND with the result obtained by subtracting the contents of AX from
+ the contents of the memory word labeled WORDOPRND.
+
+SBB (Subtract Integers with Borrow) subtracts the source operand from the
+destination operand, subtracts 1 if CF is set, and returns the result to the
+destination operand. The operands may be signed or unsigned bytes or words.
+SBB may be used to subtract numbers longer than 16 bits. This instruction
+affects OF, SF, ZF, AF, PF, and CF. The carry flag is set if a borrow is
+required.
+
+Example:
+ SBB BL, 32. Subtracts 32 from the contents of BL and then decrements the
+ result of this subtraction by one if CF is set. If CF is cleared, SBB
+ performs the same operation as SUB.
+
+DEC (Decrement) subtracts 1 from the destination operand. DEC updates AF,
+OF, PF, SF, and ZF, but it does not affect CF. Use SUB with an immediate
+value of 1 to perform a decrement that affects carry.
+
+Example:
+ DEC BX. Subtracts 1 from the contents of BX and places the result back in
+ BX.
+
+
+3.3.3 Multiplication Instructions
+
+MUL (Unsigned Integer Multiply) performs an unsigned multiplication of the
+source operand and the accumulator. If the source is a byte, the processor
+multiplies it by the contents of AL and returns the double-length result to
+AH and AL.
+
+If the source operand is a word, the processor multiplies it by the
+contents of AX and returns the double-length result to DX and AX. MUL sets
+CF and OF to indicate that the upper half of the result is nonzero;
+otherwise, they are cleared. This instruction leaves SF, ZF, AF, and PF
+undefined.
+
+Example:
+ MUL BX. Replaces the contents of DX and AX with the product of BX and AX.
+ The low-order 16 bits of the result replace the contents of AX; the
+ high-order word goes to DX. The processor sets CF and OF if the unsigned
+ result is greater than 16 bits.
+
+IMUL (Signed Integer Multiply) performs a signed multiplication operation.
+IMUL uses AX and DX in the same way as the MUL instruction, except when used
+in the immediate form.
+
+The immediate form of IMUL allows the specification of a destination
+register other than the combination of DX and AX. In this case, the result
+cannot exceed 16 bits without causing an overflow. If the immediate operand
+is a byte, the processor automatically extends it to 16 bits before
+performing the multiplication.
+
+The immediate form of IMUL may also be used with unsigned operands because
+the low 16 bits of a signed or unsigned multiplication of two 16-bit values
+will always be the same.
+
+IMUL clears CF and OF to indicate that the upper half of the result is the
+sign of the lower half. This instruction leaves SF, ZF, AF, and PF
+undefined.
+
+Example:
+ IMUL BL. Replaces the contents of AX with the product of BL and AL. The
+ processor sets CF and OF if the result is more than 8 bits long.
+
+Example:
+ IMUL BX, SI, 5. Replaces the contents of BX with the product of the
+ contents of SI and an immediate value of 5. The processor sets CF and OF
+ if the signed result is longer than 16 bits.
+
+
+3.3.4 Division Instructions
+
+DIV (Unsigned Integer Divide) performs an unsigned division of the
+accumulator by the source operand. If the source operand is a byte, it is
+divided into the double-length dividend assumed to be in registers AL and AH
+(AH = most significant byte; AL = least significant byte). The
+single-length quotient is returned in AL, and the single-length remainder is
+returned in AH.
+
+If the source operand is a word, it is divided into the double-length
+dividend in registers AX and DX. The single-length quotient is returned in
+AX, and the single-length remainder is returned in DX. Non-integral
+quotients are truncated to integers toward 0. The remainder is always less
+than the quotient.
+
+For unsigned byte division, the largest quotient is 255. For unsigned word
+division, the largest quotient is 65,535. DIV leaves OF, SF, ZF, AF, PF, and
+CF undefined. Interrupt (INT 0) occurs if the divisor is zero or if the
+quotient is too large for AL or AX.
+
+Example:
+ DIV BX. Replaces the contents of AX with the unsigned quotient of the
+ doubleword value contained in DX and AX, divided by BX. The unsigned
+ modulo replaces the contents of DX.
+
+Example:
+ DIV BL. Replaces the contents of AL with the unsigned quotient of the
+ word value in AX, divided by BL. The unsigned modulo replaces the
+ contents of AH.
+
+IDIV (Signed Integer Divide) performs a signed division of the accumulator
+by the source operand. IDIV uses the same registers as the DIV instruction.
+
+For signed byte division, the maximum positive quotient is +127 and the
+minimum negative quotient is -128. For signed word division, the maximum
+positive quotient is +32,767 and the minimum negative quotient is -32,768.
+Non-integral results are truncated towards 0. The remainder will always
+have the same sign as the dividend and will be less than the divisor in
+magnitude. IDIV leaves OF, SF, ZF, AF, PF, and CF undefined. A division by
+zero causes an interrupt (INT 0) to occur if the divisor is 0 or if the
+quotient is too large for AL or AX.
+
+Example:
+ IDIV WORDOPRND. Replaces the contents of AX with the signed quotient
+ of the double-word value contained in DX and AX, divided by the value
+ contained in the memory word labeled WORDOPRND. The signed modulo
+ replaces the contents of DX.
+
+
+3.4 Logical Instructions
+
+The group of logical instructions includes the Boolean operation
+instructions, rotate and shift instructions, type conversion instructions,
+and the no-operation (NOP)instruction.
+
+
+3.4.1 Boolean Operation Instructions
+
+Except for the NOT and NEG instructions, the Boolean operation instructions
+can use two register operands, a general purpose register operand with a
+memory operand, an immediate operand with a general purpose register
+operand, or a memory operand. The NOT and NEG instructions are unary
+operations that use a single operand in a register or memory.
+
+AND (And) performs the logical "and" of the operands (byte or word) and
+returns the result to the destination operand. AND clears OF and DF, leaves
+AF undefined, and updates SF, ZF, and PF.
+
+Example:
+ AND WORDOPRND, BX. Replaces the contents of WORDOPRND with the logical
+ "and" of the contents of the memory word labeled WORDOPRND and the
+ contents of BX.
+
+NOT (Not) inverts the bits in the specified operand to form a one's
+complement of the operand. NOT has no effect on the flags.
+
+Example:
+ NOT BYTEOPRND. Replaces the original contents of BYTEOPRND with the
+ one's complement of the contents of the memory word labeled BYTEOPRND.
+
+OR (Or) performs the logical "inclusive or" of the two operands and returns
+the result to the destination operand. OR clears OF and DF, leaves AF
+undefined, and updates SF, ZF, and PF.
+
+Example:
+ OR AL,5. Replaces the original contents of AL with the logical
+ "inclusive or" of the contents of AL and the immediate value 5.
+
+XOR (Exclusive OR) performs the logical "exclusive or" of the two operands
+and returns the result to the destination operand. XOR clears OF and DF,
+leaves AF undefined, and updates SF, ZF, and PF.
+
+Example:
+ XOR DX, WORDOPRND. Replaces the original contents of DX with the logical
+ "exclusive or" or the contents of DX and the contents of the memory word
+ labeled WORDOPRND.
+
+NEG (Negate) forms a two's complement of a signed byte or word operand. The
+effect of NEG is to reverse the sign of the operand from positive to
+negative or from negative to positive. NEG updates OF, SF, ZF, AF, PF, and
+CF.
+
+Example:
+ NEG AX. Replaces the original contents of AX with the two's complement
+ of the contents of AX.
+
+
+3.4.2 Shift and Rotate Instructions
+
+The shift and rotate instructions reposition the bits within the specified
+operand. The shift instructions provide a convenient way to accomplish
+division or multiplication by binary power. The rotate instructions are
+useful for bit testing.
+
+
+3.4.2.1 Shift Instructions
+
+The bits in bytes and words may be shifted arithmetically or logically.
+Depending on the value of a specified count, up to 31 shifts may be
+performed.
+
+A shift instruction can specify the count in one of three ways. One form of
+shift instruction implicitly specifies the count as a single shift. The
+second form specifies the count as an immediate value. The third form
+specifies the count as the value contained in CL. This last form allows the
+shift count to be a variable that the program supplies during execution.
+Only the low order 5 bits of CL are used.
+
+Shift instructions affect the flags as follows. AF is always undefined
+following a shift operation. PF, SF, and ZF are updated normally as in the
+logical instructions.
+
+CF always contains the value of the last bit shifted out of the destination
+operand. In a single-bit shift, OF is set if the value of the high-order
+(sign) bit was changed by the operation. Otherwise, OF is cleared. Following
+a multibit shift, however, the content of OF is always undefined.
+
+SAL (Shift Arithmetic Left) shifts the destination byte or word operand left
+by one or by the number of bits specified in the count operand (an immediate
+value or the value contained in CL). The processor shifts zeros in from the
+right side of the operand as bits exit from the left side. See figure 3-6.
+
+Example:
+ SAL BL,2. Shifts the contents of BL left by 2 bits and replaces the two
+ low-order bits with zeros.
+
+Example:
+ SAL BL,1. Shifts the contents of BL left by 1 bit and replaces the
+ low-order bit with a zero. Because the processor does not have to decode
+ the immediate count operand to obtain the shift count, this from of the
+ instruction takes 2 clock cycles rather than the 6 clock cycles (5 + 1
+ cycle for each bit shifted) required by the previous example.
+
+SHL (Shift Logical Left) is physically the same instruction as SAL (see SAL
+above).
+
+SHR (Shift Logical Right) shifts the destination byte or word operand right
+by one or by the number of bits specified in the count operand (an immediate
+value or the value contained in CL). The processor shifts zeros in from the
+left side of the operand as bits exit from the right side. See figure 3-7.
+
+Example:
+ SHR BYTEOPRND, CL. Shifts the contents of the memory byte labeled
+ BYTEOPRND right by the number of bits specified in CL, and pads the left
+ side of BYTEOPRND with an equal number of zeros.
+
+SAR (Shift Arithmetic Right) shifts the destination byte or word operand to
+the right by one or by the number of bits specified in the count operand (an
+immediate value or the value contained in CL). The processor preserves the
+sign of the operand by shifting in zeros on the left side if the value is
+positive or by shifting by ones if the value is negative. See figure 3-8.
+
+Example:
+ SAR WORDPRND,1. Shifts the contents of the memory byte labeled WORDPRND
+ right by one, and replaces the high-order sign bit with a value equal to
+ the original sign of WORDPRND.
+
+SHR shifts the bits in the register or memory operand to the right by the
+specified number of bit positions. CF receives the last bit shifted out of
+the right of the operand. SHR shifts in zeros to fill the vacated bit
+locations. This instruction operates on byte operands as well as word
+operands.
+
+
+Figure 3-6. SAL and SHL
+
+ BEFORE SAL OR SHL
+╔═╗ ╔═╗ ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗
+║X║ ║X║ ║ 1 ║ 1 ║ 1 ║ 1 ║ 1 ║ 0 ║ 0 ║ 0 ║ 1 ║ 1 ║ 1 ║ 1 ║ 0 ║ 0 ║ 1 ║ 1 ║
+╚═╝ ╚═╝ ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝
+
+ AFTER SAL OR SHL BY 1 BIT
+╔═╗ ╔═╗ ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗
+║0║ ║1║◄─╢ 1 ║ 1 ║ 1 ║ 1 ║ 0 ║ 0 ║ 0 ║ 1 ║ 1 ║ 1 ║ 1 ║ 0 ║ 0 ║ 1 ║ 1 ║ 0 ║
+╚═╝ ╚═╝ ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝
+
+ AFTER SAL OR SHL BY 8 BITS
+╔═╗ ╔═╗ ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗
+║X║ ║ ║◄─╢ 1 ║ 1 ║ 1 ║ 1 ║ 0 ║ 0 ║ 1 ║ 1 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║
+╚═╝ ╚═╝ ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝
+OF CF
+
+ Both SAL and SHL shift the bits in the register or memory operand to the
+ left by the specified number of bit positions. CF receives the last bit
+ shifted out of the left of the operand. SAL and SHL shift in zeros to fill
+ the vacated bit locations. These instructions operate on byte operands as
+ well as word operands.
+
+
+Figure 3-7. SHR
+
+ BEFORE SHR
+ ╔═╗ ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗ ╔═╗
+ ║X║ ║ 1 ║ 1 ║ 0 ║ 0 ║ 1 ║ 1 ║ 1 ║ 1 ║ 0 ║ 1 ║ 1 ║ 1 ║ 0 ║ 0 ║ 0 ║ 1 ║ ║X║
+ ╚═╝ ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝ ╚═╝
+
+ AFTER SHR BY 1 BIT
+ ╔═╗ ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗ ╔═╗
+ ║1║ ║ 0 ║ 1 ║ 1 ║ 0 ║ 0 ║ 1 ║ 1 ║ 1 ║ 1 ║ 0 ║ 1 ║ 1 ║ 1 ║ 0 ║ 0 ║ 0 ╟─►║1║
+ ╚═╝ ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝ ╚═╝
+
+ AFTER SHR BY 10 BITS
+ ╔═╗ ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗ ╔═╗
+ ║X║ ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 1 ║ 1 ║ 0 ║ 0 ║ 1 ╟─►║1║
+ ╚═╝ ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝ ╚═╝
+ OF OPERAND CF
+
+ SHR shifts the bits in the register or memory operand to the right by the
+ specified number of bit positions. CF receives the last bit shifted out of
+ the right of the operand. SHR shifts in zeros to fill the vacated bit
+ locations. This instruction operates on byte operands as well as word
+ operands.
+
+
+Figure 3-8. SAR
+
+ BEFORE SAR WITH A POSITIVE OPERAND
+ ╔═╗ ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗ ╔═╗
+ ║X║ ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 1 ║ ║X║
+ ╚═╝ ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝ ╚═╝
+
+ AFTER SAR WITH A POSITIVE OPERAND SHIFTED 1 BIT
+ ╔═╗ ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗ ╔═╗
+ ║X║ ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ╟─►║1║
+ ╚═╝ ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝ ╚═╝
+
+ BEFORE SAR WITH A NEGATIVE OPERAND
+ ╔═╗ ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗ ╔═╗
+ ║X║ ║ 1 ║ 0 ║ 0 ║ 0 ║ 1 ║ 1 ║ 1 ║ 1 ║ 0 ║ 0 ║ 0 ║ 1 ║ 1 ║ 0 ║ 1 ║ 0 ╟─►║X║
+ ╚═╝ ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝ ╚═╝
+
+ AFTER SAR WITH A NEGATIVE OPERAND SHIFTED 6 BITS
+ ╔═╗ ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗ ╔═╗
+ ║X║ ║ 1 ║ 1 ║ 1 ║ 1 ║ 1 ║ 1 ║ 1 ║ 0 ║ 0 ║ 0 ║ 1 ║ 1 ║ 1 ║ 1 ║ 0 ║ 0 ╟─►║0║
+ ╚═╝ ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝ ╚═╝
+ OF OPERAND CF
+
+ SAR preserves the sign of the register or memory operand as it shifts the
+ operand to the right the specified number of bit positions. CF receives the
+ last bit shifted out of the right of the operand. This instruction also
+ operates on byte operands.
+
+
+3.4.2.2 Rotate Instructions
+
+Rotate instructions allow bits in bytes and words to be rotated. Bits
+rotated out of an operand are not lost as in a shift, but are "circled" back
+into the other "end" of the operand.
+
+Rotates affect only the carry and overflow flags. CF may act as an
+extension of the operand in two of the rotate instructions, allowing a bit
+to be isolated and then tested by a conditional jump instruction (JC or
+JNC). CF always contains the value of the last bit rotated out, even if the
+instruction does not use this bit as an extension of the rotated operand.
+
+In single-bit rotates, OF is set if the operation changes the high-order
+(sign) bit of the destination operand. If the sign bit retains its original
+value, OF is cleared. On multibit rotates, the value of OF is always
+undefined.
+
+ROL (Rotate Left) rotates the byte or word destination operand left by one
+or by the number of bits specified in the count operand (an immediate value
+or the value contained in CL). For each rotation specified, the high-order
+bit that exists from the left of the operand returns at the right to become
+the new low-order bit of the operand. See figure 3-9.
+
+Example:
+ ROL AL, 8. Rotates the contents of AL left by 8 bits. This rotate
+ instruction returns AL to its original state but isolates the low-order
+ bit in CF for testing by a JC or JNC instruction.
+
+ROR (Rotate Right) rotates the byte or word destination operand right by
+one or by the number of bits specified in the count operand (an immediate
+value or the value contained in CL). For each rotation specified, the
+low-order bit that exits from the right of the operand returns at the left
+to become the new high-order bit of the operand. See figure 3-10.
+
+Example:
+ ROR WORDOPRND, CL. Rotates the contents of the memory word labeled
+ WORDOPRND by the number of bits specified by the value contained in CL.
+ CF reflects the value of the last bit rotated from the right to the left
+ side of the operand.
+
+RCL (Rotate Through Carry Left) rotates bits in the byte or word
+destination operand left by one or by the number of bits specified in the
+count operand (an immediate value or the value contained in CL).
+
+This instruction differs from ROL in that it treats CF as a high-order
+1-bit extension of the destination operand. Each high-order bit that exits
+from the left side of the operand moves to CF before it returns to the
+operand as the low-order bit on the next rotation cycle. See figure 3-11.
+
+Example:
+ RCL BX,1. Rotates the contents of BX left by one bit. The high-order bit
+ of the operand moves to CF, the remaining 15 bits move left one position,
+ and the original value of CF becomes the new low-order bit.
+
+RCR (Rotate Through Carry Right) rotates bits in the byte or word
+destination operand right by one or by the number of bits specified in the
+count operand (an immediate value or the value contained in CL).
+
+This instruction differs from ROR in that it treats CF as a low-order 1-bit
+extension of the destination operand. Each low-order bit that exits from the
+right side of the operand moves to CF before it returns to the operand as
+the high-order bit on the next rotation cycle. See figure 3-12.
+
+Example:
+ RCR BYTEOPRND,3. Rotates the contents of the memory byte labeled BYTEOPRND
+ to the right by 3 bits. Following the execution of this instruction, CF
+ reflects the original value of bit number 5 of BYTEOPRND, and the original
+ value of CF becomes bit 2.
+
+RCL rotates the bits in the memory or register operand to the left in the
+same way as ROL except that RCL treats CF as a 1-bit extension of the
+operand. Note that a 16-bit RCL produces the same result as a 1-bit RCR
+(though it takes much longer to execute). This instruction also operates on
+byte operands.
+
+RCR rotates the bits in the memory or register operand to the right in the
+same way as ROR except that RCR treats CF as a 1-bit extension of the
+operand. This instruction also operates on byte operands.
+
+
+Figure 3-9. ROL
+
+ BEFORE ROL
+ ╔═╗╔═╗ ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗
+ ║X║║X║ ║ 1 ║ 0 ║ 0 ║ 0 ║ 1 ║ 1 ║ 1 ║ 0 ║ 1 ║ 0 ║ 0 ║ 1 ║ 1 ║ 0 ║ 0 ║ 0 ║
+ ╚═╝╚═╝ ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝
+
+ AFTER ROL BY 1 BIT
+ ╔═╗╔═╗ ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗
+ ║1║║1║◄┬╢ 0 ║ 0 ║ 0 ║ 1 ║ 1 ║ 1 ║ 0 ║ 1 ║ 0 ║ 0 ║ 1 ║ 1 ║ 0 ║ 0 ║ 0 ║ 1 ◄┐
+ ╚═╝╚═╝ │╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝│
+ └─────────────────────────────────────────────────────────────────┘
+
+ AFTER ROL BY 12 BITS
+ ╔═╗╔═╗ ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗
+ ║X║║1║◄┬╢ 1 ║ 0 ║ 0 ║ 0 ║ 1 ║ 0 ║ 0 ║ 0 ║ 1 ║ 1 ║ 1 ║ 0 ║ 1 ║ 0 ║ 0 ║ 1 ◄┐
+ ╚═╝╚═╝ │╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝│
+ OF CF │ OPERAND │
+ └─────────────────────────────────────────────────────────────────┘
+
+ ROL shifts the bits in the memory or register operand to the left by the
+ specified number of bit positions. It copies the bit shifted out of the
+ left of the operand into the right of the operand. The last bit shifted
+ into the least significant bit of the operand also appears in CF. This
+ instruction also operates on byte operands.
+
+
+Figure 3-10. ROR
+
+ BEFORE ROR
+ ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗ ╔═══╗
+ ║ 1 ║ 1 ║ 0 ║ 1 ║ 1 ║ 1 ║ 0 ║ 0 ║ 1 ║ 0 ║ 1 ║ 1 ║ 1 ║ 0 ║ 0 ║ 0 ║ ║ X ║
+ ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝ ╚═══╝
+
+ AFTER ROR BY 1 BIT
+ ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗ ╔═══╗
+ ┌► 0 ║ 1 ║ 1 ║ 0 ║ 1 ║ 1 ║ 1 ║ 0 ║ 0 ║ 1 ║ 0 ║ 1 ║ 1 ║ 1 ║ 0 ║ 0 ╟┬►║ 0 ║
+ │╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝│ ╚═══╝
+ └─────────────────────────────────────────────────────────────────┘
+
+ AFTER ROR BY 8 BITS
+ ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗ ╔═══╗
+ ┌► 1 ║ 0 ║ 1 ║ 1 ║ 1 ║ 0 ║ 0 ║ 0 ║ 1 ║ 1 ║ 0 ║ 1 ║ 1 ║ 1 ║ 0 ║ 0 ╟┬►║ 1 ║
+ │╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝│ ╚═══╝
+ │ OPERAND │ CF
+ └─────────────────────────────────────────────────────────────────┘
+
+ ROR shifts the bits in the memory or register operand to the right by the
+ specified number of bit positions. It copies each bit shifted out of the
+ right of the operand into the left of the operand. The last bit shifted
+ into the most significant bit of the operand also appears in CF. This
+ instruction also operates on byte operands.
+
+
+Figure 3-11. RCL
+
+ BEFORE RCL
+ ╔═══╗ ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗
+ ║ 1 ║ ║ 1 ║ 1 ║ 1 ║ 0 ║ 0 ║ 0 ║ 1 ║ 1 ║ 0 ║ 0 ║ 1 ║ 1 ║ 0 ║ 0 ║ 0 ║ 0 ║
+ ╚═══╝ ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝
+
+ AFTER RCL BY 1 BIT
+ ╔═══╗ ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗
+ ┌─╢ 1 ║◄─╢ 1 ║ 1 ║ 0 ║ 0 ║ 0 ║ 1 ║ 1 ║ 0 ║ 0 ║ 1 ║ 1 ║ 0 ║ 0 ║ 0 ║ 0 ║ 1 ◄┐
+ │ ╚═══╝ ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝│
+ └─────────────────────────────────────────────────────────────────────────┘
+
+ AFTER RCL BY 16 BITS
+ ╔═══╗ ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗
+ ┌─╢ 0 ║◄─╢ 1 ║ 1 ║ 1 ║ 1 ║ 0 ║ 0 ║ 0 ║ 1 ║ 1 ║ 0 ║ 0 ║ 1 ║ 1 ║ 0 ║ 0 ║ 0 ◄┐
+ │ ╚═══╝ ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝│
+ │ CF OPERAND │
+ └─────────────────────────────────────────────────────────────────────────┘
+
+ RCL rotates the bits in the memory or register operand to the left in the
+ same way as ROL except that RCL treats CF as a 1-bit extension of the
+ operand. Note that a 16-bit RCL produces the same result as a 1-bit RCR
+ (though it takes much longer to execute). This instruction also operates
+ on byte operands.
+
+
+Figure 3-12. RCR
+
+ BEFORE RCR
+ ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗ ╔═══╗
+ ║ 1 ║ 1 ║ 1 ║ 0 ║ 0 ║ 0 ║ 1 ║ 1 ║ 0 ║ 0 ║ 1 ║ 1 ║ 0 ║ 0 ║ 0 ║ 0 ║ ║ 1 ║
+ ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝ ╚═══╝
+
+ AFTER RCR BY 1 BIT
+ ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗ ╔═══╗
+ ┌► 1 ║ 1 ║ 1 ║ 1 ║ 0 ║ 0 ║ 0 ║ 1 ║ 1 ║ 0 ║ 0 ║ 1 ║ 1 ║ 0 ║ 0 ║ 0 ╟─►║ 0 ╟─┐
+ │╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝ ╚═══╝ │
+ └─────────────────────────────────────────────────────────────────────────┘
+
+ AFTER RCR BY 8 BITS
+ ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗ ╔═══╗
+ ┌► 0 ║ 0 ║ 1 ║ 1 ║ 1 ║ 1 ║ 0 ║ 0 ║ 0 ║ 1 ║ 1 ║ 0 ║ 0 ║ 1 ║ 1 ║ 0 ╟─►║ 0 ╟─┐
+ │╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝ ╚═══╝ │
+ │ OPERAND CF │
+ └─────────────────────────────────────────────────────────────────────────┘
+
+ RCR rotates the bits in the memory or register operand to the right in the
+ same way as ROR except that RCR treats CF as a 1-bit extension of the
+ operand. This instruction also operates on byte operands.
+
+
+3.4.3 Type Conversion and No-Operation Instructions
+
+The type conversion instructions prepare operands for division. The NOP
+instruction is a 1-byte filler instruction with no effect on registers or
+flags.
+
+CWD (Convert Word to Double-Word) extends the sign of the word in register
+AX throughout register DX. CWD does not affect any flags. CWD can be used to
+produce a double-length (double-word) dividend from a word before a word
+division.
+
+CBW (Convert Byte to Word) extends the sign of the byte in register AL
+throughout AX. CBW does not affect any flags.
+
+Example:
+ CWD. Sign-extends the 16-bit value in AX to a 32-bit value in DX and AX
+ with the high-order 16-bits occupying DX.
+
+NOP (No Operation) occupies a byte of storage but affects nothing but the
+instruction pointer, IP. The amount of time that a NOP instruction requires
+for execution varies in proportion to the CPU clocking rate. This variation
+makes it inadvisable to use NOP instructions in the construction of timing
+loops because the operation of such a program will not be independent of the
+system hardware configuration.
+
+Example:
+ NOP. The processor performs no operation for 2 clock cycles.
+
+
+3.5 Test and Compare Instructions
+
+The test and compare instructions are similar in that they do not alter
+their operands. Instead, these instructions perform operations that only set
+the appropriate flags to indicate the relationship between the two operands.
+
+TEST (Test) performs the logical "and" of the two operands, clears OF and
+DF, leaves AF undefined, and updates SF, ZF, and PF. The difference between
+TEST and AND is that TEST does not alter the destination operand.
+
+Example:
+ TEST BL,32. Performs a logical "and" and sets SF, ZF, and PF according to
+ the results of this operation. The contents of BL remain unchanged.
+
+CMP (Compare) subtracts the source operand from the destination operand. It
+updates OF, SF, ZF, AF, PF, and CF but does not alter the source and
+destination operands. A subsequent signed or unsigned conditional transfer
+instruction can test the result using the appropriate flag result.
+
+CMP can compare two register operands, a register operand and a memory
+operand, a register operand and an immediate operand, or an immediate
+operand and a memory operand. The operands may be words or bytes, but CMP
+cannot compare a byte with a word.
+
+Example:
+ CMP BX,32. Subtracts the immediate operand, 32, from the contents of BX
+ and sets OF, SF, ZF, AF, PF, and CF to reflect the result. The contents
+ of BX remain unchanged.
+
+
+3.6 Control Transfer Instructions
+
+The 80286 provides both conditional and unconditional program transfer
+instructions to direct the flow of execution. Conditional program transfers
+depend on the results of operations that affect the flag register.
+Unconditional program transfers are always executed.
+
+
+3.6.1 Unconditional Transfer Instructions
+
+JMP, CALL, RET, INT and IRET instructions transfer control from one code
+segment location to another. These locations can be within the same code
+segment or in different code segments.
+
+
+3.6.1.1 Jump Instruction
+
+JMP (Jump) unconditionally transfers control to the target location. JMP is
+a one-way transfer of execution; it does not save a return address on the
+stack.
+
+The JMP instruction always performs the same basic function of transferring
+control from the current location to a new location. Its implementation
+varies depending on the following factors:
+
+ ■ Is the address specified directly within the instruction or indirectly
+ through a register or memory?
+
+ ■ Is the target location inside or outside the current code segment
+ selected in CS?
+
+A direct JMP instruction includes the destination address as part of the
+instruction. An indirect JMP instruction obtains the destination address
+indirectly through a register or a pointer variable.
+
+Control transfers through a gate or to a task state segment are available
+only in Protected Mode operation of the 80286. The formats of the
+instructions that transfer control through a call gate, a task gate, or to a
+task state segment are the same. The label included in the instruction
+selects one of these three paths to a new code segment.
+
+Direct JMP within the current code segment. A direct JMP that transfers
+control to a target location within the current code segment uses a relative
+displacement value contained in the instruction. This can be either a 16-bit
+value or an 8-bit value sign extended to 16 bits. The processor forms an
+effective address by adding this relative displacement to the address
+contained in IP. IP refers to the next instruction when the additions are
+performed.
+
+Example:
+ JMP NEAR_NEWCODE. Transfers control to the target location labeled
+ NEAR_NEWCODE, which is within the code segment currently selected in CS.
+
+Indirect JMP within the current code segment. Indirect JMP instructions
+that transfer control to a location within the current code segment specify
+an absolute address in one of several ways. First, the program can JMP to a
+location specified by a 16-bit register (any of AX, DX, CX, BX, BP, SI, or
+DI). The processor moves this 16-bit value into IP and resumes execution.
+
+Example:
+ JMP SI. Transfers control to the target address formed by adding the
+ 16-bit value contained in SI to the base address contained in CS.
+
+The processor can also obtain the destination address within a current
+segment from a memory word operand specified in the instruction.
+
+Example:
+ JMP PTR_X. Transfers control to the target address formed by adding the
+ 16-bit value contained in the memory word labeled PTR X to the base
+ address contained in CS.
+
+A register can modify the address of the memory word pointer to select a
+destination address.
+
+Example:
+ JMP CASE_TABLE [BX]. CASE_TABLE is the first word in an array of word
+ pointers. The value of BX determines which pointer the program selects
+ from the array. The JMP instruction then transfers control to the
+ location specified by the selected pointer.
+
+Direct JMP outside of the current code segment. Direct JMP instructions
+that specify a target location outside the current code segment contain a
+full 32-bit pointer. This pointer consists of a selector for the new code
+segment and an offset within the new segment.
+
+Example:
+ JMP FAR_NEWCODE_FOO. Places the selector contained in the instruction into
+ CS and the offset into IP. The program resumes execution at this location
+ in the new code segment.
+
+Indirect JMP outside of the current code segment. Indirect JMP instructions
+that specify a target location outside the current code segment use a
+double-word variable to specify the pointer.
+
+Example:
+ JMP NEWCODE. NEWCODE the first word of two consecutive words in memory
+ which represent the new pointer. NEWCODE contains the new offset for IP
+ and the word following NEWCODE contains the selector for CS. The program
+ resumes execution at this location in the new code segment. (Protected
+ mode programs treat this differently. See Chapters 6 and 7).
+
+Direct JMP outside of the current code segment to a call gate. If the
+selector included with the instruction refers to a call gate, then the
+processor ignores the offset in the instruction and takes the pointer of the
+routine being entered from the call gate.
+
+JMP outside of current code segment may only go to the same level.
+
+Example:
+ JMP CALL_GATE_FOO. The selector in the instruction refers to the call gate
+ CALL_GATE_FOO, and the call gate actually provides the new contents of CS
+ and IP to specify the address of the next instructions.
+
+Indirect JMP outside the current code segment to a call gate. If the
+selector specified by the instruction refers to a call gate, the processor
+ignores the offset in the double-word and takes the address of the routine
+being entered from the call gate. The JMP instruction uses the same format
+to indirectly specify a task gate or a task state segment.
+
+Example:
+ JMP CASE_TABLE [BX]. The instruction refers to the double-word in the
+ array of pointers called CASE_TABLE. The specific double-word chosen
+ depends on the value in BX when the instruction executes. The selector
+ portion of this double-word selects a call gate, and the processor takes
+ the address of the routine being entered from the call gate.
+
+ROL shifts the bits in the memory or register operand to the left by the
+specified number of bit positions. It copies the bit shifted out of the left
+of the operand into the right of the operand. The last bit shifted into the
+least significant bit of the operand also appears in CF. This instruction
+also operates on byte operands.
+
+ROR shifts the bits in the memory or register operand to the right by the
+specified number of bit positions. It copies each bit shifted out of the
+right of the operand into the left of the operand. The last bit shifted into
+the most significant bit of the operand also appears in CF. This instruction
+also operates on byte operands.
+
+
+3.6.1.2 Call Instruction
+
+CALL (Call Procedure) activates an out-of-line procedure, saving on the
+stack the address of the instruction following the CALL for later use by a
+RET (Return) instruction. An intrasegment CALL places the current value of
+IP on the stack. An intersegment CALL places both the value of IP and CS on
+the stack. The RET instruction in the called procedure uses this address to
+transfer control back to the calling program.
+
+A long CALL instruction that invokes a task-switch stores the outgoing
+task's task state segment selector in the incoming task state segment's link
+field and sets the nested task flag in the new task. In this case, the IRET
+instruction takes the place of the RET instruction to return control to the
+nested task.
+
+Examples:
+ CALL NEAR_NEWCODE
+ CALL SI
+ CALL PTR_X
+ CALL CASE_TABLE [BP]
+ CALL FAR_NEWCODE_FOO
+ CALL NEWCODE
+ CALL CALL_GATE_FOO
+ CALL CASE_TABLE [BX]
+
+See the previous treatment of JMP for a discussion of the operations of
+these instructions.
+
+
+3.6.1.3 Return And Return From Interrupt Instruction
+
+RET (Return From Procedure) terminates the execution of a procedure and
+transfers control through a back-link on the stack to the program that
+originally invoked the procedure.
+
+An intrasegment RET restores the value of IP that was saved on the stack by
+the previous intrasegment CALL instruction. An intersegment RET restores the
+values of both CS and IP which were saved on the stack by the previous
+intersegment CALL instruction.
+
+RET instructions may optionally specify a constant to the stack pointer.
+This constant specifies the new top of stack to effectively remove any
+arguments that the calling program pushed on the stack before the execution
+of the CALL instruction.
+
+Example:
+ RET. If the previous CALL instruction did not transfer control to a new
+ code segment, RET restores the value of IP pushed by the CALL instruction.
+ If the previous CALL instruction transferred control to a new segment, RET
+ restores the values of both IP and CS which were pushed on the stack by
+ the CALL instruction.
+
+Example:
+ RET n. This form of the RET instruction performs identically to the above
+ example except that it adds n (which must be an even value) to the value
+ of SP to eliminate n bytes of parameter information previously pushed by
+ the calling program.
+
+IRET (Return From Interrupt or Nested Task) returns control to an
+interrupted routine or, optionally, reverses the action of a CALL or INT
+instruction that caused a task switch. See Chapter 8 for further
+information on task switching.
+
+Example:
+ IRET. Returns from an interrupt with or without a task switch based on
+ the value of the NT bit.
+
+
+3.6.2 Conditional Transfer Instructions
+
+The conditional transfer instructions are jumps that may or may not transfer
+control, depending on the state of the CPU flags when the instruction
+executes. Instruction encoding is most efficient when the target for the
+conditional jumps is in the current code segment and within -128 to +127
+bytes of the first byte of the next instruction. Alternatively, the opposite
+sense of the conditional jump can skip around an unconditional jump to the
+destination.
+
+
+3.6.2.1 Conditional Jump Instructions
+
+Table 3-3 shows the conditional transfer mnemonics and their
+interpretations. The conditional jumps that are listed as pairs are actually
+the same instruction. The assembler provides the alternate mnemonics for
+greater clarity within a program listing.
+
+
+Table 3-3. Interpretation of Conditional Transfers
+
+ Unsigned Conditional Transfers
+Mnemonic Condition Tested "Jump If. . ."
+
+JA/JNBE (CF or ZF) = 0 above/not below nor equal
+JAE/JNB CF = 0 above or equal/not below
+JB/JNAE CF = 1 below/not above nor equal
+JBE/JNA (CF or ZF) = 1 below or equal/not above
+JC CF = 1 carry
+JE/JZ ZF = 1 equal/zero
+JNC CF = 0 not carry
+JNE/JNZ ZF = 0 not equal/not zero
+JNP/JPO PF = 0 not parity/parity odd
+JP/JPE PF = 1 parity/parity even
+
+ Signed Conditional Transfers
+Mnemonic Condition Tested "Jump If. . ."
+
+JG/JNLE ((SF xor OF) or ZF) = 0 greater/not less nor equal
+JGE/JNL (SF xor OF) = 0 greater or equal/not less
+JL/JNGE (SF xor OF) = 0 less/not greater nor equal
+JLE/JNG ((SF xor OF) or ZF) = 1 less or equal/not greater
+JNO OF = 0 not overflow
+JNS SF = 0 not sign (positive, including 0)
+JO OF = 1 overflow
+JS SF = 1 sign (negative)
+
+
+3.6.2.2 Loop Instructions
+
+The loop instructions are conditional jumps that use a value placed in CX
+to specify the number of repetitions of a software loop. All loop
+instructions automatically decrement CX and terminate the loop when CX=0.
+Four of the five loop instructions specify a condition of ZF that
+terminates the loop before CX decrements to zero.
+
+LOOP (Loop While CX Not Zero) is a conditional transfer that
+auto-decrements the CX register before testing CX for the branch condition.
+If CX is non-zero, the program branches to the target label specified in the
+instruction. The LOOP instruction causes the repetition of a code section
+until the operation of the LOOP instruction decrements CX to a value of
+zero. If LOOP finds CX=0, control transfers to the instruction immediately
+following the LOOP instruction. If the value of CX is initially zero, then
+the LOOP executes 65,536 times.
+
+Example:
+ LOOP START_LOOP. Each time the program encounters this instruction, it
+ decrements CX and then tests it. If the value of CX is non-zero, then the
+ program branches to the instruction labeled START_LOOP. If the value in CX
+ is zero, then the program continues with the instruction that follows the
+ LOOP instruction.
+
+LOOPE (Loop While Equal) and LOOPZ (Loop While Zero) are physically the
+same instruction. These instructions auto-decrement the CX register before
+testing CX and ZF for the branch conditions. If CX is non-zero and ZF=1, the
+program branches to the target label specified in the instruction. If LOOPE
+or LOOPZ finds that CX=0 or ZF=0, control transfers to the instruction
+immediately succeeding the LOOPE or LOOPZ instruction.
+
+Example:
+ LOOPE START_LOOP (or LOOPZ START_LOOP). Each time the program encounters
+ this instruction, it decrements CX and tests CX and ZF. If the value in
+ CX is non-zero and the value of ZF is 1, the program branches to the
+ instruction labeled START_LOOP. If CX=0 or ZF=0, the program continues
+ with the instruction that follows the LOOPE (or LOOPZ) instruction.
+
+LOOPNE (Loop While Not Equal) and LOOPNZ (Loop While Not Zero) are
+physically the same instruction. These instructions auto-decrement the CX
+register before testing CX and ZF for the branch conditions. If CX is
+non-zero and ZF=0, the program branches to the target label specified in
+the instruction. If LOOPNE or LOOPNZ finds that CX=0 or ZF=1, control
+transfers to the instruction immediately succeeding the LOOPNE or LOOPNZ
+instruction.
+
+Example:
+ LOOPNE START_LOOP (or LOOPNZ START_LOOP). Each time the program encounters
+ this instruction, it decrements CX and tests CX and ZF. If the value of CX
+ is non-zero and the value of ZF is 0, the program branches to the
+ instruction labeled START_LOOP. If CX=0 or ZF=1, the program continues
+ with the instruction that follows the LOOPNE (or LOOPNZ) instruction.
+
+
+3.6.2.3 Executing a Loop or Repeat Zero Times
+
+JCXZ (Jump if CX Zero) branches to the label specified in the instruction
+if it finds a value of zero in CX. Sometimes, it is desirable to design a
+loop that executes zero times if the count variable in CX is initialized to
+zero. Because the LOOP instructions (and repeat prefixes) decrement CX
+before they test it, a loop will execute 65,536 times if the program enters
+the loop with a zero value in CX. A programmer may conveniently overcome
+this problem with JCXZ, which enables the program to branch around the code
+within the loop if CX is zero when JCXZ executes.
+
+Example:
+ JCXZ TARGETLABEL. Causes the program to branch to the instruction labeled
+ TARGETLABEL if CX=0 when the instruction executes.
+
+
+3.6.3 Software-Generated Interrupts
+
+The INT n and INTO instructions allow the programmer to specify a transfer
+to an interrupt service routine from within a program. Interrupts 0-31 are
+reserved by Intel.
+
+
+3.6.3.1 Software Interrupt Instruction
+
+INT n (Software Interrupt) activates the interrupt service routine that
+corresponds to the number coded within the instruction. Interrupt type 3 is
+reserved for internal software-generated interrupts. However, the INT
+instruction may specify any interrupt type to allow multiple types of
+internal interrupts or to test the operation of a service routine. The
+interrupt service routine terminates with an IRET instruction that returns
+control to the instruction that follows INT.
+
+Example:
+ INT 3. Transfers control to the interrupt service routine specified by a
+ type 3 interrupt.
+
+Example:
+ INT 0. Transfers control to the interrupt service routine specified by a
+ type 0 interrupt, which is reserved for a divide error.
+
+INTO (Interrupt on Overflow) invokes a type 4 interrupt if OF is set when
+the INTO instruction executes. The type 4 interrupt is reserved for this
+purpose.
+
+Example:
+ INTO. If the result of a previous operation has set OF and no intervening
+ operation has reset OF, then INTO invokes a type 4 interrupt. The
+ interrupt service routine terminates with an IRET instruction, which
+ returns control to the instruction following INTO.
+
+
+3.7 Character Translation and String Instructions
+
+The instructions in this category operate on characters or string elements
+rather than on logical or numeric values.
+
+
+3.7.1 Translate Instruction
+
+XLAT (Translate) replaces a byte in the AL register with a byte from a
+user-coded translation table. When XLAT is executed, AL should have the
+unsigned index to the table addressed by BX. XLAT changes the contents of AL
+from table index to table entry. BX is unchanged. The XLAT instruction is
+useful for translating from one coding system to another, such as from
+ASCII to EBCDIC. The translate table may be up to 256 bytes long. The value
+placed in the AL register serves as an index to the location of the
+corresponding translation value. Used with a LOOP instruction, the XLAT
+instruction can translate a block of codes up to 64K bytes long.
+
+Example:
+ XLAT. Replaces the byte in AL with the byte from the translate table that
+ is selected by the value in AL.
+
+
+3.7.2 String Manipulation Instructions and Repeat Prefixes
+
+The string instructions (also called primitives) operate on string elements
+to move, compare, and scan byte or word strings. One-byte repeat prefixes
+can cause the operation of a string primitive to be repeated to process
+strings as long as 64K bytes.
+
+The repeated string primitives use the direction flag, DF, to specify
+left-to-right or right-to-left string processing, and use a count in CX to
+limit the processing operation. These instructions use the register pair
+DS:SI to point to the source string element and the register pair ES:DI to
+point to the destination.
+
+One of two possible opcodes represent each string primitive, depending on
+whether it is operating on byte strings or word strings. The string
+primitives are generic and require one or more operands along with the
+primitive to determine the size of the string elements being processed.
+These operands do not determine the addresses of the strings; the addresses
+must already be present in the appropriate registers.
+
+Each repetition of a string operation using the Repeat prefixes includes
+the following steps:
+
+ 1. Acknowledge pending interrupts.
+
+ 2. Check CX for zero and stop repeating if CX is zero.
+
+ 3. Perform the string operation once.
+
+ 4. Adjust the memory pointers in DS:SI and ES:DI by incrementing SI
+ and DI if DF is 0 or by decrementing SI and DI if DF is 1.
+
+ 5. Decrement CX (this step does not affect the flags).
+
+ 6. For SCAS (Scan String) and CMPS (Compare String), check ZF for a
+ match with the repeat condition and stop repeating if the ZF fails to
+ match.
+
+The Load String and Store String instructions allow a program to perform
+arithmetic or logical operations on string characters (using AX for word
+strings and AL for byte strings). Repeated operations that include
+instructions other than string primitives must use the loop instructions
+rather than a repeat prefix.
+
+
+3.7.2.1 String Movement Instructions
+
+REP (Repeat While CX Not Zero) specifies a repeated operation of a string
+primitive. The REP prefix causes the hardware to automatically repeat the
+associated string primitive until CX=0. This form of iteration allows the
+CPU to process strings much faster than would be possible with a regular
+software loop.
+
+When the REP prefix accompanies a MOVS instruction, it operates as a
+memory-to-memory block transfer. To set up for this operation, the program
+must initialize CX and the register pairs DS:SI and ES:DI. CX specifies the
+number of bytes or words in the block.
+
+If DF=0, the program must point DS:SI to the first element of the source
+string and point ES:DI to the destination address for the first element. If
+DF=1, the program must point these two register pairs to the last element of
+the source string and to the destination address for the last element,
+respectively.
+
+Example:
+ REP MOVSW. The processor checks the value in CX for zero. If this value is
+ not zero, the processor moves a word from the location pointed to by DS:SI
+ to the location pointed to by ES:DI and increments SI and DI by two (if
+ DF=0). Next, the processor decrements CX by one and returns to the
+ beginning of the repeat cycle to check CX again. After CX decrements to
+ zero, the processor executes the instruction that follows.
+
+MOVS (Move String) moves the string character pointed to by the combination
+of DS and SI to the location pointed to by the combination of ES and DI.
+This is the only memory-to-memory transfer supported by the instruction set
+of the base architecture. MOVSB operates on byte elements. The destination
+segment register cannot be overridden by a segment override prefix while
+the source segment register can be overridden.
+
+Example:
+ MOVSW. Moves the contents of the memory byte pointed to by DS:SI to the
+ location pointed to by ES:DI.
+
+
+3.7.2.2 Other String Operations
+
+CMPS (Compare Strings) subtracts the destination string element (ES:DI)
+from the source string element (DS:SI) and updates the flags AF, SF, PF, CF
+and OF. If the string elements are equal, ZF=1; otherwise, ZF=0. If DF=0,
+the processor increments the memory pointers (SI and DI) for the two
+strings. The segment register used for the source address can be changed
+with a segment override prefix, while the destination segment register
+cannot be overridden.
+
+Example:
+ CMPSB. Compares the source and destination string elements with each other
+ and returns the result of the comparison to ZF.
+
+SCAS (Scan String) subtracts the destination string element at ES:DI from
+AX or AL and updates the flags AF, SF, ZF, PF, CF and OF. If the values are
+equal, ZF=1; otherwise, ZF=0. If DF=0, the processor increments the memory
+pointer (DI) for the string. The segment register used for the source
+address can be changed with a segment override prefix while the destination
+segment register cannot be overridden.
+
+Example:
+ SCASW. Compares the value in AX with the destination string element.
+
+REPE/REPZ (Repeat While CX Equal/Zero) and REPNE/REPNZ (Repeat While CX Not
+Equal/Not Zero) are the prefixes that are used exclusively with the SCAS
+(ScanString) and CMPS (Compare String) primitives.
+
+The difference between these two types of prefix bytes is that REPE/REPZ
+terminates when ZF=0 and REPNE/REPNZ terminates when ZF=1. ZF does not
+require initialization before execution of a repeated string instruction.
+
+When these prefixes modify either the SCAS or CMPS primitives, the
+processor compares the value of the current string element with the value in
+AX for word elements or with the value in AL for byte elements. The
+resulting state of ZF can then limit the operation of the repeated
+operation as well as a zero value in CX.
+
+Example:
+ REPE SCASB. Causes the processor to scan the string pointed to by ES:DI
+ until it encounters a match with the byte value in AL or until CX
+ decrements to zero.
+
+LODS (Load String) places the source string element at DS:SI into AX for
+word strings or into AL for byte strings.
+
+Example:
+ LODSW. Loads AX with the value pointed to by DS:SI.
+
+
+3.8 Address Manipulation Instructions
+
+The set of address manipulation instructions provide a way to perform
+address calculations or to move to a new data segment or extra segment.
+
+LEA (Load Effective Address) transfers the offset of the source operand
+(rather than its value) to the destination operand. The source operand must
+be a memory operand, and the destination operand must be a 16-bit general
+register (AX, DX, BX, CX, BP, SP, SI, or DI).
+
+LEA does not affect any flags. This instruction is useful for initializing
+the registers before the execution of the string primitives or the XLAT
+instruction.
+
+Example:
+ LEA BX EBCDIC_TABLE. Causes the processor to place the address of the
+ starting location of the table labeled EBCDIC_TABLE into BX.
+
+LDS (Load Pointer Using DS) transfers a 32-bit pointer variable from the
+source operand to DS and the destination register. The source operand must
+be a memory operand, and the destination operand must be a 16-bit general
+register (AX, DX, BX, CX, BP, SP, SI or DI). DS receives the high-order
+segment word of the pointer. The destination register receives the
+low-order word, which points to a specific location within the segment.
+
+Example:
+ LDS SI, STRING_X. Loads DS with the word identifying the segment pointed
+ to by STRING_X, and loads the offset of STRING_X into SI. Specifying SI as
+ the destination operand is a convenient way to prepare for a string
+ operation on a source string that is not in the current data segment.
+
+LES (Load Pointer Using ES) operates identically to LDS except that ES
+receives the offset word rather than DS.
+
+Example:
+ LES DI, DESTINATION_X. Loads ES with the word identifying the segment
+ pointed to by DESTINATION_X, and loads the offset of DESTINATION_X into
+ DI. This instruction provides a convenient way to select a destination for
+ a string operation if the desired location is not in the current extra
+ segment.
+
+
+3.9 Flag Control Instructions
+
+The flag control instructions provide a method of changing the state of
+bits in the flag register.
+
+
+3.9.1 Carry Flag Control Instructions
+
+The carry flag instructions are useful in conjunction with
+rotate-with-carry instructions RCL and RCR. They can initialize the carry
+flag, CF, to a known state before execution of a rotate that moves the carry
+bit into one end of the rotated operand.
+
+STC (Set Carry Flag) sets the carry flag (CF) to 1.
+
+Example:
+ STC
+
+CLC (Clear Carry Flag) zeros the carry flag (CF).
+
+Example:
+ CLC
+
+CMC (Complement Carry Flag) reverses the current status of the carry flag
+(CF).
+
+Example:
+ CMC
+
+
+3.9.2 Direction Flag Control Instructions
+
+The direction flag control instructions are specifically included to set or
+clear the direction flag, DF, which controls the left-to-right or
+right-to-left direction of string processing. IF DF=0, the processor
+automatically increments the string memory pointers, SI and DI, after each
+execution of a string primitive. If DF=1, the processor decrements these
+pointer values. The initial state of DF is 0.
+
+CLD (Clear Direction Flag) zeros DF, causing the string instructions to
+auto-increment SI and/or DI. CLD does not affect any other flags.
+
+Example:
+ CLD
+
+STD (Set Direction Flag) sets DF to 1, causing the string instructions to
+auto-decrement SI and/or DI. STD does not affect any other flags.
+
+Example:
+ STD
+
+
+3.9.3 Flag Transfer Instructions
+
+Though specific instructions exist to alter CF and DF, there is no direct
+method of altering the other flags. The flag transfer instructions allow a
+program to alter the other flag bits with the bit manipulation instructions
+after transferring these flags to the stack or the AH register.
+
+The PUSHF and POPF instructions are also useful for preserving the state of
+the flag register before executing a procedure.
+
+LAHF (Load AH from Flags) copies SF, ZF, AF, PF, and CF to AH bits 7, 6, 4,
+2, and 0, respectively (see figure 3-13). The contents of the remaining
+bits (5, 3, and 1) are undefined. The flags remain unaffected. This
+instruction can assist in converting 8080/8085 assembly language programs to
+run on the base architecture of the 8086, 8088, 80186, 80188, and 80286.
+
+Example:
+ LAHF
+
+SAHF (Store AH into Flags) transfers bits 7, 6, 4, 2, and 0 from AH into
+SF, ZF, AF, PF, and CF, respectively (see figure 3-13). This instruction
+also provides 8080/8085 compatibility with the 8086, 8088, 80186, 80188, and
+80286.
+
+Example:
+ SAHF
+
+PUSHF (Push Flags) decrements SP by two and then transfers all flags to the
+word at the top of stack pointed to by SP (see figure 3-14). The flags
+remain unaffected. This instruction enables a procedure to save the state of
+the flag register for later use.
+
+Example:
+ PUSHF
+
+POPF (Pop Flags) transfers specific bits from the word at the top of stack
+into the low-order byte of the flag register (see figure 3-14). The
+processor then increments SP by two.
+
+Note that an application program in the protected virtual address mode may
+not alter IOPL (the I/O privilege level flag) unless the program is
+executing at privilege level 0. A program may alter IF (the interrupt flag)
+only when executing at a level that is at least as privileged as IOPL.
+
+Procedures may use this instruction to restore the flag status from a
+previous value.
+
+Example:
+ POPF
+
+
+Figure 3-13. LAHF and SAHF
+
+ 7 6 5 4 3 2 1 0
+ ╔════╤════╤════╤════╤════╤════╤════╤════╗
+ ║ SF │ ZF │▒▒▒▒│ AF │▒▒▒▒│ PF │▒▒▒▒│ CF ║
+ ╚════╧════╧════╧════╧════╧════╧════╧════╝
+ REGISTER AH
+
+ LAHF loads five flags from the flag register into register AH. SAHF stores
+ these same five flgs from AH into the flag register. The bit position of
+ each flag is the same in AH as it is in the flag register. The remaining
+ bits are indeterminate.
+
+
+Figure 3-14. PUSHF and POPF
+
+ 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+ ╔═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╗
+ ║▒▒▒│NT │ IOPL │OF │DF │IF │TF │SF │ZF │▒▒▒│AF │▒▒▒│PF │▒▒▒│CF ║
+ ╚═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╝
+ STACK WORD
+
+ PUSHF decrements SP by 2 bytes (1 word) and copies the contents of the flag
+ register to the top of the stack. POPF loads the flag register with the
+ contents of the last word pushed onto the stack. The bit position of each
+ flag is the same in the stack word as it is in the flag register. Only
+ programs executing at the highest privilege level (level 0) may alter the
+ 2-bit IOPL flag. Only programs executing at a level at least as privileged
+ as that indicated by IOPL may alter IF.
+
+
+3.10 Binary-Coded Decimal Arithmetic Instructions
+
+These instructions adjust the results of a previous arithmetic operation to
+produce a valid packed or unpacked decimal result. These instructions
+operate only on AL or AH registers.
+
+
+3.10.1 Packed BCD Adjustment Instructions
+
+DAA (Decimal Adjust) corrects the result of adding two valid packed decimal
+operands in AL. DAA must always follow the addition of two pairs of packed
+decimal numbers (one digit in each nibble) to obtain a pair of valid packed
+decimal digits as results. The carry flag will be set if carry was needed.
+
+Example:
+ DAA
+
+DAS (Decimal Adjust for Subtraction) corrects the result of subtracting two
+valid packed decimal operands in AL. DAS must always follow the subtraction
+of one pair of packed decimal numbers (one digit in each nibble) from
+another to obtain a pair of valid packed decimal digits as results. The
+carry flag will be set if a borrow was needed.
+
+Example:
+ DAS
+
+
+3.10.2 Unpacked BCD Adjustment Instructions
+
+AAA (ASCII Adjust for Addition) changes the contents of register AL to a
+valid unpacked decimal number, and zeros the top 4 bits. AAA must always
+follow the addition of two unpacked decimal operands in AL. The carry flag
+will be set and AH will be incremented if a carry was necessary.
+
+Example:
+ AAA
+
+AAS (ASCII Adjust for Subtraction) changes the contents of register AL to a
+valid unpacked decimal number, and zeros the top 4 bits. AAS must always
+follow the subtraction of one unpacked decimal operand from another in AL.
+The carry flag will be set and AH decremented if a borrow was necessary.
+
+Example:
+ AAS
+
+AAM (ASCII Adjust for Multiplication) corrects the result of a
+multiplication of two valid unpacked decimal numbers. AAM must always follow
+the multiplication of two decimal numbers to produce a valid decimal result.
+The high order digit will be left in AH, the low order digit in AL.
+
+Example:
+ AAM
+
+AAD (ASCII Adjust for Division) modifies the numerator in AH and AL to
+prepare for the division of two valid unpacked decimal operands so that the
+quotient produced by the division will be a valid unpacked decimal number.
+AH should contain the high-order digit and AL the low-order digit. This
+instruction will adjust the value and leave it in AL. AH will contain 0.
+
+Example:
+ AAD
+
+
+3.11 Trusted Instructions
+
+When operating in Protected Mode (Chapter 6 and following), the 80286
+processor restricts the execution of trusted instructions according to the
+Current Privilege Level (CPL) and the current value of IOPL, the 2-bit I/O
+privilege flag. Only a program operating at the highest privilege level
+(level 0) may alter the value of IOPL. A program may execute trusted
+instructions only when executing at a level that is at least as privileged
+as that specified by IOPL.
+
+Trusted instructions control I/O operations, interprocessor communications
+in a multiprocessor system, interrupt enabling, and the HLT instruction.
+
+These protection considerations do not apply in the real address mode.
+
+
+3.11.1 Trusted and Privileged Restrictions on POPF and IRET
+
+POPF (POP Flags) and IRET (Interrupt Return) are not affected by IOPL
+unless they attempt to alter IF (flag register bit 9). To change IF, POPF
+must be part of a program that is executing at a privilege level greater
+than or equal to that specified by IOPL. Any attempt to change IF when
+CPL ≥ 0 will be ignored (i.e., the IF flag will be ignored). To change the
+IOPL field, CPL must be zero.
+
+
+3.11.2 Machine State Instructions
+
+These trusted instructions affect the machine state control interrupt
+response, the processor halt state, and the bus LOCK signal that regulates
+memory access in multiprocessor systems.
+
+CLI (Clear Interrupt-Enable Flag) and STI (Set Interrupt-Enable Flag) alter
+bit 9 in the flag register. When IF=0, the processor responds only to
+internal interrupts and to non-maskable external interrupts. When IF=1, the
+processor responds to all interrupts. An interrupt service routine might
+use these instructions to avoid further interruption while it processes a
+previous interrupt request. As with the other flag bits, the processor
+clears IF during initialization. These instructions may be executed only if
+CPL ≤ IOPL. A protection exception will occur if they are executed when
+CPL > IOPL.
+
+Example:
+ STI. Sets IF=1, which enables the processing of maskable external
+ interrupts.
+
+Example:
+ CLI. Sets IF=0 to disable maskable interrupt processing.
+
+HLT (Halt) causes the processor to suspend processing operations pending an
+interrupt or a system reset. This trusted instruction provides an
+alternative to an endless software loop in situations where a program must
+wait for an interrupt. The return address saved after the interrupt will
+point to the instruction immediately following HLT. This instruction may be
+executed only when CPL = 0.
+
+Example:
+ HLT
+
+LOCK (Assert Bus Lock) is a 1-byte prefix code that causes the processor to
+assert the bus LOCK signal during execution of the instruction that follows.
+LOCK does not affect any flags. LOCK may be used only when CPL ≤ IOPL. A
+protection exception will occur if LOCK is used when CPL > IOPL.
+
+
+3.11.3 Input and Output Instructions
+
+These trusted instructions provide access to the processor's I/O ports to
+transfer data to and from peripheral devices. In Protected Mode, these
+instructions may be executed only when CPL ≤ IOPL.
+
+IN (Input from Port) transfers a byte or a word from an input port to AL or
+AX. If a program specifies AL with the IN instruction, the processor
+transfers 8 bits from the selected port to AL. Alternately, if a program
+specifies AX with the IN instruction, the processor transfers 16 bits from
+the port to AX.
+
+The program can specify the number of the port in two ways. Using an
+immediate byte constant, the program can specify 256 8-bit ports numbered 0
+through 255 or 128 16-bit ports numbered 0,2,4,...,252,254. Using the
+current value contained in DX, the program can specify 8-bit ports numbered
+0 through 65,535, or 16-bit ports using even-numbered ports in the same
+range.
+
+Example:
+ IN AL,
+ BYTE_PORT_NUMBER. Transfers 8 bits to AL from the port identified by the
+ immediate constant BYTE_PORT_NUMBER.
+
+OUT (Output to Port) transfers a byte or a word to an output port from AL
+or AX. The program can specify the number of the port using the same methods
+of the IN instruction.
+
+Example:
+ OUT AX, DX. Transfers 16 bits from AX to the port identified by the 16-bit
+ number contained in DX.
+
+INS and OUTS (Input String and Output String) cause block input or output
+operations using a Repeat prefix. See Chapter 4 for more information on INS
+and OUTS.
+
+
+3.12 Processor Extension Instructions
+
+Processor Extension provides an extension to the instruction set of the
+base architecture (e.g., 80287). The NPX extends the instruction set of the
+CPU-based architecture to support high-precision integer and floating-point
+calculations. This extended instruction set includes arithmetic,
+comparison, transcendental, and data transfer instructions. The NPX also
+contains a set of useful constants to enhance the speed of numeric
+calculations.
+
+A program contains instructions for the NPX in line with the instructions
+for the CPU. The system executes these instructions in the same order as
+they appear in the instruction stream. The NPX operates concurrently with
+the CPU to provide maximum throughput for numeric calculations.
+
+The software emulation of the NPX is transparent to application software
+but requires more time for execution.
+
+
+3.12.1 Processor Extension Synchronization Instructions
+
+Escape and wait instructions allow a processor extension such as the 80287
+NPX to obtain instructions and data from the system bus and to wait for the
+NPX to return a result.
+
+ESC (Escape) identifies floating point numeric instructions and allows the
+80286 to send the opcode to the NPX or to transfer a memory operand to the
+NPX. The 80287 NPX uses the Escape instructions to perform high-performance,
+high-precision floating point arithmetic that conforms to the IEEE floating
+point standard 754.
+
+Example:
+ ESC 6, ARRAY [SI]. The CPU sends the escape opcode 6 and the location of
+ the array pointed to by SI to the NPX.
+
+WAIT (Wait) suspends program execution until the 80286 CPU detects a signal
+on the BUSY pin. In a configuration that includes a numeric processor
+extension, the NPX activates the BUSY pin to signal that it has completed
+its processing task and that the CPU may obtain the results.
+
+Example:
+ WAIT
+
+
+3.12.2 Numeric Data Processor Instructions
+
+This section describes the categories of instructions available with
+Numeric Data Processor systems that include a Numeric Processor Extension or
+a software emulation of this processor extension.
+
+
+3.12.2.1 Arithmetic Instructions
+
+The extended instruction set includes not only the four arithmetic
+operations (add, subtract, multiply, and divide), but also subtract-reversed
+and divide-reversed instructions. The arithmetic functions include square
+root, modulus, absolute value, integer part, change sign, scale exponent,
+and extract exponent instructions.
+
+
+3.12.2.2 Comparison Instructions
+
+The comparison operations are the compare, examine, and test instructions.
+Special forms of the compare instruction can optimize algorithms by allowing
+comparisons of binary integers with real numbers in memory.
+
+
+3.12.2.3 Transcendental Instructions
+
+The instructions in this group perform the otherwise time-consuming
+calculations for all common trigonometric, inverse trigonometric,
+hyperbolic, inverse hyperbolic, logarithmic, and exponential functions. The
+transcendental instructions include tangent, arctangent, 2 x-1, Y. log{2} X,
+and Y. log{2} (X+1).
+
+
+3.12.2.4 Data Transfer Instructions
+
+The data transfer instructions move operands among the registers and
+between a register and memory. This group includes the load, store, and
+exchange instructions.
+
+
+3.12.2.5 Constant Instructions
+
+Each of the constant instructions loads a commonly used constant into an
+NPX register. The values have a real precision of 64 bits and are accurate
+to approximately 19 decimal places. The constants loaded by these
+instructions include 0, 1, Pi, log{e} 10, log{2} e, log{10} 2, and log 2{e}.
+
+
+Chapter 4 Extended Instruction Set
+
+───────────────────────────────────────────────────────────────────────────
+
+The instructions described in this chapter extend the capabilities of the
+base architecture instruction set described in Chapter 3. These extensions
+consist of new instructions and variations of some instructions that are not
+strictly part of the base architecture (in other words, not included on the
+8086 and 8088). These instructions are also available on the 80186 and
+80188. The instruction variations, described in Chapter 3, include the
+immediate forms of the PUSH and MUL instructions, PUSHA, POPA, and the
+privilege level restrictions on POPF.
+
+New instructions described in this chapter include the string input and
+output instructions (INS and OUTS), the ENTER procedure and LEAVE procedure
+instructions, and the check index BOUND instruction.
+
+
+4.1 Block I/O Instructions
+
+REP, the Repeat prefix, modifies INS and OUTS (the string I/O instructions)
+to provide a means of transferring blocks of data between an I/O port and
+Memory. These block I/O instructions are string primitives. They simplify
+programming and increase the speed of data transfer by eliminating the need
+to use a separate LOOP instruction or an intermediate register to hold the
+data.
+
+INS and OUTS are trusted instructions. To use trusted instructions, a
+program must execute at a privilege level at least as privileged as that
+specified by the 2-bit IOPL flag (CPL ≤ IOPL). Any attempt by a
+less-privileged program to use a trusted instruction results in a
+protection exception. See Chapter 7 for information on protection concepts.
+
+One of two possible opcodes represents each string primitive depending on
+whether it operates on byte strings or word strings. After each transfer,
+the memory address in SI or DI is updated by 1 for byte values and by 2 for
+word values. The value in the DF field determines if SI or DI is to be auto
+incremented (DF=0) or auto decremented (DF=1).
+
+INS and OUTS use DX to specify I/O ports numbered 0 through 65,535 or
+16-bit ports using only even port addresses in the same range.
+
+INS (Input String from Port) transfers a byte or a word string element from
+an input port to memory. If a program specifies INSB, the processor
+transfers 8 bits from the selected port to the memory location indicated by
+ES:DI. Alternately, if a program specifies INSW, the processor transfers 16
+bits from the port to the memory location indicated by ES:DI. The
+destination segment register choice (ES) cannot be changed for the INS
+instruction.
+
+Combined with the REP prefix, INS moves a block of information from an
+input port to a series of consecutive memory locations.
+
+Example:
+ REP INSB. The processor repeatedly transfers 8 bits to the memory
+ location indicated by ES:DI from the port selected by the 16-bit port
+ number contained in DX. Following each byte transfer, the CPU
+ decrements CX. The instruction terminates the block transfer when CX=0.
+ After decrementing CX, the processor increments DI by one if DF=0. It
+ decrements DI by one if DF=1.
+
+OUTS (Output String to Port) transfers a byte or a word string element to
+an output port from memory. Combined with the REP prefix, OUTS moves a block
+of information from a series of consecutive memory locations indicated by
+DS:SI to an output port.
+
+Example:
+ REP OUTS WSTRING. Assuming that the program declares WSTRING to be a
+ word-length string element, the assembler uses the 16-bit form of the OUTS
+ instruction to create the object code for the program. The processor
+ repeatedly transfers words from the memory locations indicated by DI to
+ the output port selected by the 16-bit port number in DX.
+
+Following each word transfer, the CPU decrements CX. The instruction
+terminates the block transfer when CX=0. After decrementing CX, the
+processor increments SI by two to point to the next word in memory if DF=0;
+it decrements SI by two if DF=1.
+
+
+4.2 High-Level Instructions
+
+The instructions in this section provide machine-language functions
+normally found only in high-level languages. These instructions include
+ENTER and LEAVE, which simplify the programming of procedures, and BOUND,
+which provides a simple method of testing an index against its predefined
+range.
+
+ENTER (Enter Procedure) creates the stack frame required by most
+block-structured high-level languages. A LEAVE instruction at the end of a
+procedure complements an ENTER at the beginning of the procedure to simplify
+stack management and to control access to variables for nested procedures.
+
+Example:
+ ENTER 2048,3. Allocates 2048 bytes of dynamic storage on the stack and
+ sets up pointers to two previous stack frames in the stack frame that
+ ENTER creates for this procedure.
+
+The ENTER instruction includes two parameters. The first parameter
+specifies the number of bytes of dynamic storage to be allocated on the
+stack for the routine being entered. The second parameter corresponds to the
+lexical nesting level (0-31) of the routine. (Note that the lexical level
+has no relationship to either the protection privilege levels or to the I/O
+privilege level.)
+
+The specified lexical level determines how many sets of stack frame
+pointers the CPU copies into the new stack frame from the preceding frame.
+This list of stack frame pointers is sometimes called the "display." The
+first word of the display is a pointer to the last stack frame. This
+pointer enables a LEAVE instruction to reverse the action of the previous
+ENTER instruction by effectively discarding the last stack frame.
+
+After ENTER creates the new display for a procedure, it allocates the
+dynamic storage space for that procedure by decrementing SP by the number of
+bytes specified in the first parameter. This new value of SP serves as a
+base for all PUSH and POP operations within that procedure.
+
+To enable a procedure to address its display, ENTER leaves BP pointing to
+the beginning of the new stack frame. Data manipulation instructions that
+specify BP as a base register implicitly address locations within the stack
+segment instead of the data segment. Two forms of the ENTER instruction
+exist: nested and non-nested. If the lexical level is 0, the non-nested form
+is used. Since the second operand is 0, ENTER pushes BP, copies SP to BP and
+then subtracts the first operand from SP. The nested form of ENTER occurs
+when the second parameter (lexical level) is not 0. Figure 4-1 gives the
+formal definition of ENTER.
+
+The main procedure (with other procedures nested within) operates at the
+highest lexical level, level 1. The first procedure it calls operates at the
+next deeper lexical level, level 2. A level 2 procedure can access the
+variables of the main program which are at fixed locations specified by the
+compiler. In the case of level 1, ENTER allocates only the requested dynamic
+storage on the stack because there is no previous display to copy.
+
+A program operating at a higher lexical level calling a program at a lower
+lexical level requires that the called procedure should have access to the
+variables of the calling program. ENTER provides this access through a
+display that provides addressability to the calling program's stack frame.
+
+A procedure calling another procedure at the same lexical level implies
+that they are parallel procedures and that the called procedure should not
+have access to the variables of the calling procedure. In this case, ENTER
+copies only that portion of the display from the calling procedure which
+refers to previously nested procedures operating at higher lexical levels.
+The new stack frame does not include the pointer for addressing the calling
+procedure's stack frame.
+
+ENTER treats a reentrant procedure as a procedure calling another procedure
+at the same lexical level. In this case, each succeeding iteration of the
+reentrant procedure can address only its own variables and the variables of
+the calling procedures at higher lexical levels. A reentrant procedure can
+always address its own variables; it does not require pointers to the stack
+frames of previous iterations.
+
+By copying only the stack frame pointers of procedures at higher lexical
+levels, ENTER makes sure that procedures access only those variables of
+higher lexical levels, not those at parallel lexical levels (see figure
+4-2). Figures 4-2a, 4-2b, 4-2c, and 4-2d demonstrate the actions of the
+ENTER instruction if the modules shown in figure 4-1 were to call one
+another in alphabetic order.
+
+Block-structured high-level languages can use the lexical levels defined by
+ENTER to control access to the variables of previously nested procedures.
+For example, if PROCEDURE A calls PROCEDURE B which, in turn, calls
+PROCEDURE C, then PROCEDURE C will have access to the variables of MAIN and
+PROCEDURE A, but not PROCEDURE B because they operate at the same lexical
+level. Following is the complete definition of the variable access for
+figure 4-2.
+
+ 1. MAIN PROGRAM has variables at fixed locations.
+
+ 2. PROCEDURE A can access only the fixed variables of MAIN.
+
+ 3. PROCEDURE B can access only the variables of PROCEDURE A and MAIN.
+ PROCEDURE B cannot access the variables of PROCEDURE C or PROCEDURE D.
+
+ 4. PROCEDURE C can access only the variables of PROCEDURE A and MAIN.
+ PROCEDURE C cannot access the variables of PROCEDURE B or PROCEDURE D.
+
+ 5. PROCEDURE D can access the variables of PROCEDURE C, PROCEDURE A, and
+ MAIN. PROCEDURE D cannot access the variables of PROCEDURE B.
+
+ENTER at the beginning of the MAIN PROGRAM creates dynamic storage space
+for MAIN but copies no pointers. The first and only word in the display
+points to itself because there is no previous value for LEAVE to return to
+BP. See figure 4-2a.
+
+After MAIN calls PROCEDURE A, ENTER creates a new display for PROCEDURE A
+with the first word pointing to the previous value of BP (BPM for LEAVE to
+return to the MAIN stack frame) and the second word pointing to the current
+value of BP. Procedure A can access variables in MAIN since MAIN is at level
+1. Therefore the base for the dynamic storage for MAIN is at [BP-2]. All
+dynamic variables for MAIN will be at a fixed offset from this value. See
+figure 4-2b.
+
+After PROCEDURE A calls PROCEDURE B, ENTER creates a new display for
+PROCEDURE B with the first word pointing to the previous value of BP, the
+second word pointing to the value of BP for MAIN, and the third word
+pointing to the value of BP for A and the last word pointing to the current
+BP. B can access variables in A and MAIN by fetching from the display the
+base addresses of the respective dynamic storage areas. See figure 4-2c.
+
+After PROCEDURE B calls PROCEDURE C, ENTER creates a new display for
+PROCEDURE C with the first word pointing to the previous value of BP, the
+second word pointing to the value of BP for MAIN, and the third word
+pointing to the BP value for A and the third word pointing to the current
+value of BP. Because PROCEDURE B and PROCEDURE C have the same lexical
+level, PROCEDURE C is not allowed access to variables in B and therefore
+does not receive a pointer to the beginning of PROCEDURE B's stack frame.
+See figure 4-2d.
+
+LEAVE (Leave Procedure) reverses the action of the previous ENTER
+instruction. The LEAVE instruction does not include any operands.
+
+Example:
+ LEAVE. First, LEAVE copies BP to SP to release all stack space allocated
+ to the procedure by the most recent ENTER instruction. Next, LEAVE pops
+ the old value of BP from the stack. A subsequent RET instruction can then
+ remove any arguments that were pushed on the stack by the calling program
+ for use by the called procedure.
+
+BOUND (Detect Value Out of Range) verifies that the signed value contained
+in the specified register lies within specified limits. An interrupt (INT 5)
+occurs if the value contained in the register is less than the lower bound
+or greater than the upper bound.
+
+The BOUND instruction includes two operands. The first operand specifies
+the register being tested. The second operand contains the effective
+relative address of the two signed BOUND limit values. The BOUND instruction
+assumes that it can obtain the upper limit from the memory word that
+immediately follows the lower limit. These limit values cannot be register
+operands; if they are, an invalid opcode exception occurs.
+
+BOUND is useful for checking array bounds before using a new index value to
+access an element within the array. BOUND provides a simple way to check the
+value of an index register before the program overwrites information in a
+location beyond the limit of the array.
+
+The two-word block of memory that specifies the lower and upper limits of
+an array might typically reside just before the array itself. This makes the
+array bounds accessible at a constant offset of -4 from the beginning of the
+array. Because the address of the array will already be present in a
+register, this practice avoids extra calculations to obtain the effective
+address of the array bounds.
+
+Example:
+ BOUND BX,ARRAY-4. Compares the value in BX with the lower limit at
+ address ARRAY-4 and the upper limit at address ARRAY-2. If the signed
+ value in BX is less than the lower bound or greater than the upper bound,
+ the interrupt for this instruction (INT 5) occurs. Otherwise, this
+ instruction has no effect.
+
+
+Figure 4-1. Formal Definition of the ENTER Instruction
+
+The Formal Definition Of The ENTER Instruction. For All Cases Is Given By
+The Following Listing. LEVEL Denotes The Value Of The Second Operand.
+
+Push BP
+Set a temporary value FRAME_PTR:=SP
+If LEVEL > 0 then
+ Repeat (LEVEL - 1) times:
+ BP:=BP - 2
+ Push the word pointed to by BP
+ End repeat
+ Push FRAME_PTR
+End if
+BP:=FRAME_PTR
+SP:=SP - first operand.
+
+
+Figure 4-2. Variable Access in Nested Procedures
+
+ ╔═════════════════════════════════════════╗
+ ║ MAIN PROGRAM (LEXICAL LEVEL 1) ║
+ ║ ╔═════════════════════════════════════╗ ║
+ ║ ║ PROCEDURE A (LEXICAL LEVEL 2) ║ ║
+ ║ ║ ╔═════════════════════════════╗ ║ ║
+ ║ ║ ║PROCEDURE B (LEXICAL LEVEL 3)║ ║ ║
+ ║ ║ ╚═════════════════════════════╝ ║ ║
+ ║ ║ ║ ║
+ ║ ║ ╔═════════════════════════════════╗ ║ ║
+ ║ ║ ║ PROCEDURE C (LEXICAL LEVEL 3) ║ ║ ║
+ ║ ║ ║ ╔═════════════════════════════╗ ║ ║ ║
+ ║ ║ ║ ║PROCEDURE D (LEXICAL LEVEL 4)║ ║ ║ ║
+ ║ ║ ║ ╚═════════════════════════════╝ ║ ║ ║
+ ║ ║ ║ ║ ║ ║
+ ║ ║ ╚═════════════════════════════════╝ ║ ║
+ ║ ║ ║ ║
+ ║ ╚═════════════════════════════════════╝ ║
+ ║ ║
+ ╚═════════════════════════════════════════╝
+
+
+Figure 4-2a. Stack Frame for MAIN at Level 1
+
+ • •
+ ║ 15 0 ║
+ ╠═══════════════╣─┐
+ ║ OLD BP ║ │
+ BP FOR MAIN──►╠═══════════════╣ ├─DISPLAY
+ ║ BPM
+BPM = BP value for MAIN ║ │
+ ╠═══════════════╣─┘
+ ║ ║
+ ║ ║
+ ║ ║∙DYNAMIC
+ ║ ║ STORAGE
+ ║ ║
+ SP──►╠═══════════════╣
+ ║ ║
+
+
+Figure 4-2b. Stack Frame for PROCEDURE A
+
+ ║15 0║
+ ╠═══════════════╣
+ ║ OLD BP ║
+ ╠═══════════════╣
+ ║ BPM ║
+ ╠═══════════════╣
+ ║ ║
+ ║ ║
+ ║ ║
+ ║ ║
+ ╠═══════════════╣─┐
+ ║ BPM ║ │
+ BP FOR A──►╠═══════════════╣ │
+ ║ BPM ║ │
+ ╠═══════════════╣ ├─DISPLAY
+ ║ BPA
+BPA = BP value for PROCEDURE A ║ │
+ ╠═══════════════╣═╡
+ ║ ║ │
+ ║ ║ ├─DYNAMIC
+ ║ ║ │ STORAGE
+ ║ ║ │
+ SP──►╠═══════════════╣─┘
+ ║ ║
+ ╠═══════════════╣
+ ║ ║
+
+
+Figure 4-2c. Stack Frame for PROCEDURE B at Level 3 Called from A
+
+ ║15 0║
+ ╠═══════════════╣
+ ║ OLD BP ║
+ ╠═══════════════╣
+ ║ BPM ║
+ ╠═══════════════╣
+ ║ ║
+ ║ ║
+ ║ ║
+ ║ ║
+ ╠═══════════════╣
+ ║ BPM ║
+ ╠═══════════════╣
+ ║ BPM ║
+ ╠═══════════════╣
+ ║ BPA ║
+ ╠═══════════════╣
+ ║ ║
+ ║ ║
+ ║ ║
+ ║ ║
+ ╠═══════════════╣─┐
+ ║ BPA ║ │
+ BP──►╠═══════════════╣ │
+ ║ BPM ║ │
+ ╠═══════════════╣ ├─DISPLAY
+ ║ BPA ║ │
+ ╠═══════════════╣ │
+ ║ BPB ║ │
+ ╠═══════════════╣═╡
+ ║ ║ │
+ ║ ║ ├─DYNAMIC
+ ║ ║ │ STORAGE
+ ║ ║ │
+ ╠═══════════════╣─┘
+ ║ ║
+ SP──►╠═══════════════╣
+ ║ ║
+
+
+Figure 4-2d. Stack Frame for PROCEDURE C at Level 3 Called from B
+
+ ║15 0║
+ ╠═══════════════╣
+ ║ OLD BP ║
+ ╠═══════════════╣
+ ║ BPM ║
+ ╠═══════════════╣
+ ║ ║
+ ║ ║
+ ║ ║
+ ║ ║
+ ╠═══════════════╣
+ ║ BPM ║
+ ╠═══════════════╣
+ ║ BPM ║
+ ╠═══════════════╣
+ ║ BPA ║
+ ╠═══════════════╣
+ ║ ║
+ ║ ║
+ ║ ║
+ ║ ║
+ ╠═══════════════╣
+ ║ BPA ║
+ BP──►╠═══════════════╣─┐
+ ║ BPM ║ │
+ ╠═══════════════╣ │
+ ║ BPA ║ ├─DISPLAY
+ ╠═══════════════╣ │
+ ║ BPB ║ │
+ ╠═══════════════╣═╡
+ ║ ║ │
+ ║ ║ ├─DYNAMIC
+ ║ ║ │ STORAGE
+ ║ ║ │
+ SP──►╠═══════════════╣─┘
+ ║ ║
+
+
+Chapter 5 Real Address Mode
+
+───────────────────────────────────────────────────────────────────────────
+
+The 80286 can be operated in either of two modes according to the status of
+the Protection Enabled bit of the MSW status register. In contrast to the
+"modes" and "mode bits" of some processors, however, the 80286 modes do not
+represent a radical transition between conflicting architectures. Instead,
+the setting of the Protection Enabled bit simply determines whether certain
+advanced features, in addition to the baseline architecture of the 80286,
+are to be made available to system designers and programmers.
+
+If the Protection Enabled (PE) bit is set by the programmer, the processor
+changes into Protected Virtual Address Mode. In this mode of operation,
+memory addressing is performed in terms of virtual addresses, with on-chip
+mapping mechanisms performing the virtual-to-physical translation. Only in
+this mode can the system designer make use of the advanced architectural
+features of the 80286: virtual memory support, system-wide protection, and
+built-in multitasking mechanisms are among the new features provided in this
+mode of operation. Refer to Part II of this book (Chapters 6, 7, 8, 9,
+10, and 11) for details on Protected Mode operation.
+
+Initially, upon system reset, the processor starts up in Real Address Mode.
+In this mode of operation, all memory addressing is performed in terms of
+real physical addresses. In effect, the architecture of the 80286 in
+this mode is identical to that of the 8086 and other processors in the 8086
+family. The principal features of this baseline architecture have already
+been discussed throughout Part I (Chapters 2, 3, and 4) of this book.
+This chapter discusses certain additional topics──addressing, interrupt
+handling, and system initialization──that complete the system programmer's
+view of the 80286 in Real Address Mode.
+
+
+5.1 Addressing and Segmentation
+
+Like other processors in the 8086 family, the 80286 provides a one-megabyte
+memory space (2^(20) bytes) when operated in Real Address Mode. Physical
+addresses are the 20-bit values that uniquely identify each byte location in
+this address space. Physical addresses, therefore, may range from 0 through
+FFFFFH. Address bits A20-A23 may not always be zero in Real Address Mode.
+A20-A23 should not be used by the system while the 80286 is operating in
+Real Address Mode.
+
+An address is specified by a 32-bit pointer containing two components: (1)
+a 16-bit effective address offset that determines the displacement, in
+bytes, of a particular location within a segment; and (2) a 16-bit segment
+selector component that determines the starting address of the segment.
+Both components of an address may be referenced explicitly by an instruction
+(such as JMP, LES, LDS, or CALL); more often, however, the segment selector
+is simply the contents of a segment register.
+
+The interpretation of the first component, the effective address offset, is
+straight-forward. Segments are at most 64K (2^(16)) bytes in length, so an
+unsigned 16-bit quantity is sufficient to address any arbitrary byte
+location with a segment. The lowest-addressed byte within a segment has an
+offset of 0, and the highest-addressed byte has an offset of FFFFH. Data
+operands must be completely contained within a segment and must be
+contiguous. (These rules apply in both modes.)
+
+A segment selector is the second component of a logical address. This
+16-bit quantity specifies the starting address of a segment within a
+physical address space of 2^(20) bytes.
+
+Whenever the 80286 accesses memory in Real Address Mode, it generates a
+20-bit physical address from a segment selector and offset value. The
+segment selector value is left-shifted four bit positions to form the
+segment base address. The offset is extended with 4 high order zeroes and
+added to the base to form the physical address (see figure 5-1).
+
+Therefore, every segment is required to start at a byte address that is
+evenly divisible by 16; thus, each segment is positioned at a 20-bit
+physical address whose least significant four bits are zeroes. This
+arrangement allows the 80286 to interpret a segment selector as the
+high-order 16 bits of a 20-bit segment base address.
+
+No limit or access checks are performed by the 80286 in the Real Address
+Mode. All segments are readable, writable, executable, and have a limit of
+0FFFFH (65,535 bytes). To save physical memory, you can use unused portions
+of a segment as another segment by overlapping the two (see figure 5-2).
+The Intel 8086 software development tools support this feature via the
+segment override and group operators. However, programs that access segment
+B from segment A become incompatible in the protected virtual address mode.
+
+
+Figure 5-1a. Forming the Segment Base Address
+
+ 16 BIT SEGMENT SELECTOR
+ ┌───────────────────────┴───────────────────────┐
+ 15 0
+ ╔══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤ ═ ═ ═ ═ ═ ╗
+ ║ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │0 │0 │0 │0
+ ╚══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧ ═ ═ ═ ═ ═ ╝
+ 19 0
+
+
+Figure 5-1b. Forming the 20-bit Physical Address in the Real Address Mode
+
+ ╔══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤ ═ ═ ═ ═ ═ ╗
+ SEGMENT BASE ║ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │0 │0 │0 │0
+ ╚══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧ ═ ═ ═ ═ ═ ╝
+ 19 0
+ +
+ ╔ ═ ═ ═ ═ ═ ╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╗
+ OFFSET 0 │0 │0 │0 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ║
+ ╚ ═ ═ ═ ═ ═ ╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╝
+ 19 15 0
+ =
+ ─────────────────────────────────────────────────────────────
+ ╔══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╗
+ PHYSICAL ║ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ║
+ ADDRESS ╚══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╝
+ 19 0
+
+
+Figure 5-2. Overlapping Segments to Save Physical Memory
+
+ • •
+ ║ ║
+ ╟─ ── ── ── ── ─╫ ───
+ ║ ║ ▲
+ ║ ║ │
+ ║ ║ 64K SEGMENT B
+ ║ ║ │
+ ─── ╫─ ── ── ── ── ─╫ │
+ ▲ ║ OVERLAP ║ ▼
+ │ ╠═══════════════╣◄───── BASE OF
+ SEGMENT A 64K ║ ║ SEGMENT B
+ │ ║ ║
+ │ ║ ║
+ ▼ ║ ║
+ ─── ╠═══════════════╣◄───── BASE OF
+ ║ ║ SEGMENT A
+ • •
+
+
+5.2 Interrupt Handling
+
+Program interrupts may be generated in either of two distinct ways. An
+internal interrupt is caused directly by the currently executing program.
+The execution of a particular instruction results in the occurrence of an
+interrupt, whether intentionally (e.g., an INT n instruction) or as an
+unanticipated exception (e.g., invalid opcode). On the other hand, an
+external interrupt occurs asynchronously as the result of an event
+external to the processor, and bears no necessary relationship with the
+currently executing program. The INTR and NMI pins of the 80286 provide the
+means by which external hardware signals the occurrence of such events.
+
+
+5.2.1 Interrupt Vector Table
+
+Whatever its origin, whether internal or external, an interrupt demands
+immediate attention from an associated service routine. Control must be
+transferred, at least for the moment, from the currently executing program
+to the appropriate interrupt service routine. By means of interrupt
+vectors, the 80286 handles such control transfers uniformly for both kinds
+of interrupts.
+
+An interrupt vector is an unsigned integer in the range of 0-255; every
+interrupt is assigned such a vector. In some cases, the assignment is
+predetermined and fixed: for example, an external NMI interrupt is
+invariably associated with vector 2, while an internal divide exception is
+always associated with vector 0. In most cases, however, the association of
+an interrupt and a vector is established dynamically. An external INTR
+interrupt, for example, supplies a vector in response to an interrupt
+acknowledge bus cycle, while the INT n instruction supplies a vector
+incorporated within the instruction itself. The vector is shifted two places
+left to form a byte address into the table (see figure 5-3).
+
+In any case, the 80286 uses the interrupt vector as an index into a table
+in order to determine the address of the corresponding interrupt service
+routine. For Real Address Mode, this table is known as the Interrupt Vector
+Table. Its format is illustrated in figure 5-3.
+
+The Interrupt Vector Table consists of as many as 256 consecutive entries,
+each four bytes long. Each entry defines the address of a service routine to
+be associated with the correspondingly numbered interrupt vector code.
+Within each entry, an address is specified by a full 32-bit pointer that
+consists of a 16-bit offset and a 16-bit segment selector. Interrupts 0-31
+are reserved by Intel.
+
+In Real Address Mode, the interrupt table can be accessed directly at
+physical memory location 0 through 1023. In the protected virtual address
+mode, however, the interrupt vector table has no fixed physical address and
+cannot be directly accessed. Therefore, Real Address mode programs that
+directly manipulate the interrupt vector table will not work in the
+protected virtual address mode.
+
+
+Table 5-1. Interrupt Processing Order
+
+Order Interrupt
+1. Instruction exception
+2. Single step
+3. NMI
+4. Processor extension segment overrun
+5. INTR
+
+
+Figure 5-3. Interrupt Vector Table for Real Address Mode
+
+ POWER TO
+ INTERRUPT HANDLER PHYSICAL
+ FOR: ADDRESS
+
+ ╔═══════════════╗
+ INTERRUPT 255 ║ POINTER ║ 1020
+ ╠═══════════════╣
+ INTERRUPT 254 ║ POINTER ║ 1018
+ ╠═══════════════╣
+ INTERRUPT 253 ║ POINTER ║◄┐ 1012
+ ╠═══════════════╣ └────────────────────┐
+ ║ ║ ╔═════════════════╤╧═══════════╤═╤═╗
+ ║ ║ ║0 ∙ ∙ ∙ ∙ ∙ ∙ ∙ 0│ VECTOR │0│0║
+ ≈ ≈ ╚═════════════════╧════════════╧═╧═╝
+ ║ ║ 19 10 9 2 1 0
+ ║ ║
+ ╠═══════════════╣
+ INTERRUPT 1 ║ POINTER ║ 4
+ ╠═══════════════╣
+ INTERRUPT 0 ║ POINTER ║ 0
+ ╚═══════════════╝
+
+
+5.2.1.1 Interrupt Priorities
+
+When simultaneous interrupt requests occur, they are processed in a fixed
+order as shown in table 5-1. Interrupt processing involves saving the
+flags, the return address, and setting CS:IP to point at the first
+instruction of the interrupt handler. If other interrupts remain enabled,
+they are processed before the first instruction of the current interrupt
+handler is executed. The last interrupt processed is therefore the first one
+serviced.
+
+
+5.2.2 Interrupt Procedures
+
+When an interrupt occurs in Real Address Mode, the 8086 performs the
+following sequence of steps. First, the FLAGS register, as well as the old
+values of CS and IP, are pushed onto the stack (see figure 5-4). The IF and
+TF flag bits are cleared. The vector number is then used to read the
+address of the interrupt service routine from the interrupt table. Execution
+begins at this address.
+
+Thus, when control is passed to an interrupt service routine, the return
+linkage is placed on the stack, interrupts are disabled, and single-step
+trace (if in effect) is turned off. The IRET instruction at the end of the
+interrupt service routine will reverse these steps before transferring
+control to the program that was interrupted.
+
+An interrupt service routine may affect registers other than other IP, CS,
+and FLAGS. It is the responsibility of an interrupt routine to save
+additional context information before proceeding so that the state of the
+machine can be restored upon completion of the interrupt service routine
+(PUSHA and POPA instructions are intended for these operations). Finally,
+execution of the IRET instruction pops the old IP, CS, and FLAGS from the
+stack and resumes the execution of the interrupted program.
+
+
+Figure 5-4. Stack Structure after Interrupt (Real Address Mode)
+
+ ║ ║
+ ≈ ≈
+ ▲ ╠═══════════════╣
+ │ ║ OLD FLAGS ║
+ INCREASING │ ╠═══════════════╣
+ ADDRESSES │ ║ OLD CS ║
+ │ ╠═══════════════╣
+ │ ║ OLD IP ║◄── <SS:SP>
+ │ ╠═══════════════╣
+ ║ • ║
+ ≈ • ≈
+ ║ • ║
+
+
+5.2.3 Reserved and Dedicated Interrupt Vectors
+
+In general, the system designer is free to use almost any interrupt vectors
+for any given purpose. Some of the lowest-numbered vectors, however, are
+reserved by Intel for dedicated functions; their use is specifically implied
+by certain types of exceptions. None of the first 32 vectors should be
+defined by the user; these vectors are either invoked by pre-defined
+exceptions or reserved by Intel for future expansion. Table 5-2 shows the
+dedicated and reserved vectors of the 80286 in Real Address Mode.
+
+The purpose and function of the dedicated interrupt vectors may be
+summarized as follows (the saved value of CS:IP will include all leading
+prefixes):
+
+ ■ Divide error (Interrupt 0). This exception will occur if the quotient
+ is too large or an attempt is made to divide by zero using either the
+ DIV or IDIV instruction. The saved CS:IP points at the first byte of
+ the failing instruction. DX and AX are unchanged.
+
+ ■ Single-Step (Interrupt 1). This interrupt will occur after
+ each instruction if the Trap Flag (TF) bit of the FLAGS register is
+ set. Of course, TF is cleared upon entry to this or any other interrupt
+ to prevent infinite recursion. The saved value of CS:IP will point to
+ the next instruction.
+
+ ■ Nonmaskable (Interrupt 2). This interrupt will occur upon receipt of
+ an external signal on the NMI pin. Typically, the nonmaskable interrupt
+ is used to implement power-fail/auto-restart procedures. The saved
+ value of CS:IP will point to the first byte of the interrupted
+ instruction.
+
+ ■ Breakpoint (Interrupt 3). Execution of the one-byte breakpoint
+ instruction causes this interrupt to occur. This instruction is useful
+ for the implementation of software debuggers since it requires only one
+ code byte and can be substituted for any instruction opcode byte. The
+ saved value of CS:IP will point to the next instruction.
+
+ ■ INTO Detected Overflow (Interrupt 4). Execution of the INTO
+ conditional software interrupt instruction will cause this interrupt
+ to occur if the overflow bit (OF) of the FLAGS register is set. The
+ saved value of CS:IP will point to the next instruction.
+
+ ■ BOUND Range Exceeded (Interrupt 5). Execution of the BOUND instruction
+ will cause this interrupt to occur if the specified array index is
+ found to be invalid with respect to the given array bounds. The saved
+ value of CS:IP will point to the first byte of the BOUND instruction.
+
+ ■ Invalid Opcode (Interrupt 6). This exception will occur if execution
+ of an invalid opcode is attempted. (In Real Address Mode, most of the
+ Protected Virtual Address Mode instructions are classified as invalid
+ and should not be used). This interrupt can also occur if the
+ effective address given by certain instructions, notably BOUND, LDS,
+ LES, and LIDT, specifies a register rather than a memory location. The
+ saved value of CS:IP will point to the first byte of the
+ invalid instruction or opcode.
+
+ ■ Processor Extension Not Available (Interrupt 7). Execution of the ESC
+ instruction will cause this interrupt to occur if the status bits of
+ the MSW indicate that processor extension functions are to be emulated
+ in software. Refer to section 10.2.1 for more details. The saved value
+ of CS:IP will point to the first byte of the ESC or the WAIT
+ instruction.
+
+ ■ Interrupt Table Limit Too Small (Interrupt 8). This interrupt will
+ occur if the limit of the interrupt vector table was changed from 3FFH
+ by the LIDT instruction and an interrupt whose vector is outside the
+ limit occurs. The saved value of CS:IP will point to the first byte of
+ the instruction that caused the interrupt or that was ready to execute
+ before an external interrupt occurred. No error code is pushed.
+
+ ■ Processor Extension Segment Overrun Interrupt (Interrupt 9). The
+ interrupt will occur if a processor extension memory operand does not
+ fit in a segment. The saved CS:IP will point at the first byte of the
+ instruction that caused the interrupt.
+
+ ■ Segment Overrun Exception (Interrupt 13). This interrupt will occur if
+ a memory operand does not fit in a segment. In Real Mode this will
+ occur only when a word operand begins at segment offset 0FFFFH. The
+ saved CS:IP will point at the first byte of the instruction that
+ caused the interrupt. No error code is pushed.
+
+ ■ Processor Extension Error (Interrupt 16). This interrupt occurs after
+ the numeric instruction that caused the error. It can only occur while
+ executing a subsequent WAIT or ESC. The saved value of CS:IP will point
+ to the first byte of the ESC or the WAIT instruction. The address of
+ the failed numeric instruction is saved in the NPX.
+
+
+Table 5-2. Dedicated and Reserved Interrupt Vectors in Real Address Mode
+
+
+Function Interrupt Related Instructions Return Address
+ Number Before Instruction
+ Causing Exception?
+Divide error exception 0 DIV, IDIV Yes
+Single step interrupt 1 All N/A
+NMI interrupt 2 All N/A
+Breakpoint interrupt 3 INT N/A
+INTO detected overflow 4 INTO No
+exception
+BOUND range exceeded 5 BOUND Yes
+exception
+Invalid opcode exception 6 Any undefined opcode Yes
+Processor extension 7 ESC or WAIT Yes
+not available exception
+Interrupt table 8 LIDT Yes
+limit too small
+Processor extension 9 ESC Yes
+segment overrun interrupt
+Segment overrun exception 13 Any memory reference Yes
+ instruction that
+ attempts to reference
+ 16-bit word at
+ offset 0FFFFH.
+Reserved 10-12,
+ 14, 15
+Processor extension 16 ESC or WAIT N/A
+error interrupt
+Reserved 17-31
+User defined 32-255
+
+N/A = Not Applicable
+
+
+5.3 System Initialization
+
+The 80286 provides an orderly way to start or restart an executing system.
+Upon receipt of the RESET signal, certain processor registers go into the
+determinate state shown in table 5-3.
+
+Since the CS register contains F000 (thus specifying a code segment
+starting at physical address F0000) and the instruction pointer contains
+FFF0, the processor will execute its first instruction at physical address
+FFFF0H. The uppermost 16 bytes of physical memory are therefore reserved
+for initial startup logic. Ordinarily, this location contains an
+intersegment direct JMP instruction whose target is the actual beginning of
+a system initialization or restart program.
+
+Some of the steps normally performed by a system initialization routine are
+as follows:
+
+ ■ Allocate a stack.
+
+ ■ Load programs and data from secondary storage into memory.
+
+ ■ Initialize external devices.
+
+ ■ Enable interrupts (i.e., set the IF bit of the FLAGS register). Set
+ any other desired FLAGS bit as well.
+
+ ■ Set the appropriate MSW flags if a processor extension is present, or
+ if processor extension functions are to be emulated by software.
+
+ ■ Set other registers, as appropriate, to the desired initial values.
+
+ ■ Execute. (Ordinarily, this last step is performed as an intersegment
+ JMP to the main system program.)
+
+
+Table 5-3. Processor State after RESET
+
+Register Contents
+FLAGS 0002
+MSW FFF0
+IP FFF0
+CS F000
+DS 0000
+SS 0000
+ES 0000
+
+
+Chapter 6 Memory Management and Virtual Addressing
+
+───────────────────────────────────────────────────────────────────────────
+
+In Protected Virtual Address Mode, the 80286 provides an advanced
+architecture that retains substantial compatibility with the 8086 and other
+processors in the 8086 family. In many respects, the baseline architecture
+of the processor remains constant regardless of the mode of operation.
+Application programmers continue to use the same set of instructions,
+addressing modes, and data types in Protected Mode as in Real Address Mode.
+
+The major difference between the two modes of operation is that the
+Protected Mode provides system programmers with additional architectural
+features, supplementary to the baseline architecture, that can be used to
+good advantage in the design and implementation of advanced systems.
+Especially noteworthy are the mechanisms provided for memory management,
+protection, and multitasking.
+
+This chapter focuses on the memory management mechanisms of Protected Mode;
+the concept of a virtual address and the process of virtual-to-physical
+address translation are described in detail in this chapter. Subsequent
+chapters deal with other key aspects of Protected Mode operation. Chapter 7
+discusses the issue of protection and the integrated mechanisms that
+support a system-wide protection policy. Chapter 8 discusses the notion of
+a task and its central role in the 80286 architecture. Chapters 9, 10, and
+11 discuss certain additional topics──interrupt handling, special
+instructions, system initialization, etc.──that complete the system
+programmer's view of 80286 Protected Mode.
+
+
+6.1 Memory Management Overview
+
+A memory management scheme interposes a mapping operation between logical
+addresses (i.e., addresses as they are viewed by programs) and physical
+addresses (i.e., actual addresses in real memory). Since the logical address
+spaces are independent of physical memory (dynamically relocatable), the
+mapping (the assignment of real address space to virtual address space) is
+transparent to software. This allows the program development tools (for
+static systems) or the system software (for reprogrammable systems) to
+control the allocation of space in real memory without regard to the
+specifics of individual programs.
+
+Application programs may be translated and loaded independently since they
+deal strictly with virtual addresses. Any program can be relocated to use
+any available segments of physical memory.
+
+The 80286, when operated in Protected Mode, provides an efficient on-chip
+memory management architecture. Moreover, as described in Chapter 11, the
+80286 also supports the implementation of virtual memory systems──that is,
+systems that dynamically swap chunks of code and data between real memory
+and secondary storage devices (e.g., a disk) independent of and transparent
+to the executing application programs. Thus, a program-visible address is
+more aptly termed a virtual address rather than a logical address since it
+may actually refer to a location not currently present in real memory.
+
+Memory management, then, consists of a mechanism for mapping the virtual
+addresses that are visible to the program onto the physical addresses of
+real memory. With the 80286, segmentation is the key to virtual memory
+addressing. Virtual memory is partitioned into a number of individual
+segments, which are the units of memory that are mapped into physical memory
+and swapped to and from secondary storage devices. Most of this chapter is
+devoted to a detailed discussion of the mapping and virtual memory
+mechanisms of the 80286.
+
+The concept of a task also plays a significant role in memory management
+since distinct memory mappings may be assigned to the different tasks in a
+multitask or multi-user environment. A complete discussion of tasks is
+deferred until Chapter 8, "Tasks and State Transition." For present
+purposes, it is sufficient to think of a task as an ongoing process, or
+execution path, that is dedicated to a particular function. In a multi-user
+time-sharing environment, for example, the processing required to interact
+with a particular user may be considered as a single task, functionally
+independent of the other tasks (i.e., users) in the system.
+
+
+6.2 Virtual Addresses
+
+In Protected Mode, application programs deal exclusively with virtual
+addresses; programs have no access whatsoever to the actual physical
+addresses generated by the processor. As discussed in Chapter 2, an address
+is specified by a program in terms of two components: (1) a 16-bit
+effective address offset that determines the displacement, in bytes, of a
+location within a segment; and (2) a 16-bit segment selector that uniquely
+references a particular segment. Jointly, these two components constitute a
+complete 32-bit address (pointer data type), as shown in figure 6-1.
+
+These 32-bit virtual addresses are manipulated by programs in exactly the
+same way as the two-component addresses of Real Address Mode. After a
+program loads the segment selector component of an address into a segment
+register, each subsequent reference to locations within the selected
+segment requires only a 16-bit offset be specified. Locality of reference
+will ordinarily insure that addresses can be specified very efficiently
+using only 16-bit offsets.
+
+An important difference between Real Address Mode and Protected Mode,
+however, concerns the actual format and information content of segment
+selectors. In Real Address Mode, as with the 8086 and other processors in
+the 8086 family, a 16-bit selector is merely the upper bits of a segment's
+physical base address. By contrast, segment selectors in Protected Mode
+follow an entirely different format, as illustrated by figure 6-1.
+
+Two of the selector bits, designated as the RPL field in figure 6-1, are
+not actually involved in the selection and specification of segments; their
+use is discussed in Chapter 7.
+
+The remaining 14 bits of the selector component uniquely designate a
+particular segment. The virtual address space of a program, therefore, may
+encompass as many as 16,384 (2^(14)) distinct segments. Segments themselves
+are of variable size, ranging from as small as a single byte to as large as
+64K (2^(16)) bytes. Thus, a program's virtual address space may contain,
+altogether, up to a full gigabyte (2^(30) = 2^(14) * 2^(16)) of individually
+addressable byte locations.
+
+The entirety of a program's virtual address space is further subdivided
+into two separate halves, as distinguished by the TI ("table indicator") bit
+in the virtual address. These two halves are the global address space and
+the local address space.
+
+The global address space is used for system-wide data and procedures
+including operating system software, library routines, runtime language
+support and other commonly shared system services. (To application programs,
+the operating system appears to be a set of service routines that are
+accessible to all tasks.) Global space is shared by all tasks to avoid
+unnecessary replication of system service routines and to facilitate shared
+data and interrupt handling. Global address space is defined by addresses
+with a zero in the TI bit position; it is identically mapped for all tasks
+in the system.
+
+The other half of the virtual address space──comprising those addresses
+with the TI bit set──is separately mapped for each task in the system.
+Because such an address space is local to the task for which it is defined,
+it is referred to as a local address space. In general, code and data
+segments within a task's local address space are private to that particular
+task or user. Figure 6-2 illustrates the task isolation made possible by
+partitioning the virtual address spaces into local and global regions.
+
+Within each of the two regions addressable by a program──either the global
+address space or a particular local address space──as many as 8,192 (2^(13))
+distinct segments may be defined. The INDEX field of the segment selector
+allows for a unique specification of each of these segments. This 13-bit
+quantity acts as an index into a memory-resident table, called a descriptor
+table, that records the mapping between segment address and the physical
+locations allocated to each distinct segment. (These descriptor tables, and
+their role in virtual-to-physical address translation, are described in the
+sections that follow.)
+
+In summary, a Protected Mode virtual address is a 32-bit pointer to a
+particular byte location within a one-gigabyte virtual address space. Each
+such pointer consists of a 16-bit selector component and a 16-bit offset
+component. The selector component, in turn, comprises a 13-bit table index,
+a 1-bit table indicator (local versus global), and a 2-bit RPL field; all
+but this last field serve to select a particular segment from among the 16K
+segments in a task's virtual address space. The offset component of a full
+pointer is an unsigned 16-bit integer that specifies the desired byte
+location within the selected segment.
+
+
+Figure 6-1. Format of the Segment Selector Component
+
+ 32-BIT POINTER
+ ┌───────────────────┴───────────────────┐
+ 31 16 15 0
+ ╔════════════════════╤════════════════════╗
+ ║ SEGMENT SELECTOR │ SEGMENT OFFSET ║
+ ╚════════════════════╧════════════════════╝
+ │ │
+ │ │
+ │ │
+ ┌──┘ └───────────────────────┐
+ 15 3 2 1 0
+ ╔══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╤══╗
+ ║ INDEX │TI│ RPL ║
+ ╚══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╧══╝
+ └───────────────────────┬───────────────────────┘
+ SELECTOR
+
+
+Figure 6-2. Address Spaces and Task Isolation
+
+ ┌──────────────┐
+ │ ╔══════════╗ │
+ │ ║TASK 1 ║ │
+ │ ║LOCAL ║ │
+ TASK 3 │ ║ADDRESS ║ │
+ VIRTUAL ADDRESS SPACE ┐ │ ║SPACE ║ │◄────TASK 1
+ ▼ │ ╚══════════╝ │ VIRTUAL ADDRESS SPACE
+ ┌─────────────│──────────────│┐
+ │ ╔══════════╗│┌─────────────│───────────────┐
+ │ ║TASK 3 ║││ ╔════════╗ ││ ╔══════════╗ │
+ │ ║LOCAL ║││ ║GLOBAL ║ ││ ║TASK 2 ║ │
+ │ ║ADDRESS ║││ ║ADDRESS ║ ││ ║LOCAL ║ │
+ │ ║SPACE ║││ ║SPACE ║ ││ ║ADDRESS ║ │
+ │ ╚══════════╝││ ╚════════╝ ││ ║SPACE ║ │
+ └─────────────└──────────────┘┘ ╚══════════╝ │
+ └─────────────────────────────┘
+ ▲
+ └TASK 2
+ VIRTUAL ADDRESS SPACE
+
+
+6.3 Descriptor Tables
+
+A descriptor table is a memory-resident table either defined by program
+development tools in a static system or controlled by operating system
+software in systems that are reprogrammable. The descriptor table contents
+govern the interpretation of virtual addresses. Whenever the 80286 decodes
+a virtual address, translating a full 32-bit pointer into a corresponding
+24-bit physical address, it implicitly references one of these tables.
+
+Within a Protected Mode system, there are ordinarily several descriptor
+tables resident in memory. One of these is the global descriptor table
+(GDT); this table provides a complete description of the global address
+space. In addition, there may be one or more local descriptor tables
+(LDTs), each describing the local address space of one or more tasks.
+
+For each task in the system, a pair of descriptor tables──consisting of the
+GDT (shared by all tasks) and a particular LDT (private to the task or to a
+group of closely related tasks)──provides a complete description of that
+task's virtual address space. The protection mechanism described in Chapter
+7, "Protection," ensures that a task is granted access only to its own
+virtual address space. In the simplest of system configurations, tasks can
+reside entirely within the GDT without the use of local descriptor tables.
+This will simplify system software by only requiring maintenance of one
+table (the GDT) at the expense of no isolation between tasks. The point is:
+the 80286 memory management scheme is flexible enough to accommodate a
+variety of implementations and does not require use of all possible
+facilities when implementing a system.
+
+The descriptor tables consist of a sequence of 8-byte entries called
+descriptors. A descriptor table may contain from 1 to 8192 entries.
+
+Within a descriptor table, two main classes of descriptors are recognized
+by the 80286 architecture. The most important of these, from the standpoint
+of memory management, are called segment descriptors; these determine the
+set of segments that are included within a given address space. The other
+class are special-purpose control descriptors──such as call gates and task
+descriptors──to implement protection (described in succeeding chapters) and
+special system data segments.
+
+Figure 6-3 shows the format of a segment descriptor. Note that it provides
+information about the physical-memory base address and size of a segment, as
+well as certain access information. If a particular segment is to be
+included within a virtual address space, then a segment descriptor that
+describes that segment must be included within the appropriate descriptor
+table. Thus, within the GDT, there are segment descriptors for all of the
+segments that comprise a system's global address space. Similarly, within a
+task's LDT, there must be a descriptor for each of the segments that are to
+be included in that task's local address space.
+
+Each local descriptor table is itself a special system segment,
+recognizable as such by the 80286 architecture and described by a specific
+type of segment descriptor (see figure 6-4). Because there is only a single
+GDT segment, it is not defined by a segment descriptor. Its base and size
+information is maintained in a dedicated register, GDTR, as described below
+(section 6.6.2).
+
+Similarly, there is another dedicated register within the 80286, LDTR, that
+records the base and size of the current LDT segment (i.e., the LDT
+associated with the currently executing task). The LDTR register state,
+however, is volatile: its contents are automatically altered whenever a
+task switch is made from one task to another. An alternate specification
+independent of changeable register contents must therefore exist for each
+LDT in the system. This independent specification is accomplished by means
+of special system segment descriptors known as descriptor table descriptors
+or LDT descriptors.
+
+Figure 6-4 shows the format of a descriptor table descriptor. (Note that it
+is distinguished from an ordinary segment descriptor by the contents of
+certain bits in the access byte.) This special type of descriptor is used to
+specify the physical base address and size of a local descriptor table that
+defines the virtual address space and address mapping for an individual user
+or task (figure 6-5).
+
+Each LDT segment in a system must lie within that system's global address
+space. Thus, all of the descriptor table descriptors must be included among
+the entries in the global descriptor table (the GDT) of a system. In fact,
+these special descriptors may appear only in the GDT. Reference to an LDT
+descriptor within an LDT will cause a protection violation. Even though
+they are in the global address space available to all tasks, the descriptor
+table descriptors are protected from corruption within the GDT since they
+are special system segments and can only be accessed for loading into the
+LDTR register.
+
+
+Figure 6-3. Segment Descriptors (S=1)
+
+ 7 0 7 0
+ ╔═══════════════════════════════╤════════════════════════════════╗
+ +7║ INTEL RESERVED
+ Must be set to 0 for compatibility with iAPX 386 MUST BE 0 ║+6
+ACCESS ╟───┬───────┬───┬───────────┬───┬────────────────────────────────╢
+ +5║ P │ DPL │S=1│ TYPE │ A │ BASE{23-16} ║+4
+RIGHTS ╟───┴───┴───┴───┴───┴───┴───┴───┴────────────────────────────────╢
+ +3║ BASE{15-0} ║+2
+BYTES ╟────────────────────────────────────────────────────────────────╢
+ +1║ LIMIT{15-0} ║ 0
+ ╚═══════════════════════════════╧════════════════════════════════╝
+ 15 8 7 0
+
+ ACCESS RIGHTS BYTES:
+ P = PRESENT
+ DPL = DESCRIPTOR PRIVILEGE LEVEL
+ S = SEGMENT DESCRIPTOR
+ TYPE = SEGMENT TYPE AND ACCESS INFORMATION
+ (see Figure 6-7)
+ A = ACCESSED
+
+
+Figure 6-4. Special Purpose Descriptors or System Segment Descriptors (S=1)
+
+ 7 0 7 0
+ ╔═══════════════════════════════╤════════════════════════════════╗
+ +7║ INTEL RESERVED
+Must be set to 0 for compatibility with iAPX 386 MUST BE 0 ║+6
+ ╟───┬───────┬───┬───────────────┬────────────────────────────────╢
+ +5║ P │ DPL │S=1│ TYPE │ BASE{23-16} ║+4
+ ╟───┴───┴───┴───┴───┴───┴───┴───┴────────────────────────────────╢
+ +3║ BASE{15-0} ║+2
+ ║───────────────────────────────┴────────────────────────────────║
+ +1║ LIMIT{15-0} ║ 0
+ ╚═══════════════════════════════╧════════════════════════════════╝
+ 15 8 7 0
+
+ ACCESS RIGHTS BYTES:
+ P = PRESENT
+ DPL = DESCRIPTOR PRIVILEGE LEVEL
+ S = SEGMENT DESCRIPTOR
+ TYPE = SEGMENT TYPE AND ACCESS INFORMATION
+ (Includes control and system segments)
+
+ 0 = INVALID DESCRIPTOR
+ 1 = AVAILABLE TASK STATE SEGMENT
+ 2 = LDT DESCRIPTOR
+ 3 = BUSY TASK STATE SEGMENT
+ 4-7 = CONTROL DESCRIPTOR (see Chapter 7)
+ 8 = INVALID DESCRIPTOR (reserved by Intel)
+ 9-F = RESERVED BY INTEL
+
+Figure 6-5. LDT Descriptors
+
+ • •
+ • • ║ ║
+ ┌─►║ ║ ┌─►╠═══════════════╣
+ │ ≈ ≈ │ ║ ║
+• • │ ║ ║ │ ║ ONE ║
+║ ║ │ ╠═════════════════╣ │ ║ SEGMENT ║
+╠═════════════════╣ │ ║ RESERVED ZERO ║ │ ║ OF THE ║SEGMENT
+║ RESERVED ZERO ║ │ ╠════════╤════════╣┐ │ ║ TASKS ║LIMIT
+╠════════╤════════╣┐ │ ║ │BASE{23-16} │ ║ LOCAL ║
+║ │BASE{23-16} │ ╠════════╧════════╣├─┐ │ ║ (private) ║
+╠════════╧════════╣├─┐ │ ║ BASE{15-0} ║│ │ │ ║ ADDRESS ║
+║ BASE{15-0} ║│ │ │ ╠═════════════════╣┘ │ │ ║ SPACE ║
+╠═════════════════╣┘ │ │ ║ BASE{15-0} ╟──│─┘ ║ ║
+║ LIMIT{15-0} ╟──│─┘ ╠═════════════════╣ └───►╠═══════════════╣SEGMENT
+╠═════════════════╣ │ ║ ║ ║ ║BASE
+║ LDT ║ │ ║ ║ ║ ║
+• DESCRIPTION IN • │ ║ ║ ║ ║
+ THE GDT IN MEMORY │ ╠═════════════════╣ ║ ║
+ │ ≈ ≈ ║ ║
+ │ ║ ║ ║ ║
+ └───►╠═════════════════╣ ║ ║
+ ║ DESCRIPTOR ║ ║ SEGMENT ║
+ • TABLES IN RAM • • IN RAM •
+
+
+6.4 Virtual-to-Physical Address Translation
+
+The translation of a full 32-bit virtual address pointer into a real 24-bit
+physical address is shown by figure 6-6. When the segment's base address is
+determined as a result of the mapping process, the offset value is added to
+the result to obtain the physical address.
+
+The actual mapping is performed on the selector component of the virtual
+address. The 16-bit segment selector is mapped to a 24-bit segment base
+address via a segment descriptor maintained in one of the descriptor tables.
+
+The TI bit in the segment selector (see figure 6-1) determines which of two
+descriptor tables, either the GDT or the current LDT, is to be chosen for
+memory mapping. In either case, using the GDTR or LDTR register, the
+processor can readily determine the physical base address of the
+memory-resident table.
+
+The INDEX field in the segment selector specifies a particular descriptor
+entry within the chosen table. The processor simply multiplies this index
+value by 8 (the length of a descriptor), and adds the result to the base
+address of the descriptor table in order to access the appropriate segment
+descriptor in the table.
+
+Finally, the segment descriptor contains the physical base address of the
+target segment, as well as size (limit) and access information. The
+processor sums the 24-bit segment base and the specified 16-bit offset to
+generate the resulting 24-bit physical address.
+
+
+Figure 6-6. Virtual-to-Physical Address Translation
+
+ ╔═════════════════════════════════════════════════════╗
+ ║ VIRTUAL ADDRESS ║
+ ║ ╔════════════════════════╤════════════════════════╗ ║ • TARGET •
+ ║ ║ SELECTOR │ OFFSET ║ ║ ║ SEGMENT ║
+ ║ ╚════╤═══════════╤═══════╧═════╤══════════════════╝ ║ ║ ║
+ ╚══════│═══════════│═════════════│════════════════════╝ ║ ║
+ │ │ TI ▼ ║ ║
+ │ │ ╔═╗ ╟─────────╢
+ │ ▼ ║+╟───────────────────────►║ DATUM ║
+ │ DESCRIPTOR ╚═╝ PHYSICAL ADDRESS ╟─────────╢
+ │ • TABLE • ▲ ║ ║
+ │ ╠════════════╣ │ ║ ║
+ │ ≈ ≈ │ ║ ║
+ │ ╟────────────╢ │ ║ ║
+ │ ║ SEGMENT ║ │ SEGMENT BASE ║ ║
+ ▼ ║ DESCRIPTOR ╟──────┴────────────────────────►╠═════════╣
+ ─ ─ ─ ─ ─ ─ ╫────────────╢ ║ ║
+ INDEX ▲ ≈ ≈ • •
+ ─ ─ ─ ┴ ─ ─ ╫════════════╣
+ • •
+
+
+6.5 Segments and Segment Descriptors
+
+Segments are the basic units of 80286 memory management. In contrast to
+schemes based on fixed-size pages, segmentation allows for a very efficient
+implementation of software: variable-length segments can be tailored to the
+exact requirements of an application. Segmentation, moreover, is consistent
+with the way a programmer naturally deals with his virtual address space:
+programmers are encouraged to divide code and data into clearly defined
+modules and structures which are manipulated as consistent entities. This
+reduces (minimizes) the potential for virtual memory thrashing.
+Segmentation also eliminates the restrictions on data structures that span a
+page (e.g., a word that crosses page boundaries).
+
+Each segment within an 80286 system is defined by an associated segment
+descriptor, which may appear in one or more descriptor tables. Its inclusion
+within a descriptor table represents the presence of its associated segment
+within the virtual address space defined by that table. Conversely, its
+ommission from a descriptor table means that the segment is absent from the
+corresponding address space.
+
+As shown previously in figure 6-3, an 8-byte segment descriptor encodes the
+following information about a particular segment:
+
+ ■ Size. This 16-bit field, comprising bytes 0 and 1 of a segment
+ descriptor, specifies an unsigned integer as the size, in bytes (from 1
+ byte to 64K bytes), of the segment.
+
+ Unlike segments in the 8086 (or the 80286 in Real Address Mode)──which
+ are never explicitly limited to less than a full 64K bytes──Protected
+ Mode segments are always assigned a specific size value. In conjunction
+ with the protection features described in Chapter 7, this assigned
+ size allows the enforcement of a very desirable and natural rule:
+ inadvertent accesses to locations beyond a segment's actual boundaries
+ are prohibited.
+
+ ■ Base. This 24-bit field, comprising bytes 2 through 4 of a segment
+ descriptor, specifies the physical base address of the segment; it thus
+ defines the actual location of the segment within the 16-megabyte real
+ memory space. The base may be any byte address within the 16-megabyte
+ real memory space.
+
+ ■ Access. This 8-bit field comprises byte 5 of a segment descriptor.
+ This access byte specifies a variety of additional information about a
+ segment, particularly in regard to the protection features of the
+ 80286. For example, code segments are distinguished from data
+ segments; and certain special access restrictions (such as Execute-Only
+ or Read-Only) may be defined for segments of each type. Access byte
+ values of 00H or 80H will always denote "invalid."
+
+Figure 6-7 shows the access byte format for both code and data segment
+descriptors. Detailed discussion of the protection related fields within an
+access byte (Conforming, Execute-Only, Descriptor Privilege Level, Expand
+Down, and Write-Permitted), and their use in implementing protection
+policies, is deferred to Chapter 7. The two fields Accessed and Present are
+used for virtual memory implementations.
+
+
+Figure 6-7. Segment Descriptor Access Bytes
+
+ CODE SEGMENT TYPE
+ MSB ┌─────┴─────┐LSB
+ ╔═══╤═════╤═══╤═══╤═══╤═══╤═══╗
+ ║ P │ DPL │ 1 │ 1 │ C │ R │ A ║
+ ╚═══╧═════╧═══╧═══╧═══╧═══╧═══╝
+ ▲ └──┬──┘ ▲ ▲ ▲ ▲ ▲
+ PRESENT (1 = yes)────────────────────────┘ ▲ │ │ │ │ │
+ DESCRIPTOR PRIVILEGE LEVEL────────────────────┘ │ │ │ │ │
+ (indicates segment descriptor)─────────────────────┘ │ │ │ │
+ EXECUTABLE (1 = yes for code)──────────────────────────┘ │ │ │
+ CONFORMING (1 = yes)───────────────────────────────────────┘ │ │
+ READABLE (1 = yes)─────────────────────────────────────────────┘ │
+ ACCESSED (1 = yes)─────────────────────────────────────────────────┘
+
+ DATA OR STACK SEGMENT
+ MSB LSB
+ ╔═══╤═════╤═══╤═══╤════╤═══╤═══╗
+ ║ P │ DPL │ 1 │ 0 │ ED │ W │ A ║
+ ╚═══╧═════╧═══╧═══╧════╧═══╧═══╝
+ ▲ ▲ ▲ ▲ ▲ ▲ ▲
+ PRESENT (1 = yes)───────────────────────┘ │ │ │ │ │ │
+ DESCRIPTOR PRIVILEGE LEVEL───────────────────┘ │ │ │ │ │
+ (indicates segment descriptor)────────────────────┘ │ │ │ │
+ EXECUTABLE (0 = no for data) ────────────────────────┘ │ │ │
+ CONFORMING (1 = yes)──────────────────────────────────────┘ │ │
+ WRITEABLE (1 = yes)────────────────────────────────────────────┘ │
+ ACCESSED (1 = yes)─────────────────────────────────────────────────┘
+
+
+6.6 Memory Management Registers
+
+The Protected Virtual Address Mode features of the 80286 operate at high
+performance due to extensions to the basic 8086 register set. Figure 6-8
+illustrates that portion of the extended register structure that pertains to
+memory management. (For a complete summary of all Protected Mode registers,
+refer to section 10.1).
+
+
+6.6.1 Segment Address Translation Registers
+
+Figure 6-8 shows the segment registers CS, DS, ES, and SS. In contrast to
+their usual representation, however, these registers are now depicted as
+64-bit registers, each with "visible" and "hidden" components.
+
+The visible portions of these segment address translation registers are
+manipulated by programs exactly as if they were simply the 16-bit segment
+registers of Real Address Mode. By loading a segment selector into one of
+these registers, the program makes the associated segment one of its four
+currently addressable segments.
+
+The operations that load these registers──or, more exactly, those that load
+the visible portion of these registers──are normal program instructions.
+These instructions may be divided into two categories:
+
+ 1. Direct segment-register load instructions. These instructions (such
+ as LDS, LES, MOV, POP, etc.) can explicitly reference the SS, DS, or
+ ES segment registers as the destination operand.
+
+ 2. Implied segment-register load instructions. These instructions (such
+ as intersegment CALL and JMP) implicitly reference the CS code segment
+ register; as a result of these operations, the contents of CS are
+ altered.
+
+Using these instructions, a program loads the visible part of the segment
+register with a 16-bit selector (i.e., the high-order word of a virtual
+address pointer). Whenever this is done, the processor automatically uses
+the selector to reference the appropriate descriptor and loads the 48-bit
+hidden descriptor cache for that segment register.
+
+The correspondence between selectors and descriptors has already been
+described. Remember that the selector's TI bit indicates one of the two
+descriptor tables, either the LDT or the GDT. Within the indicated table, a
+particular entry is chosen by the selector's 13-bit INDEX field. This
+index, scaled by a factor of 8, represents the relative displacement of the
+chosen table entry (a descriptor).
+
+Thus, so long as a particular selector value is valid (i.e., it points to a
+valid segment descriptor within the bounds of the descriptor table), it can
+be readily associated with an 8-byte descriptor. When a selector value is
+loaded into the visible part of a segment register, the 80286 automatically
+loads 6 bytes of the associated descriptor into the hidden part of the
+register. These 6 bytes, therefore, contain the size, base, and access type
+of the selected segment. Figure 6-9 illustrates this transparent process of
+descriptor loading.
+
+In effect, the hidden descriptor fields of the segment registers function
+as the memory management cache of the 80286. All the information required to
+address the current working set of segments──that is, the base address,
+size, and access rights of the currently addressable segments──is stored in
+this memory cache. Unlike the probabilistic caches of other architectures,
+however, the 80286 cache is completely deterministic: the caching of
+descriptors is explicitly controlled by the program.
+
+Most memory references do not require the translation of a full 32-bit
+virtual address, or long pointer. Operands that are located within one of
+the currently addressable segments, as determined by the four segment
+registers, can be referenced very efficiently by means of a short pointer,
+which is simply a 16-bit offset.
+
+In fact, most 80286 instructions reference memory locations in precisely
+this way, specifying only a 16-bit offset with respect to one of the
+currently addressable segments. The choice of segments (CS, DS, ES, or SS)
+is either implicit within the instruction itself, or explicitly specified
+by means of a segment-override prefix (as described in Chapter 2).
+
+Thus, in most cases, virtual-to-physical address translation is actually
+performed in two separate steps. First, when a program loads a new value
+into a segment register, the processor immediately performs a mapping
+operation; the physical base address of the selected segment (as well as
+certain additional information) is automatically loaded into the hidden
+portion of the register. The internal cache registers (virtual address
+translation hardware) are therefore dynamically shared among the 16K
+different segments potentially addressable within the user's virtual address
+space. No software overhead (either system or application) is required to
+perform this operation.
+
+Subsequently, as the program utilizes a short pointer to reference a
+location within a segment, the processor generates a 24-bit physical address
+simply by adding the specified offset value to the previously cached segment
+base address. By encouraging the use of short pointers in this way, rather
+than requiring a full 32-bit virtual address for every memory reference, the
+80286 provides a very efficient on-chip mechanism for address translation,
+with minimum overhead for references to memory-based tables or the need for
+external address-translation devices.
+
+
+Figure 6-8. Memory Management Registers
+
+ SEGMENT ADDRESS TRANSLATION REGISTERS
+
+ 16-BIT 48-BIT HIDDEN DESCRIPTOR CACHE
+ SELECTOR (PROGRAM INVISIBLE──LOADED BY CPU)
+ ╔═════════╤══════╤══════════════════╤══════════════╗
+CS║ │ │ │ ║CODE SEGMENT REGISTER
+ ╟─────────┼──────┼──────────────────┼──────────────╢
+DS║ │ │ │ ║DATA SEGMENT REGISTER
+ ╟─────────┼──────┼──────────────────┼──────────────╢
+ES║ │ │ │ ║EXTRA SEGMENT REGISTER
+ ╟─────────┼──────┼──────────────────┼──────────────╢
+SS║ │ │ │ ║STACK SEGMENT REGISTER
+ ╚═════════╧══════╧══════════════════╧══════════════╝
+ 63 48 47 40 39 16 15 0
+ ACCESS SEGMENT BASE SEGMENT
+ RIGHTS ADDRESS SIZE
+
+
+ SYSTEM ADDRESS REGISTERS
+
+ 40-BIT EXPLICIT REGISTER
+ ╔═════════════════╤══════════╗
+ GDTR ║ ║GLOBAL DESCRIPTOR TABLE REGISTER
+ ╟─────────────────┼──────────╢
+ IDTR ║ ║INTERRUPT DESCRIPTOR TABLE REGISTER
+ ╚═════════════════╧══════════╝
+ 39 16 15 0
+ BASE LIMIT
+
+
+ 16-BIT
+ VISIBLE 40-BIT HIDDEN
+ SELECTOR DESCRIPTOR CACHE
+ ╔══════════╤═════════════════╤══════════╗
+LDTR║ │ ║LOCAL DESCRIPTOR TABLE REGISTER
+ ╚══════════╧═════════════════╧══════════╝
+ 55 40 39 16 15 0
+ BASE LIMIT
+
+
+Figure 6-9. Descriptor Loading
+
+ ┌── ── ── ── ── ── ── ── ── ── ── ─┐
+ │ CPU │
+ APPLICATION DESCRIPTOR • •
+ │ VISIBLE CACHE │ ║ SYSTEM ║
+ ┌────┴─────┐ ┌────┴─────┐ ║ MEMORY ║
+ │ SEGMENT SEGMENT │ ║ ║
+ REGISTER DESCRIPTOR ║ ║
+ │ ╔══════════╗ ╔══════════╗ │ ║ ║
+ ║ SELECTOR ║ ║ TYPE ║ ║ ║
+ │ ╚═════╤════╝ ╟──────────╢ │ ║ ║
+ ║ BASE ║ ║ ║
+ │ │ ╟──────────╢ │ ≈ ≈
+ ║ LIMIT ║ ║ ║
+ │ │ ╚══════════╝ │ ║ ║
+ ▲ ║ ║
+ │ │ │TRANSPARENT│ ║ ║
+ │DESCRIPTOR ╠═══════════════╣─┐
+ │ │ │LOADING │ ║ ║ │
+ └───────────────╫───────────────╢ │
+ │ │ │ ║ ║ ├─DESCRIPTOR
+ ───────────────►╟───────────────╢ │ TABLE
+ │ └── ── ── ── ── ► ▲ INDEX │ ║ ║ │
+ ┌ ── ── ── ── ── ─┴ ── ── ── ►╠═══════════════╣─┘
+ │ │ ║ ║
+ ╔═════╧════╗ ║ ║
+ │ ║DESCRIPTOR║ │ ║ ║
+ ║TABLE BASE║ ║ ║
+ │ ╚══════════╝ │ • •
+ └── ── ── ── ── ── ── ── ── ── ── ──┘
+
+
+6.6.2 System Address Registers
+
+The Global Descriptor Table Register (GDTR) is a dedicated 40-bit (5 byte)
+register used to record the base and size of a system's global descriptor
+table (GDT). Thus, two of these bytes define the size of the GDT, and three
+bytes define its base address.
+
+In figure 6-8, the contents of the GDTR are referred to as a "hidden
+descriptor." The term "descriptor" here emphasizes the analogy with the
+segment descriptors ordinarily found in descriptor tables. Just as these
+descriptors specify the base and size (limit) of ordinary segments, the
+GDTR register specifies these same parameters for that segment of memory
+serving as the system GDT. The limit prevents accesses to descriptors in the
+GDT from accessing beyond the end of the GDT and thus provides address space
+isolation at the system level as well as at the task level.
+
+The register contents are "hidden" only in the sense that they are not
+accessible by means of ordinary instructions. Instead, the dedicated
+protected instructions LGDT and SGDT are reserved for loading and storing,
+respectively, the contents of the GDTR at Protected Mode initialization
+(refer to section 10.2 for details). Subsequent alteration of the GDT base
+and size values is not recommended but is a system option at the most
+privileged level of software (see section 7.3 for a discussion of privilege
+levels).
+
+The Local Descriptor Table Register (LDTR) is a dedicated 40-bit register
+that contains, at any given moment, the base and size of the local
+descriptor table (LDT) associated with the currently executing task. Unlike
+GDTR, the LDTR register contains both a "visible" and a "hidden" component.
+Only the visible component is accessible, while the hidden component remains
+truly inaccessible even to dedicated instructions.
+
+The visible component of the LDTR is a 16-bit "selector" field. The format
+of these 16 bits corresponds exactly to that of a segment selector in a
+virtual address pointer. Thus, it contains a 13-bit INDEX field, a 1-bit TI
+field, and a 2-bit RPL field. The TI "table indicator" bit must be zero,
+indicating a reference to the GDT (i.e., to global address space). The INDEX
+field consequently provides an index to a particular entry within the GDT.
+This entry, in turn, must be an LDT descriptor (or descriptor table
+descriptor), as defined in the previous section. In this way, the visible
+"selector" field of the LDTR, by selecting an LDT descriptor, uniquely
+designates a particular LDT in the system.
+
+The dedicated, protected instructions LLDT and SLDT are reserved for
+loading and storing, respectively, the visible selector component of the
+LDTR register (refer to section 10.2 for details). Whenever a new value is
+loaded into the visible "selector" portion of LDTR, an LDT descriptor will
+have been uniquely chosen (assuming, of course, that the "selector" value is
+valid). In this case, the 80286 automatically loads the hidden "descriptor"
+portion of LDTR with five bytes from the chosen LDT descriptor. Thus, size
+and base information about a particular LDT, as recorded in a
+memory-resident global descriptor table entry, is cached in the LDTR
+register.
+
+New values may be loaded into the visible portion of the LDTR (and, thus,
+into the hidden portion as well) in either of two ways. The LLDT
+instruction, during system initialization, is used explicitly to set an
+initial value for the LDTR register; in this way, a local address space is
+provided for the first task in a multitasking environment. After system
+startup, explicit changes are not required since operations that
+automatically invoke a task switch (described in section 8.4) appropriately
+manage the LDTR.
+
+At all times, the LDTR register thus records the physical base address (and
+size) of the current task's LDT; the descriptor table required for mapping
+the current local address space, therefore, is immediately accessible to the
+processor. Moreover, since GDTR always maintains the base address of the
+GDT, the table that maps the global address space is similarly accessible.
+The two system address registers, GDTR and LDTR, act as a special processor
+cache, maintaining current information about the two descriptor tables
+required, at any given time, for addressing the entire current virtual
+address space.
+
+
+Chapter 7 Protection
+
+───────────────────────────────────────────────────────────────────────────
+
+7.1 Introduction
+
+In most microprocessor based products, the product's availability, quality,
+and reliability are determined by the software it contains. Software is
+often the key to a product's success. Protection is a tool used to shorten
+software development time, and improve software quality and reliability.
+
+Program testing is an important step in developing software. A system with
+protection will detect software errors more quickly and accurately than a
+system without protection. Eliminating errors via protection reduces the
+development time for a product.
+
+Testing software is difficult. Many errors occur only under complex
+circumstances which are difficult to anticipate. The result is that products
+are shipped with undetected errors. When such errors occur, products appear
+unreliable. The impact of a software error is multiplied if it introduces
+errors in other bug-free programs. Thus, the total system reliability
+reduces to that of the least reliable program running at any given time.
+
+Protection improves the reliability of an entire system by preventing
+software errors in one program from affecting other programs. Protection can
+keep the system running even when some user program attempts an invalid or
+prohibited operation.
+
+Hardware protection performs run-time checks in parallel with the execution
+of the program. But, hardware protection has traditionally resulted in a
+design that is more expensive and slower than a system without protection.
+However, the 80286 provides hardware-enforced protection without the
+performance or cost penalties normally associated with protection.
+
+The protected mode 80286 implements extensive protection by integrating
+these functions on-chip. The 80286 protection is more comprehensive and
+flexible than comparable solutions. It can locate and isolate a large number
+of program errors and prevent the propagation of such errors to other tasks
+or programs. The protection of the total system detects and isolates bugs
+both during development and installed usage. Chapter 9 discusses exceptions
+in more detail.
+
+The remaining sections of this chapter explain the protection model
+implemented in the 80286.
+
+
+7.1.1 Types of Protection
+
+Protection in the 80286 has three basic aspects:
+
+ 1. Isolation of system software from user applications.
+ 2. Isolation of users from each other (Inter-task protection).
+ 3. Data-type checking.
+
+The 80286 provides a four-level, ringed-type, increasingly-privileged
+protection mechanism to isolate applications software from various layers of
+system software. This is a major improvement and extension over the simpler
+two-level user/supervisor mechanism found in many systems. Software modules
+in a supervisor level are protected from modules in the application level
+and from software in less privileged supervisor levels.
+
+Restricting the addressability of a software module enables an operating
+system to control system resources and priorities. This is especially
+important in an environment that supports multiple concurrent users.
+Multi-user, multi-tasking, and distributed processing systems require this
+complete control of system resources for efficient, reliable operation.
+
+The second aspect of protection is isolating users from each other. Without
+such isolation an error in one user program could affect the operation of
+another error-free user program. Such subtle interactions are difficult to
+diagnose and repair. The reliability of applications programs is greatly
+enhanced by such isolation of users.
+
+Within a system or application level program, the 80286 will ensure that
+all code and data segments are properly used (e.g., data cannot be executed,
+programs cannot be modified, and offset must be within defined limits,
+etc.). Such checks are performed on every memory access to provide full
+run-time error checking.
+
+
+7.1.2 Protection Implementation
+
+The protection hardware of the 80286 establishes constraints on memory and
+instruction usage. The number of possible interactions between instructions,
+memory, and I/O devices is practically unlimited. Out of this very large
+field the protection mechanism limits interactions to a controlled,
+understandable subset. Within this subset fall the list of "correct"
+operations. Any operation that does not fall into this subset is not allowed
+by the protection mechanism and is signalled as a protection violation.
+
+To understand protection on the 80286, you must begin with its basic parts:
+segments and tasks. 80286 segments are the smallest region of memory which
+have unique protection attributes. Modular programming automatically
+produces separate regions of memory (segments) whose contents are treated as
+a whole. Segments reflect the natural construction of a program, e.g., code
+for module A, data for module A, stack for the task, etc. All parts of the
+segment are treated in the same way by the 80286. Logically separate regions
+of memory should be in separate segments.
+
+The memory segmentation model (see figure 7-1) of the 80286 was designed to
+optimally execute code for software composed of independent modules. Modular
+programs are easier to construct and maintain. Compared to monolithic
+software systems, modular software systems have enhanced capabilities, and
+are typically easier to develop and test for proper operation.
+
+Each segment in the system is defined by a memory-resident descriptor. The
+protection hardware prevents accesses outside the data areas and attempts to
+modify instructions, etc., as defined by the descriptors. Segmentation on
+the 80286 allows protection hardware to be integrated into the CPU for full
+data access control without any performance impact.
+
+The segmented memory architecture of the 80286 provides unique capabilities
+for regulating the transfer of control between programs.
+
+Programs are given direct but controlled access to other procedures and
+modules. This capability is the heart of isolating application and system
+programs. Since this access is provided and controlled directly by the 80286
+hardware, there is no performance penalty. A system designer can take
+advantage of the 80286 access control to design high-performance modular
+systems with a high degree of confidence in the integrity of the system.
+
+Access control between programs and the operating system is implemented via
+address space separation and a privilege mechanism. The address space
+control separates applications programs from each other while the privilege
+mechanism isolates system software from applications software. The
+privilege mechanism grants different capabilities to programs to access
+code, data, and I/O resources based on the associated protection level.
+Trusted software that controls the whole system is typically placed at the
+most privileged level. Ordinary application software does not have to deal
+with these control mechanisms. They come into play only when there is a
+transfer of control between tasks, or if the Operating System routines have
+to be invoked.
+
+The protection features of multiple privilege levels extend to ensuring
+reliable I/O control. However, for a system designer to enable only one
+specific level to do I/O would excessively constrain subsequent extensions
+or application development. Instead, the 80286 permits each task to be
+assigned a separate minimum level where I/O is allowed. I/O privilege is
+discussed in section 10.3.
+
+An important distinction exists between tasks and programs. Programs (e.g.,
+instructions in code segments) are static and consist of a fixed set of code
+and data segments each with an associated privilege level. The privilege
+assigned to a program determines what the program may do when executed by a
+task. Privilege is assigned to a program when the system is built or when
+the program is loaded.
+
+Tasks are dynamic; they execute one or more programs. Task privilege
+changes with time according to the privilege level of the program being
+executed. Each task has a unique set of attributes that define it, e.g.,
+address space, register values, stack, data, etc. A task may execute a
+program if that program appears in the task's address space. The rules of
+protection control determine when a program may be executed by a task, and
+once executed, determine what the program may do.
+
+
+Figure 7-1. Addressing Segments of a Module within a Task
+
+ ┌─ ── ─┐
+ ╔══════╗
+ ║ CODE ║
+ ╟──────╢ MODULE A
+ ║ DATA ║
+ ╚══════╝
+ CPU │ │
+ ┌───────────┐ ╔══════╗
+ │ ╔═══════╗ │ ║ CODE ║
+ │ ║ CODE ╟─┼─────────────────────────►╟──────╢ MODULE B
+ │ ╟───────╢ │ ║ DATA ║
+ │ ║ DATA ╟─┼─────────────────────────►╚══════╝
+ │ ╟───────╢ │ │ │
+ │ ║ STACK ╟─┼───────────────┐ ╔══════╗
+ │ ╟───────╢ │ │ ║ ║ TASK STACK
+ │ ║ EXTRA ╟─┼───────────┐ └─────────►╚══════╝
+ │ ╚═══════╝ │ │ │ │
+ │ SEGMENT │ │ ╔══════╗ TASK
+ │ REGISTERS │ │ ║ ║ DATA
+ └───────────┘ └─────────────►╚══════╝ BLOCK 1
+ │ │
+ ╔══════╗ TASK
+ ║ ║ DATA
+ ╚══════╝ BLOCK 2
+ └─ ── ─┘
+ MEMORY
+
+
+7.2 Memory Management and Protection
+
+The protection hardware of the 80286 is related to the memory management
+hardware. Since protection attributes are assigned to segments, they are
+stored along with the memory management information in the segment
+descriptor. The protection information is specified when the segment is
+created. In addition to privilege levels, the descriptor defines the segment
+type (e.g., Code segment, Data segment, etc.). Descriptors may be created
+either by program development tools or by a loader in a dynamically loaded
+reprogrammable environment.
+
+The protection control information consists of a segment type, its
+privilege level, and size. These are fields in the access byte of the
+segment descriptor (see figure 7-2). This information is saved on-chip in
+the programmer invisible section of the segment register for fast access
+during execution. These entries are changed only when a segment register is
+loaded. The protection data is used at two times: upon loading a segment
+register and upon each reference to the selected segment.
+
+The hardware performs several checks while loading a segment register.
+These checks enforce the protection rules before any memory reference is
+generated. The hardware verifies that the selected segment is valid (is
+identified by a descriptor, is in memory, and is accessible from the
+privilege level in which the program is executing) and that the type is
+consistent with the target segment register. For example, you cannot load a
+read-only segment descriptor into SS because the stack must always be
+writable.
+
+Each reference into the segment defined by a segment register is checked by
+the hardware to verify that it is within the defined limits of the segment
+and is of the proper type. For example, a code segment or read-only data
+segment cannot be written. All these checks are made before the memory cycle
+is started; any violation will prevent that cycle from starting and cause
+an exception to occur. Since the checks are performed concurrently with
+address formation, there is no performance penalty.
+
+By controlling the access rights and privilege attributes of segments, the
+system designer can assure a program will not change its code or overwrite
+data belonging to another task. Such assurances are vital to maintaining
+system integrity in the face of error-prone programs.
+
+
+ Figure 7-2. Descriptor Cache Registers
+
+ ┌─ ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ─┐
+ PROGRAM VISIBLE │ PROGRAM INVISIBLE │
+
+ │ ACCESS │
+ SEGMENT SELECTORS RIGHTS SEGMENT BASE ADDRESS SEGMENT SIZE
+ ╔═════════════════╗ │ ╔══════╤══════════════════════╤══════════════╗ │
+ CS╟─────────────────╢ ╟──────┼──────────────────────┼──────────────╢
+ DS╟─────────────────╢ │ ╟──────┼──────────────────────┼──────────────╢ │
+ SS╟─────────────────╢ ╟──────┼──────────────────────┼──────────────╢
+ ╚═════════════════╝ │ ╚══════╧══════════════════════╧══════════════╝ │
+ 15 0 47 40 39 16 15 0
+ │ │
+ SEGMENT REGISTERS SEGMENT DESCRIPTOR CACHE REGISTERS
+ (loaded by program) │ (loaded by CPU) │
+ └─ ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ─┘
+
+
+7.2.1 Separation of Address Spaces
+
+As described in Chapter 6, each task can address up to a gigabyte
+(2^(14) - 2 segments of up to 65,536 bytes each) of virtual memory defined
+by the task's LDT (Local Descriptor Table) and the system GDT. Up to
+one-half gigabyte (2^(13) segments of up to 65,536 bytes each) of the task's
+address space is defined by the LDT and represents the task's private
+address space. The remaining virtual address space is defined by the GDT and
+is common to all tasks in the system.
+
+Each descriptor table is itself a special kind of segment recognized by the
+80286 architecture. These tables are defined by descriptors in the GDT
+(Global Descriptor Table). The CPU has a set of base and limit registers
+that point to the GDT and the LDT of the currently running task. The local
+descriptor table register is loaded by a task switch operation.
+
+An active task can only load selectors that reference segments defined by
+descriptors in either the GDT or its private LDT. Since a task cannot
+reference descriptors in other LDTs, and no descriptors in its LDT refer to
+data or code belonging to other tasks, it cannot gain access to another
+tasks' private code and data (see figure 7-3).
+
+Since the GDT contains information that is accessible by all users (e.g.,
+library routines, common data, Operating System services, etc.), the 80286
+uses privilege levels and special descriptor types to control access (see
+section 7.2.2). Privilege levels protect more trusted data and code (in GDT
+and LDT) from less trusted access (WITHIN a task), while the private virtual
+address spaces defined by unique LDTs provide protection BETWEEN tasks (see
+figure 7-4).
+
+
+Figure 7-3. 80286 Virtual Address Space
+
+ ╔═════════════════════════════════════╗
+╔═════════════════════════════════╗ ║ ╔═════════════════════════════════╗ ║
+║ ╔══════╗65535 ║ ║ ║ ╔══════╗65535 ║ ║
+║ ║ SEG. ║ ↑ ║ ║ ║ ║ SEG. ║ ↑ ║ ║
+║ ║ ║OFFSET║ ║ ║ ║ ║OFFSET║ ║
+║ 8191╔═════╗ ┌─►╚══════╝0 ↓ ║ ║ ║ 8191╔═════╗ ┌─►╚══════╝0 ↓ ║ ║
+║ ↑ ║ LDT ╟───┘ • ║ ║ ║ ↑ ║ LDT ╟───┘ • ║ ║
+║ ↓ ║ A ╟───┐ • ║ ║ ║ ↓ ║ B ╟───┐ • ║ ║
+║ 0╚═════╝ │ • ║ ║ ║ 0╚═════╝ │ • ║ ║
+║ │ ╔══════╗65535 ║ ║ ║ │ ╔══════╗65535 ║ ║
+║ │ ║ SEG. ║ ↑ ║ ║ ║ │ ║ SEG. ║ ↑ ║ ║
+║ │ ║ ║OFFSET║ ║ ║ │ ║ ║OFFSET║ ║
+║ └─►╚══════╝0 ↓ ║ ║ ║ └─►╚══════╝0 ↓ ║ ║
+╚═════════════════════════════════╝ ║ ╚═════════════════════════════════╝ ║
+ TASK A PRIVATE ADDRESS SPACE ║ TASK B PRIVATE ADDRESS SPACE ║
+ ║ ║
+╔═════════════════════════════════╗ ║ ╔═════════════════════════════════╗ ║
+║ ╔══════╗65535 ║ ║ ║ ╔══════╗65535 ║ ║
+║ ║ SEG. ║ ↑ ║ ║ ║ ║ SEG. ║ ↑ ║ ║
+║ ║ ║OFFSET║ ║ ║ ║ ║OFFSET║ ║
+║ 8191╔═════╗ ┌─►╚══════╝0 ↓ ║ ║ ║ 8191╔═════╗ ┌─►╚══════╝0 ↓ ║ ║
+║ ↑ ║ LDT ╟───┘ • ║ ║ ║ ↑ ║ GDT ╟───┘ • ║ ║
+║ ↓ ║ C ╟───┐ • ║ ║ ║ ↓ ║ ╟───┐ • ║ ║
+║ 0╚═════╝ │ • ║ ║ ║ 0╚═════╝ │ • ║ ║
+║ │ ╔══════╗65535 ║ ║ ║ │ ╔══════╗65535 ║ ║
+║ │ ║ SEG. ║ ↑ ║ ║ ║ │ ║ SEG. ║ ↑ ║ ║
+║ │ ║ ║OFFSET║ ║ ║ │ ║ ║OFFSET║ ║
+║ └─►╚══════╝0 ↓ ║ ║ ║ └─►╚══════╝0 ↓ ║ ║
+╚═════════════════════════════════╝ ║ ╚═════════════════════════════════╝ ║
+ TASK C PRIVATE ADDRESS SPACE ║ SHARED ADDRESS SPACE ║
+ ╚═════════════════════════════════════╝
+ TASK B ADDRESS SPACE
+
+Figure 7-4. Local and Global Descriptor Table Definitions
+
+ MEMORY
+ • •
+ ┌─┬───►╟───────────────╢─┐
+ │ ╟───────────────╢ │
+ CPU │ │ ╟───────────────╢ │
+ ╔═════════════════════╗ │ ║ ∙ ║ │
+ ║ ║ │ │ ║ ∙ ║ ├─ GDT
+ ║ 15 0 ║ │ ║ ∙ ║ │
+ ║ ╔═════════╗ ║ │ │ ╟───────────────╢ │
+ ║ 23 ║LDT LIMIT╟───╫─┘ ╟───────────────╢ │
+ ║ ╔═══╨─────────╢ ║ │ ╟───────────────╢ │
+ GDTR ║ ║ GDT BASE ╟───╫───────►╟───────────────╢─┘
+ ║ ╚═════════════╝ ║ ║ ║
+ ║ ║ ║ ║
+ ╟─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╢ ║ ║
+ ║ ║ ║ LDT{1} ║
+ ║ 15 0 ║ ┌─┬───►╟───────────────╢─┐
+ ║ ╔══════════╗ ║ │ ╟───────────────╢ │
+ ║ ║ LDT ║ ║ │ │ ╟───────────────╢ │
+ ║ ║ SELECTOR ║ ║ │ ║ ∙ ║ │
+ ║ ╚══════════╝ ║ │ │ ║ ∙ ║ ├─ CURRENT LDT
+ ║┌─ ── ── ── ── ── ──┐║ │ ║ ∙ ║ │
+ ║│ 15 0 │║ │ │ ╟───────────────╢ │
+ ║ ╔═════════╗ ║ │ ╟───────────────╢ │
+ ║│ 23 ║LDT LIMIT╟──┼╫─┘ │ ╟───────────────╢ │
+ ║ ╔═══╨─────────╢ ║ ┌────►╟───────────────╢─┘
+ LDTR ║│ ║ LDT BASE ╟──┼╟──┘ ║ ║
+ ║ ╚═════════════╝ ║ ║ ║
+ ║│ PROGRAM INVISIBLE │║ ║ ║
+ ║└─ ── ── ── ── ── ──┘║ ║ LDT{n} ║
+ ╚═════════════════════╝ ╟───────────────╢
+ ╟───────────────╢
+ ╟───────────────╢
+ ╟───────────────╢
+ ║ ∙ ║
+ ║ ∙ ║
+ ║ ∙ ║
+ ╟───────────────╢
+ ╟───────────────╢
+ ╟───────────────╢
+ ╟───────────────╢
+ ╟───────────────╢
+ • •
+
+
+7.2.2 LDT and GDT Access Checks
+
+All descriptor tables have a limit used by the protection hardware to
+ensure address space separation of tasks. Each task's LDT can be a different
+size as defined by its descriptor in the GDT. The GDT may also contain less
+than 8191 descriptors as defined by the GDT limit value. The descriptor
+table limit identifies the last valid byte of the last descriptor in that
+table. Since each descriptor is eight bytes long, the limit value is
+N * 8 - 1 for N descriptors.
+
+Any attempt by a program to load a segment register, local descriptor table
+register (LDTR), or task register (TR) with a selector that refers to a
+descriptor outside the corresponding limit causes an exception with an error
+code identifying the invalid selector used (see figure 7-5).
+
+Not all descriptor entries in the GDT or LDT need contain a valid
+descriptor. There can be holes, or "empty" descriptors, in the LDT and GDT.
+"Empty" descriptors allow dynamic allocation and deletion of segments or
+other system objects without changing the size of the GDT or LDT. Any
+descriptor with an access byte equal to zero is considered empty. Any
+attempt to load a segment register with a selector that refers to an empty
+descriptor will cause an exception with an error code identifying the
+invalid selection.
+
+
+Figure 7-5. Error Code Format (on the stack)
+
+ 15 3 2 1 0
+ ╔═══════════════════════════════════════════════════╤═══╤═══╤═══╗
+ ║ │ T │ I │ E ║
+ ║ INDEX │ I │ D │ X ║
+ ║ │ │ T │ T ║
+ ╚═══════════════════════════════════════════════════╧═╤═╧═╤═╧═╤═╝
+ └─────────────────────────┬─────────────────────────┘ │ │ │
+ ┌─────────────────────┘ │ │ │
+ │ ┌───────────────────────────────────────┘ │ │
+ │ │ ┌─────────────────────────────┘ │
+ ▼ ▼ ▼ ▼
+┌───────┐┌─────────┐┌───────────────┐┌─────────────────────────────────────┐
+│ Entry ││ 1 means ││ 1 means use ││ 1 means that an event external to │
+│ in ││ use ││ IDT and ││ the program caused the exception │
+│ IDT, ││ LDT ││ ignore ││ (i.e., external interrupt, single │
+│ GDT, ││ 0 means ││ bit 2. ││ step, processor extension error) │
+│ or ││ use ││ 0 means bit 2 ││ 0 means that an exception occurred │
+│ LDT ││ GDT ││ indicates ││ while processing the instruction │
+│ ││ ││ table usage ││ at CS:IP saved on the stack. │
+└───────┘└─────────┘└───────────────┘└─────────────────────────────────────┘
+
+
+7.2.3 Type Validation
+
+After checking that a selector reference is within the bounds of a
+descriptor table and refers to a non-empty descriptor, the type of segment
+defined by the descriptor is checked against the destination register. Since
+each segment register has predefined functions, each must refer to certain
+types of segments (see section 7.4.1). An attempt to load a segment
+register in violation of the protection rules causes an exception.
+
+The "null" selector is a special type of segment selector. It has an index
+field of all zeros and a table indicator of 0. The null selector appears to
+refer to GDT descriptor entry #0 (see GDT in figure 7-3). This selector
+value may be used as a place holder in the DS or ES segment registers; it
+may be loaded into them without causing an exception. However, any attempt
+to use the null segment registers to reference memory will cause an
+exception and prevent any memory cycle from occurring.
+
+
+7.3 Privilege Levels and Protection
+
+As explained in section 6.2, each task has its own separate virtual address
+space defined by its LDT. All tasks share a common address space defined by
+the GDT. The system software then has direct access to task data and can
+treat all pointers in the same way.
+
+Protection is required to prevent programs from improperly using code or
+data that belongs to the operating system. The four privilege levels of the
+80286 provide the isolation needed between the various layers of the system.
+The 80286 privilege levels are numbered from 0 to 3, where 0 is the most
+trusted level, 3 the least.
+
+Privilege level is a protection attribute assigned to all segments. It
+determines which procedures can access the segment. Like access rights and
+limit checks, privilege checks are automatically performed by the hardware,
+and thus protect both data and code segments.
+
+Privilege on the 80286 is hierarchical. Operating system code and data
+segments placed at the most privileged level (0) cannot be accessed directly
+by programs at other privilege levels. Programs at privilege level 0 may
+access data at all other levels. Programs at privilege levels 1-3 may only
+access data at the same or less trusted (numerically greater) privilege
+levels. Figure 7-6 illustrates the privilege level protection of code or
+data within tasks.
+
+In figure 7-6, programs can access data at the same or outer level, but not
+at inner levels. Code and data segments placed at level 1 cannot be accessed
+by programs executing at levels 2 or 3. Programs at privilege level 0 can
+access data at level 1 in the course of providing service to that level.
+80286 provides mechanisms for inter-level transfer of control when needed
+(see section 7.5).
+
+The four privilege levels of the 80286 are an extension of the typical
+two-level user/supervisor privilege mechanism. Like user mode, application
+programs in the outer level are not permitted direct access to data
+belonging to more privileged system services (supervisor mode). The 80286
+adds two more privilege levels to provide protection for different layers of
+system software (system services, I/O drivers, etc.).
+
+
+Figure 7-6. Code and Data Segments Assigned to a Privilege Level
+
+ TASK C
+ ┌───────────────────────────────────────────────────┐
+ │ ╔═══════════════════════════════════════════════╗ │
+ │ ║ APPLICATIONS ║ │
+ │ ║ ╔═══════════════════════════════════╗ ║ │
+ │ ║ ║ CUSTOM EXTENSIONS ║ ║ │
+ │ ║ ║ ╔═══════════════════════╗ ║ ║ │
+ │ ║ ║ ║ SYSTEM SERVICES ║ ║ ║ │
+ │ ║ ║ ║ ╔═══════════╗ ║ ║ ║ │
+ │ ║ ║ ║ ║ KERNAL ║ ║ ║ ║ │
+ ╞═╟─────╫─────╫─────╫─────┬─────╫─────╫─────╫─────╢═╡
+ │ ║ ║ ║ ║ │LEVEL║LEVEL║LEVEL║LEVEL║ │
+ │ ║ ║ ║ ║ │ 0 ║ 1 ║ 2 ║ 3 ║ │
+ │ ║ ║ ║ ╚═════╪═════╝ ║ ║ ║ │
+ │ ║ ║ ║ │ ║ ║ ║ │
+ │ ║ ║ ╚═══════════╪═══════════╝ ║ ║ │
+ │ ║ ║ │ ║ ║ │
+ │ ║ ╚═════════════════╪═════════════════╝ ║ │
+ │ ║ │ ║ │
+ TASK B┤ ╚═══════════════════════╧═══════════════════════╝ ├TASK A
+ └────────────────────────┘ └────────────────────────┘
+
+
+7.3.1 Example of Using Four Privilege Levels
+
+Two extra privilege levels allow development of more reliable, and flexible
+system software. This is achieved by dividing the system into small,
+independent units. Figure 7-6 shows an example of the usage of different
+protection levels. Here, the most privileged level is called the kernel.
+This software would provide basic, application-independent, CPU-oriented
+services to all tasks. Such services include memory management, task
+isolation, multitasking, inter-task communication, and I/O resource
+control. Since the kernel is only concerned with simple functions and cannot
+be affected by software at other privilege levels, it can be kept small,
+safe, and understandable.
+
+Privilege level one is designated system services. This software provides
+high-level functions like file access scheduling, character I/O, data
+communcations, and resource allocation policy which are commonly expected in
+all systems. Such software remains isolated from applications programs and
+relies on the services of the kernel, yet cannot affect the integrity of
+level 0.
+
+Privilege level 2 is the custom operating system extensions level. It
+allows standard system software to be customized. Such customizing can be
+kept isolated from errors in applications programs, yet cannot affect the
+basic integrity of the system software. Examples of customized software are
+the data base manager, logical file access services, etc.
+
+This is just one example of protection mechanism usage. Levels 1 and 2 may
+be used in many different ways. The usage (or non-usage) is up to the system
+designer.
+
+Programs at each privilege level are isolated from programs at outer
+layers, yet cannot affect programs in inner layers. Programs written for
+each privilege level can be smaller, easier to develop, and easier to
+maintain than a monolithic system where all system software can affect all
+other system software.
+
+
+7.3.2 Privilege Usage
+
+Privilege applies to tasks and three types of descriptors:
+
+ 1. Main memory segments
+
+ 2. Gates (control descriptors for state or task transitions, discussed
+ in sections 7.5.1, 8.3, 8.4 and 9.2)
+
+ 3. Task state segments (discussed in Chapter 8).
+
+Task privilege is a dynamic value. It is derived from the code segment
+currently being executed. Task privilege can change only when a control
+transfers to a different code segment.
+
+Descriptor privilege, including code segment privilege, is assigned when
+the descriptor (and any associated segment) is created. The system designer
+assigns privilege directly when the system is constructed with the system
+builder (see the 80286 Builder User's Guide) or indirectly via a loader.
+
+Each task operates at only one privilege level at any given moment: namely
+that of the code segment being executed. (The conforming segments discussed
+in section 11.2 permit some flexibility in this regard.) However, as figure
+7-6 indicates, the task may contain segments at one, two, three, or four
+levels, all of which are to be used at appropriate times. The privilege
+level of the task, then, changes under the carefully enforced rules for
+transfer of control from one code segment to another.
+
+The descriptor privilege attribute is stored in the access byte of a
+descriptor and is called the Descriptor Privilege Level (DPL). Task
+privilege is called the Current Privilege Level (CPL). The least significant
+two bits of the CS register specify the CPL.
+
+A few general rules of privilege can be stated before the detailed
+discussions of later sections. Data access is restricted to those data
+segments whose privilege level is the same as or less privileged
+(numerically greater) than the current privilege level (CPL). Direct code
+access, e.g., via call or jump, is restricted to code segments of equal
+privilege. A gate (section 7.5.1) is required for access to code at more
+privileged levels.
+
+
+7.4 Segment Descriptor
+
+Although the format of access control information, discussed below, is
+similar for both data and code segment descriptors, the rules for accessing
+data segments differ from those for transferring control to code segments.
+Data segments are meant to be accessible from many privilege levels, e.g.,
+from other programs at the same level or from deep within the operating
+system. The main restriction is that they cannot be accessed by less
+privileged code.
+
+Code segments, on the other hand, are meant to be executed at a single
+privilege level. Transfers of control that cross privilege boundaries are
+tightly restricted, requiring the use of gates. Control transfers within a
+privilege level can also use gates, but they are not required. Control
+transfers are discussed in section 7.5.
+
+Protection checks are automatically invoked at several points in selecting
+and using new segments. The process of addressing memory begins when the
+currently executing program attempts to load a selector into one of the
+segment registers. As discussed in Chapter 6, the selector has the form
+shown in figure 7-7.
+
+When a new selector is loaded into a segment register, the processor
+accesses the associated descriptor to perform the necessary loading and
+privilege checks.
+
+The protection mechanism verifies that the selector points to a valid
+descriptor type for the segment register (see section 7.4.1). After
+verifying the descriptor type, the CPU compares the privilege level of the
+task (CPL) to the privilege level in the descriptor (DPL) before loading
+the descriptor's information into the cache.
+
+The general format of the eight bits in the segment descriptor's access
+rights byte is shown in table 7-1.
+
+For example, the access rights byte for a data and code segment present in
+real memory but not yet accessed (at the same privilege level) is shown in
+figure 7-8.
+
+Whenever a segment descriptor is loaded into a segment register, the
+accessed bit in the descriptor table is set to 1. This bit is useful for
+determining the usage profile of the segment.
+
+
+Table 7-1. Segment Access Rights Byte Format
+
+
+Bit Name Description
+
+7 Present 1 means Present and addressable in real memory;
+ 0 means not present. See section 11.3.
+
+6,5 DPL 2-bit Descriptor Privilege Level, 0 to 3.
+
+4 Segment 1 means Segment descriptor; 0 means control
+ descriptor.
+
+ For Segment=1, the remaining bits have the following meanings:
+
+3 Executable 1 means code, 0 means data.
+
+2 C or ED If code, Conforming: 1 means yes, 0 no.
+ If data, Expand Down: 1 yes, 0 no──normal case.
+
+1 R or W If code, Readable: 1 means readable, 0 not.
+ If data, Writable: 1 means writable, 0 not.
+
+0 Accessed 1 if segment descriptor has been Accessed, 0 if not.
+
+
+───────────────────────────────────────────────────────────────────────────
+NOTE
+ When the Segment bit (bit 4) is 0, the descriptor is for a gate, a
+ task state segment, or a Local Descriptor Table, and the meanings of bits
+ 0 through 3 change. Control transfers and descriptors are discussed in
+ section 7.5.
+───────────────────────────────────────────────────────────────────────────
+
+Table 7-2. Allowed Segment Types in Segment Registers
+
+ Allowed Segment Types
+ ┌──────────────────────────┴─────────────────────────────┐
+Segment Register Read Only Read-Write Execute Only Execute-Read
+ Data Segment Data Segment Code Segment Code Segment
+ DS Yes Yes No Yes
+ ES Yes Yes No Yes
+ SS No Yes No No
+ CS No No Yes Yes
+
+───────────────────────────────────────────────────────────────────────────────────────────────────
+NOTE
+ The Intel reserved bytes in the segment descriptor must be set to 0 for
+ compatibility with the 80386.
+───────────────────────────────────────────────────────────────────────────────────────────────────
+
+Figure 7-7. Selector Fields
+
+ SELECTOR
+ ╔═══════════════════════════════════════════════════╤═══╤═══════╗
+ ║ INDEX │ T │ ║
+ ║ │ I │ RPL ║
+ ╚═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╝
+ 15 8 7 2 1 0
+
+╔══════╤══════════════════════╤════════════════════════════════════════════╗
+║ BITS │ NAME │ FUNCTION ║
+╟──────┼──────────────────────┼────────────────────────────────────────────╢
+║ 1-0 │ REQUESTED PRIVELEGE │ INDICATES SELECTOR PRIVILEGE LEVEL DESIRED ║
+║ │ LEVEL (RPL) │ ║
+╟──────┼──────────────────────┼────────────────────────────────────────────╢
+║ 2 │ TABLE INDICATOR (TI) │ TI = 0 USE GLOBAL DESCRIPTOR TABLE (GDT) ║
+║ │ │ TI = 1 USE LOCAL DESCRIPTORTABLE (LDT) ║
+╟──────┼──────────────────────┼────────────────────────────────────────────╢
+║ 15-3 │ INDEX │ SELECT DESCRIPTOR ENTRY IN TABLE ║
+╚══════╧══════════════════════╧════════════════════════════════════════════╝
+
+
+Figure 7-8. Access Byte Examples
+
+ READABLE CODE SEGMENT WRITABLE CODE SEGMENT
+
+ P DPL S E C R A P DPL S E ED W A
+ ╔══════════════════════════════╗ ╔═══════════════════════════════╗
+ ║ 1 01 1 1 0 1 0 ║ ║ 1 01 1 0 0 1 0 ║
+ ╚══════════════════════════════╝ ╚═══════════════════════════════╝
+ 7 0 7 0
+
+
+7.4.1 Data Accesses
+
+Data may be accessed in data segments or readable code segments. When DS or
+ES is loaded with a new selector, e.g., by an LDS, LES, or MOV to ES, SS, or
+DS instruction, the bits in the access byte are checked to verify legitimate
+descriptor type and access (see table 7-2). If any test fails, an error
+code is pushed onto the stack identifying the selector involved (see figure
+7-5 for the error code format).
+
+A privilege check is made when the segment register is loaded. In general,
+a data segment's DPL must be numerically greater than or equal to the CPL.
+The DPL of a descriptor loaded into the SS must equal the CPL. Conforming
+code segments are an exception to privilege checking rules (see section
+11.2).
+
+Once the segment descriptor and selector are loaded, the offset of
+subsequent accesses within the segment are checked against the limit given
+in the segment descriptor. Violating the segment size limit causes a General
+Protection exception with an error code of 0.
+
+A normal data segment is addressed with offset values ranging from 0 to the
+size of the segment. When the ED bit of the access rights byte in the
+segment descriptor is 0, the allowed range of offsets is 0000H to the limit.
+If limit is 0FFFFH, the data segment contains 65,536 bytes.
+
+Since stacks normally occupy different offset ranges (lower limit to
+0FFFFH) than data segments, the limit field of a segment descriptor can be
+interpreted in two ways. The Expand Down (ED) bit in the access byte allows
+offsets for stack segments to be greater than the limit field. When ED is
+1, the allowed range of offsets within the segment is limit + 1 to 0FFFFH.
+To allow a full stack segment, set ED to 1 and the limit to 0FFFFH. The ED
+bit of a data segment descriptor does not have to be set for use in SS
+(i.e., it will not cause an exception). Section 7.5.1.4 discusses stack
+segment usage in greater detail. An expand down (ED=1) segment can also be
+loaded into ES or DS.
+
+Limit and access checks are performed before any memory reference is
+started. For stack push instructions (PUSH, PUSHA, ENTER, CALL, INT), a
+possible limit violation is identified before any internal registers are
+updated. Therefore, these instructions are fully restartable after a stack
+size violation.
+
+
+7.4.2 Code Segment Access
+
+Code segments are accessed via CS for execution. Segments that are
+execute-only can ONLY be executed; they cannot be accessed via DS or ES, nor
+read via CS with a CS override prefix. If a segment is executable (bit 3=1
+in the access byte), access via DS or ES is possible only if it is also
+readable. Thus, any code segment that also contains data must be readable.
+(Refer to Chapter 2 for a discussion of segment override prefixes.)
+
+An execute-only segment preserves the privacy of the code against any
+attempt to read it; such an attempt causes a general protection fault with
+an error code of 0. A code segment cannot be loaded into SS and is never
+writable. Any attempted write will cause a general protection fault with an
+error code of 0.
+
+The limit field of a code segment descriptor identifies the last byte in
+the segment. Any offset greater than the limit value will cause a general
+protection fault. The prefetcher of the 80286 can never cause a code segment
+limit violation with an error code of 0. The program must actually attempt
+to execute an instruction beyond the end of the code segment to cause an
+exception.
+
+If a readable non-conforming code segment is to be loaded into DS or ES,
+the privilege level requirements are the same as those stated for data
+segments in 7.4.1.
+
+Code segments are subject to different privilege checks when executed. The
+normal privilege requirement for a jump or call to another code segment is
+that the current privilege level equal the descriptor privilege level of the
+new code segment. Jumps and calls within the current code segment
+automatically obey this rule.
+
+Return instructions may pass control to code segments at the same or less
+(numerically greater) privileged level. Code segments at more privileged
+levels may only be reached via a call through a call gate as described in
+section 7.5.
+
+An exception to this, previously stated, is the conforming code segment
+that allows the DPL of the requested code segment to be numerically less
+than (of greater privilege than) the CPL. Conforming code segments are
+discussed in section 11.2.
+
+
+7.4.3 Data Access Restriction by Privilege Level
+
+This section describes privilege verification when accessing either data
+segments (loading segment selectors into DS, ES, or SS) or readable code
+segments. Privilege verification when loading CS for transfer of control
+across privilege levels is described in the next section.
+
+Three basic kinds of privilege level indicators are used when determining
+accessibility to a segment for reading and writing. They are termed Current
+Privilege Level (CPL), Descriptor Privilege Level (DPL), and Requested
+Privilege Level (RPL). The CPL is simply the privilege level of the code
+segment that is executing (except if the current code segment is
+conforming). The CPL is stored as bits 0 and 1 of the CS and SS registers.
+Bits 0 and 1 of DS and ES are not related to CPL.
+
+DPL is the privilege level of the segment; it is stored in bits 5 and 6 of
+the access byte of a descriptor. For data access to data segments and
+non-conforming code segments, CPL must be numerically less than or equal to
+DPL (the task must be of equal or greater privilege) for access to be
+granted. Violation of this rule during segment load instruction causes a
+general protection exception with an error code identifying the selector.
+
+While the enforcement of DPL protection rules provides the mechanism for
+the isolation of code and data at different privilege levels, it is
+conceivable that an erroneous pointer passed onto a more trusted program
+might result in the illegal modification of data with a higher privilege
+level. This possibility is prevented by the enforcement of effective
+privilege level protection rules and correct usage of the RPL value.
+
+The RPL (requested privilege level) is used for pointer validation. It is
+the least significant two bits in the selector value loaded into any segment
+register. RPL is intended to indicate the privilege level of the originator
+of that selector. A selector may be passed down through several procedures
+at different levels. The RPL reflects the privilege level of the original
+supplier of the selector, not the privilege level of the intermediate
+supplier. The RPL must be numerically less than or equal to the DPL of the
+descriptor selected, thereby indicating greater or equal privilege of the
+supplier; otherwise, access is denied and a general protection violation
+occurs.
+
+Pointer validity testing is required in any system concerned with
+preventing program errors from destroying system integrity. The 80286
+provides hardware support for pointer validity testing. The RPL field
+indicates the privilege level of the originator of the pointer to the
+hardware. Access will be denied if the originator of the pointer did not
+have access to the selected segment even if the CPL is numerically less than
+or equal to the DPL. RPL can reduce the effective privilege of a task when
+using a particular selector. RPL never allows access to more privileged
+segments (CPL must always be numerically less than or equal to DPL).
+
+A fourth term is sometimes used: the Effective Privilege Level (EPL). It is
+defined as the numeric maximum of the CPL and the RPL──meaning the one of
+lesser privilege. Access to a protected entity is granted only when the EPL
+is numerically less than or equal to the DPL of that entity. This is simply
+another way of saying that both CPL and RPL must be numerically less than
+or equal to DPL for access to be granted.
+
+
+7.4.4 Pointer Privilege Stamping via ARPL
+
+The ARPL instruction is provided in the 80286 to fill the RPL field of a
+selector with the minimum privilege (maximum numeric value) of the
+selector's current RPL and the caller's CPL (given in an
+instruction-specified register). A straight insertion of the caller's CPL
+would stamp the pointer with the privilege level of the caller, but not
+necessarily the ultimate originator of the selector (e.g., Level 3 supplies
+a selector to a level 2 routine that calls a level 0 routine with the same
+selector).
+
+Figure 7-9 shows a program with an example of such a situation. The program
+at privilege level 3 calls a routine at level 2 via a gate. The routine at
+level 2 uses the ARPL instruction to assure that the selector's RPL is 3.
+When the level 2 routine calls a routine at level 0 and passes the
+selector, the ARPL instruction at level 0 leaves the RPL field unchanged.
+
+Stamping a pointer with the originator's privilege eliminates the complex
+and time-consuming software typically associated with pointer validation in
+less comprehensive architectures. The 80286 hardware performs the pointer
+test automatically while loading the selector.
+
+Privilege errors are trapped at the time the selector is loaded because
+pointers are commonly passed to other routines, and it may not be possible
+to identify a pointer's originator. To verify the access capabilities of a
+pointer, it should be tested when the pointer is first received from an
+untrusted source. The VERR (Verify Read), VERW (Verify Write), and LAR (Load
+Access Rights) instructions are provided for this purpose.
+
+Although pointer validation is fully supported in the 80286, its use is an
+option of the system designer. To accommodate systems that do not require
+it, RPL can be ignored by setting selector RPLs to zero (except stack
+segment selectors) and not adjusting them with the ARPL instruction.
+
+
+Figure 7-9. Pointer Privilege Stamping
+
+Level 3 PUSH SELECTOR ; RPL value doesn't matter at level 3
+ CALL LEVEL_2
+
+ Level_2:
+ ENTER 4,0
+ MOV AX, [BP] + 4 ; GET CS of return address, RPL=3
+ ARPL [BP] + 6, AX ; Put 3 in RPL field
+Level 2 ∙
+ ∙
+ ∙
+ PUSH WORD PTR [BP] + 6 ; Pass selector
+ CALL LEVEL_0
+
+ Level_0:
+ ENTER 6,0
+Level 0 MOV AX, [BP] + 4 ; Get CS of return address, RPL=2
+ ARPL [BP] + 6, AX ; Leaves RPL unchanged
+
+
+7.5 Control Transfers
+
+Three kinds of control transfers can occur within a task:
+
+ 1. Within a segment, causing no change of privilege level (a short jump,
+ call, or return).
+
+ 2. Between segments at the same privilege level (a long jump, call, or
+ return).
+
+ 3. Between segments at different privilege levels (a long call, or
+ return). (NOTE: A JUMP to a different privilege level is not allowed.)
+
+The first two types of control transfers need no special controls (with
+respect to privilege protection) beyond those discussed in section 7.4.
+
+Inter-level transfers require special consideration to maintain system
+integrity. The protection hardware must check that:
+
+ ■ The task is currently allowed to access the destination address.
+ ■ The correct entry address is used.
+
+To achieve control transfers, a special descriptor type called a gate is
+provided to mediate the change in privilege level. Control transfer
+instructions call the gate rather than transfer directly to a code segment.
+From the viewpoint of the program, a control transfer to a gate is the same
+as to another code segment.
+
+Gates allow programs to use other programs at more privileged levels in the
+same manner as a program at the same privilege level. Programmers need never
+distinguish between programs or subroutines that are more privileged than
+the current program and those that are not. The system designer may,
+however, elect to use gates only for control transfers that cross privilege
+levels.
+
+
+7.5.1 Gates
+
+A gate is a four-word control descriptor used to redirect a control
+transfer to a different code segment in the same or more privileged level or
+to a different task. There are four types of gates: call, trap, interrupt,
+and task gates. The access rights byte distinguishes a gate from a segment
+descriptor, and determines which type of gate is involved. Figure 7-10
+shows the format of a gate descriptor.
+
+A key feature of a gate is the re-direction it provides. All four gate
+types define a new address which transfers control when invoked. This
+destination address normally cannot be accessed by a program. Loading the
+selector to a call gate into SS, DS, or ES will cause a general protection
+fault with an error code identifying the invalid selector.
+
+Only the selector portion of an address is used to invoke a gate. The
+offset is ignored. All that a program need know about the desired function
+is the selector required to invoke the gate. The 80286 will automatically
+start the execution at the correct address stored within the gate.
+
+A further advantage of a gate is that it provides a fixed address for any
+program to invoke another program. The calling program's address remains
+unaltered even if the entry address of the destination program changes.
+Thus, gates provide a fixed set of entry points that allow a task to access
+Operating System functions such as simple subroutines, yet the task is
+prohibited from simply jumping into the middle of the Operating System.
+
+Call gates, as described in the next section, are used for control
+transfers within a task which must either be transparently redirected or
+which require an increase in privilege level. A call gate normally specifies
+a subroutine at a greater privilege level, and the called routine returns
+via a return instruction. Call gates also support delayed binding
+(resolution of target routine addresses at run-time rather than
+program-generation-time).
+
+Trap and interrupt gates handle interrupt operations that are to be
+serviced within the current task. Interrupt gates cause interrupts to be
+disabled; trap gates do not. Trap and interrupt gates both require a return
+via the interrupt return instruction.
+
+Task gates are used to control transfers between tasks and to make use of
+task state segments for task control and status information. Tasks are
+discussed in Chapter 8, interrupts in Chapter 9.
+
+In the 80286 protection model, each privilege level has its own stack.
+Therefore, a control transfer (call or return) that changes the privilege
+level causes a new stack to be invoked.
+
+
+Figure 7-10. Gate Descriptor Format
+
+ 0 7 0
+ ╔═══════════════════════════════════════════════════════════════╗
+ +7 ║
+ INTEL RESERVEDMust be set to 0 for compatibility with the 80386 ║ +6
+ ╟───┬───────┬───┬───────────────┬───────────────────────────────╢
+ +5 ║ P │ DPL │ 0 │ 0 1 0 1 │ UNUSED ║ +4
+ ╟───┴───┴───┴───┴───┴───┴───┴───┴───────────────────────────────╢
+ +3 ║ TSS SELECTOR ║ +2
+ ╟───────────────────────────────────────────────────────────────╢
+ +1 ║ UNUSED ║ 0
+ ╚═══════════════════════════════════════════════════════════════╝
+ 15 0
+
+ Gate Descriptor Fields
+ ╔═══════════════╤══════════╤═════════════════════════════════════════════╗
+ ║ Name │ Value │ Description ║
+ ╠═══════════════╪══════════╪═════════════════════════════════════════════╣
+ ║ │ 4 │ Call Gate. ║
+ ║ TYPE │ 5 │ Task Gate. ║
+ ║ │ 6 │ Interrupt Gate. ║
+ ║ │ 7 │ Trap Gate. ║
+ ╟───────────────┼──────────┼─────────────────────────────────────────────╢
+ ║ P │ 0 │ Descriptor Contents are not valid. ║
+ ║ │ 1 │ Descriptor Contents are valid. ║
+ ╟───────────────┼──────────┼─────────────────────────────────────────────╢
+ ║ DPL │ 0-3 │ Descriptor Privilege Level. ║
+ ╟───────────────┼──────────┼─────────────────────────────────────────────╢
+ ║ │ 0-31 │ Number of words to copy from caller's ║
+ ║ WORD COUNT │ │ stack to called procedure's stack. Only ║
+ ║ │ │ used with call gate. ║
+ ╟───────────────┼──────────┼─────────────────────────────────────────────╢
+ ║ │ 16-bit │ Selector to the target code segment (Call, ║
+ ║ DESTINATION │ selector │ Interrupt or Trap Gate). ║
+ ║ SELECTOR │ │ Selector to the target task state segment ║
+ ║ │ │ (Task Gate). ║
+ ╟───────────────┼──────────┼─────────────────────────────────────────────╢
+ ║ DESTINATION │ 16-bit │ Entry point within the target code segment. ║
+ ║ OFFSET │ offset │ ║
+ ╚═══════════════╧══════════╧═════════════════════════════════════════════╝
+
+
+7.5.1.1 Call Gates
+
+Call gate descriptors are used by call and jump instructions in the same
+manner as a code segment descriptor. The hardware automatically recognizes
+that the destination selector refers to a gate descriptor. Then, the
+operation of the instruction is expanded as determined by the contents of
+the call gate. A jump instruction can access a call gate only if the target
+code segment is at the same privilege level. A call instruction uses a call
+gate for the same or more privileged access.
+
+A call gate descriptor may reside in either the GDT or the LDT, but not in
+the IDT. Figure 7-10 gives the complete layout of a call gate descriptor.
+
+A call gate can be referred to by either the long JMP or CALL instructions.
+From the viewpoint of the program executing a JMP or CALL instruction, the
+fact that the destination was reached via a call gate and not directly from
+the destination address of the instruction is not apparent.
+
+The following is a description of the protection checks performed while
+transferring control (with the CALL instruction) through a call gate:
+
+ ■ Verifying that access to the call gate is allowed. One of the
+ protection features provided by call gates is the access checks made to
+ determine if the call gate may be used (i.e., checking if the privilege
+ level of the calling program is adequate).
+
+ ■ Determining the destination address and whether a privilege transition
+ is required. This feature makes privilege transitions transparent to
+ the caller.
+
+ ■ Performing the privilege transition, if required.
+
+Verifying access to a call gate is the same for any call gate and is
+independent of whether a JMP or CALL instruction was used. The rules of
+privilege used to determine whether a data segment may be accessed are
+employed to check if a call gate may be jumped-to or called. Thus,
+privileged subroutines can be hidden from untrusted programs by the absence
+of a call gate.
+
+When an inter-segment CALL or JMP instruction selects a call gate, the
+gate's privilege and presence will be checked. The gate's DPL (in the access
+byte) is checked against the EPL (MAX (task CPL, selector RPL)). If EPL >
+CPL, the program is less privileged than the gate and therefore it may not
+make a transition. In this case, a general protection fault occurs with an
+error code identifying the gate. Otherwise, the gate is accessible from the
+program executing the call, and the control transfer is allowed to continue.
+After the privilege checks, the descriptor presence is checked. If the
+present bit of the gate access rights byte is 0 (i.e., the target code
+segment is not present), not present fault occurs with an error code
+identifying the gate.
+
+The checks indicated in table 7-3 are applied to the contents of the call
+gate. Violating any of them causes the exception shown. The low order two
+bits of the error code are zero for these exceptions.
+
+
+Table 7-3. Call Gate Checks
+
+ Type of Check Fault
+GP = General Protection, NP = Not-Present Exception Error Code
+Selector is not Null GP 0
+Selector is within Descriptor Table Limit GP Selector id
+Descriptor is a Code Segment GP Code Segment id
+Code Segment is Present NP Code Segment id
+Nonconforming Code Segment DPL > CPL GP Code Segment id
+
+───────────────────────────────────────────────────────────────────────────
+NOTE
+ The offset portion of the JMP or CALL destination address which refers to
+ a call gate is always ignored.
+───────────────────────────────────────────────────────────────────────────
+
+
+7.5.1.2 Intra-Level Transfers Via Call Gate
+
+The transfer is Intra-level if the destination code segment is at the same
+privilege level as CPL. Either the code segment is non-conforming with
+DPL = CPL, or it is conforming, with DPL ≤ CPL (see section 11.2 for this
+case). The 32-bit destination address in the gate is loaded into CS:IP.
+
+If the IP value is not within the limit of the code segment, a general
+protection fault occurs with an error code of 0. If a CALL instruction is
+used, the return address is saved in the normal manner. The only effect of
+the call gate is to place a different address into CS:IP than that
+specified in the destination address of the JMP or CALL instruction. This
+feature is useful for systems which require that a fixed address be provided
+to programs, even though the entry address for the routine may change due to
+different functions, software changes, or segment relocation.
+
+
+7.5.1.3 Inter-Level Control Transfer Via Call Gates
+
+If the destination code segment of the call gate is at a different
+privilege level than the CPL, an inter-level transfer is being requested.
+However, if the destination code segment DPL > CPL, then a general
+protection fault occurs with an error code identifying the destination code
+segment.
+
+The gate guarantees that all transitions to a more privileged level will go
+to a valid entry point rather than possibly into the middle of a procedure
+(or worse, into the middle of an instruction). See figure 7-11.
+
+Calls to more privileged levels may be performed only through call gates. A
+JMP instruction can never cause a privilege change. Any attempt to use a
+call gate in this manner will cause a general protection fault with an error
+code identifying the gate. Returns to more privileged levels are also
+prohibited. Inter-level transitions due to interrupts use a different gate,
+as discussed in Chapter 9.
+
+The RPL field of the CS selector saved as part of the return address will
+always identify the caller's CPL. This information is necessary to correctly
+return to the caller's privilege level during the return instruction. Since
+the CALL instruction places the CS value on the more privileged stack, and
+JMP instructions cannot change privilege levels, it is not possible for a
+program to maliciously place an invalid return address on the caller's
+stack.
+
+
+Figure 7-11. Call Gate
+
+ ╔═════════════╤════════════╤══════════════╗
+ ║ CALL OPCODE │ OFFSET │ SELECTOR ║ INSTRUCTION
+ ╚═════════════╧════════════╧══════╤═══════╝
+ │
+ ▼
+ • ═╦══════════════╤══• •═══╤══════════════╦═ •
+ ║ CODE │ │ ║ DESCRIPTOR
+ ║ SEG. │ │ CALL GATE ║ TABLES
+ ║ DESCR. │ │ ║
+ • ═╩════╤═════════╧══• •═══╧════╤═══╤═════╩═ •
+ │ ▲ │ │
+ │ └───────────────────┘ │ OFFSET
+ ▼ ▼
+ • ═╦════════════════════════════════════════╦═ •
+ ║ ║ TARGET
+ ║ ENTER ║ CODE
+ ║ ║ SEGMENT
+ • ═╩════════════════════════════════════════╩═ •
+
+
+7.5.1.4 Stack Changes Caused By Call Gates
+
+To maintain system integrity, each privilege level has a separate stack.
+Furthermore, each task normally uses separate stacks from other tasks for
+each privilege level. These stacks assure sufficient stack space to process
+calls from less privileged levels. Without them, trusted programs may not
+work correctly, especially if the calling program does not provide
+sufficient space on the caller's stack.
+
+When a call gate is used to change privilege levels, a new stack is
+selected as determined by the new CPL. The new stack pointer value is loaded
+from the Task State Segment (TSS). The privilege level of the new stack data
+segment must equal the new CPL; if it does not, a task stack fault occurs
+with the saved machine state pointing at the CALL instruction and the error
+code identifying the invalid stack selector.
+
+The new stack should contain enough space to hold the old SS:SP, the return
+address, and all parameters and local variables required to process the
+call. The initial stack pointers for privilege levels 0-2 in the TSS are
+strictly read only values. They are never changed during the course of
+execution.
+
+The normal technique for passing parameters to a subroutine is to place
+them onto the stack. To make privilege transitions transparent to the called
+program, a call gate specifies that parameters are to be copied from the old
+stack to the new stack. The word count field in a call gate (see figure
+7-10) specifies how many words (up to 31) are to be copied from the
+caller's stack to the new stack. If the word count is zero, no parameters
+are copied.
+
+Before copying the parameters, the new stack is checked to assure that it
+is large enough to hold the parameters; if it is not, a stack fault occurs
+with an error code of 0. After the parameters are copied, the return link is
+on the new stack (i.e., a pointer to the old stack is placed in the new
+stack). In particular, the return address is pointed at by SS:SP. The call
+and return example of figure 7-12 illustrate the stack contents after a
+successful inter-level call.
+
+The stack pointer of the caller is saved above the caller's return address
+as the first two words pushed onto the new stack. The caller's stack can
+only be saved for calls to procedures at privilege levels 2, 1, and 0. Since
+level 3 cannot be called by any procedure at any other privilege level, the
+level 3 stack will never contain links to other stacks.
+
+Procedures requiring more than the 31 words for parameters that may be
+called from another privilege level must use the saved SS:SP link to access
+all parameters beyond the last word copied.
+
+The call gate does not check the values of the words copied onto the new
+stack. The called procedure should check each parameter for validity.
+Section 11.3 discusses how the ARPL, VERR, VERW, LSL, and LAR instructions
+can be used to check pointer values.
+
+
+Figure 7-12. Stack Contents after an Inter-Level Call
+
+ ▲ ╔══════════╗ ╔══════════╗
+ │ ║ ║ ║ OLD SS ║ │
+ │ ║ ║ ╟──────────╢ │ DIRECTION
+ HIGHER ║ ║ ║ OLD SP ║ │ OF STACK
+ ADDRESSES ║ ║ ╟──────────╢ │ GROWTH
+ ║ ║ ║ PARM 3 ║ │
+ ║ ║ ╟──────────╢ │
+ ║ ║ ║ PARM 2 ║ │
+ ╟──────────╢ ╟──────────╢ │
+ ║ PARM 3 ║ ║ PARM 1 ║ ▼
+ ╟──────────╢ ╟──────────╢
+ ║ PARM 2 ║ ║ OLD CS ║
+ OLD ╟──────────╢ NEW ╟──────────╢
+ SS:SP ║ PARM 1 ║ SS + SP ║ OLD IP ║
+ LOWER └───►╚══════════╝ └────►╚══════════╝
+ ADDRESSES
+ │ OLD STACK NEW STACK
+ │ (AT "OUTER" (AT "INNER"
+ ▼ PRIVILEGE PRIVILEGE
+ LEVEL) LEVEL)
+
+
+7.5.2 Inter-Level Returns
+
+An inter-segment return instruction can also change levels, but only toward
+programs of equal or lesser privilege (when code segment DPL is numerically
+greater or equal than the CPL). The RPL of the selector popped off the stack
+by the return instruction identifies the privilege level to resume
+execution of the calling program.
+
+When the RET instruction encounters a saved CS value whose RPL > CPL, an
+inter-level return occurs. Checks shown in table 7-4 are made during such a
+return.
+
+The old SS:SP value is then adjusted by the number of bytes indicated in
+the RET instruction and loaded into SS:SP. The new SP value is not checked
+for validity. If SP is invalid it is not recognized until the first stack
+operation. The SS:SP value of the returning program is not saved. (Note:
+this value normally is the same as that saved in the TSS.)
+
+The last step in the return is checking the contents of the DS and ES
+descriptor register. If DS or ES refer to segments whose DPL is greater than
+the new CPL (excluding conforming code segments), the segment registers are
+loaded with the null selector. Any subsequent memory reference that
+attempts to use the segment register containing the null selector will cause
+a general protection fault. This prevents less privileged code from
+accessing more privileged data previously accessed by the more privileged
+program.
+
+
+Table 7-4. Inter-Level Return Checks
+
+Type of Check Exception
+SF = Stack Fault, GP = General Protection Exception, NP = Not-Present Error Code
+SP is not within Segment Limit SF 0
+SP + N + 7 is not in Segment Limit SF 0
+RPL of Return CS is Greater than CPL GP Return CS id
+Return CS Selector is not null GP Return CS id
+Return CS segment is within Descriptor GP Return CS id
+ Table Limit
+Return CS Descriptor is a Code Segment GP Return CS id
+Return CS Segment is Present NP Return CS id
+DPL of Return Non-Conforming Code GP Return CS id
+ Segment = RPL of CS
+SS Selector at SP + N + 6 is not Null SF Return SS id
+SS Selector at SP + N + 6 is within SF Return SS id
+ Descriptor Table Limit
+SS Descriptor is Writable Data Segment SF Return SS id
+SS Segment is Present SF Return SS id
+SS Segment DPL = RPL of CS SF Return SS id
+
+
+Chapter 8 Tasks and State Transitions
+
+───────────────────────────────────────────────────────────────────────────
+
+8.1 Introduction
+
+An 80286 task is a single, sequential thread of execution. Each task can be
+isolated from all other tasks. There may be many tasks associated with an
+80286 CPU, but only one task executes at any time. Switching the CPU from
+executing one task to executing another can occur as the result of either an
+interrupt or an inter-task CALL, JMP or IRET. A hardware-recognized data
+structure defines each task.
+
+The 80286 provides a high performance task switch operation with complete
+isolation between tasks. A full task-switch operation takes only 22
+microseconds at 8 MHz (18 microseconds at 10 MHz). High-performance,
+interrupt-driven, multi-application systems that need the benefits of
+protection are feasible with the 80286.
+
+A performance advantage and system design advantage arise from the 80286
+task switch:
+
+ ■ Faster task switch: A task switch is a single instruction performed by
+ microcode. Such a scheme is 2-3 times faster than an explicit task
+ switch instruction. A fast task switch translates to a significant
+ performance boost for heavily multi-tasked systems over conventional
+ methods.
+
+ ■ More reliable, flexible systems: The isolation between tasks and the
+ high speed task switch allows interrupts to be handled by separate
+ tasks rather than within the currently interrupted task. This isolation
+ of interrupt handling code from normal programs prevents undesirable
+ interactions between them. The interrupt system can become more
+ flexible since adding an interrupt handler is as safe and easy as
+ adding a new task.
+
+ ■ Every task is protected from all others via the separation of address
+ spaces described in Chapter 7, including allocation of unique stacks
+ to each active privilege level in each task (unless explicit sharing is
+ planned in advance). If the address spaces of two tasks include no
+ shared data, one task cannot affect the data of another task. Code
+ sharing is always safe since code segments may never be written into.
+
+
+8.2 Task State Segments and Descriptors
+
+Tasks are defined by a special control segment called a Task State Segment
+(TSS). For each task, there must be an unique TSS. The definition of a task
+includes its address space and execution state. A task is invoked (made
+active) by inter-segment jump or call instructions whose destination
+address refers to a task state segment or a task gate.
+
+The Task State Segment (TSS) has a special descriptor. The Task Register
+within the CPU contains a selector to that descriptor. Each TSS selector
+value is unique, providing an unambiguous "identifier" for each task. Thus,
+an operating system can use the value of the TSS selector to uniquely
+identify the task.
+
+A TSS contains 22 words that define the contents of all registers and
+flags, the initial stacks for privilege levels 0-2, the LDT selector, and a
+link to the TSS of the previously executing task. Figure 8-1 shows the
+layout of the TSS. The TSS can not be written into like an ordinary data
+segment.
+
+Each TSS consists of two parts, a static portion and a dynamic portion. The
+static entries are never changed by the 80286, while the dynamic entries are
+changed by each task switch out of this task. The static portions of this
+segment are the task LDT selector and the initial SS:SP stack pointer
+addresses for levels 0-2.
+
+The modifiable or dynamic portion of the task state segment consists of all
+dynamically-variable and programmer-visible processor registers, including
+flags, segment registers, and the instruction pointer. It also includes the
+linkage word used to chain nested invocations of different tasks.
+
+The link word provides a history of which tasks invoked others. The link
+word is important for restarting an interrupted task when the interrupt has
+been serviced. Placing the back link in the TSS protects the identity of the
+interrupted task from changes by the interrupt task, since the TSS is not
+writable by the interrupt task. (In most systems only the operating system
+has sufficient privilege to create or use a writable data segment "alias"
+descriptor for the TSS.)
+
+The stack pointer entries in the TSS for privilege levels 0-2 are static
+(i.e., never written during a privilege or task switch). They define the
+stack to use upon entry to that privilege level. These stack entries are
+initialized by the operating system when the task is created. If a
+privilege level is never used, no stack need be allocated for it.
+
+When entering a more privileged level, the caller's stack pointer is saved
+on the stack of the new privilege level, not in the TSS. Leaving the
+privilege level requires popping the caller's return address and stack
+pointer off the current stack. The stack pointer at that time will be the
+same as the initial value loaded from the TSS upon entry to the privilege
+level.
+
+There is only one stack active at any time, the one defined by the SS and
+SP registers. The only other stacks that may be non-empty are those at outer
+(less privileged) levels that called the current level. Stacks for inner
+levels must be empty, since outward (to numerically larger privilege
+levels) calls from inner levels are not allowed.
+
+The location of the stack pointer for an outer privilege level will always
+be found at the start of the stack of the inner privilege level called by
+that level. That stack may be the initial stack for this privilege level or
+an outer level. Look at the start of the stack for this privilege level.
+The TSS contains the starting stack address for levels 0-2. If the RPL of
+the saved SS selector is the privilege level required, then the stack
+pointer has been found. Otherwise, go to the beginning of the stack defined
+by that value and look at the saved SS:SP value there.
+
+
+Figure 8-1. Task State Segment and TSS Registers
+
+ • •
+ ┌─╟───────────────────────────────╢
+ │ ║ INTEL RESERVED ║
+ │ ╟─┬───┬─┬───────┬───────────────║─┐
+ TSS │ ║P
+╔═══╤═══════════════════════════════════╗
+║ P │ DESCRIPTION ║
+╠═══╪═══════════════════════════════════╣
+║ 1 │ BASE AND LIMIT FIELDS ARE VALID ║
+╟───┼───────────────────────────────────╢
+║ 0 │ SEGMENT IS NOT PRESENT IN MEMORY. ║
+║ │ BASE AND LIMIT ARE NOT DEFINED ║
+╚═══╧═══════════════════════════════════╝
+DPL│0│ TYPE
+╔════╤══════════════════════════════════════════════╗
+║TYPE│DESCRIPTION ║
+╠════╪══════════════════════════════════════════════╣
+║ 1 │AN AVAILABLE TASK STATE SEGMENT MAY BE USED ║
+║ │AS THE DESTINATION OF A TASK SWITCH OPERATION.║
+╟────┼──────────────────────────────────────────────╢
+║ │A BUSY TASK STATE SEGMENT CANNOT BE USED AS ║
+║ │THE DESTINATION OF A TASK SWITCH. ║
+╚════╧══════════════════════════════════════════════╝
+ │ BASE 23-16 ║ │
+ DESCRIPTOR ─┤ ╟─┴─┴─┴─┴─┴─┴─┴─┴───────────────╢ │
+ ▲ │ ║ BASE 15-0 ║ ├ ┐
+ │ │ ╟───────────────────────────────╢ │
+ │ ║ LIMIT 15-0 ║ │ │
+ │ └─╟───────────────────────────────╢─┘
+ CPU ┌─ ──║── ── ── ── ── ── ── ── ── ── ─╫ ──┘
+╔════════════════════╪══╗ ≈ ≈
+║ TASK REGISTER ║ │ ║15 0║ BYTE
+║ ╔═══════╗ │ ║ ┌─╟───────────────────────────────╢ OFFSET
+║ ║ ╟── ─┘ ║ │ │ ║ TASK LDT SELECTOR ║ 42
+Never altered (static) after initialization by O.S. The values as
+initialized for this task are always valid SS:SP values to use upon entry
+to that privilege level (0, 1, or 2) from a level of lesser privilege.
+║ ╚═══════╝ ║ │ ╟───────────────────────────────╢ ─┐
+║ 15 0 ║ │ │ ║ DS SELECTOR ║ 40 │
+║ ┌── ── ── ── ── ── ─┐ ║ │ ╟───────────────────────────────╢ │
+║ PROGRAM INVISIBLE ║ │ │ ║ SS SELECTOR ║ 38 │
+║ │ 15 0 │ ║ │ ╟───────────────────────────────╢ │
+║ ╔═══════╗ ┐ ║ │ │ ║ CS SELECTOR ║ 36 │
+║ │ ║ LIMIT ╟─┐ │ │ ║ │ ╟───────────────────────────────╢ │
+║ ╔═══╩───────╢ │ │◄─ ╫─┘ │ ║ ES SELECTOR ║ 34 │
+║ │ ║ BASE ║ │ │ │ ║ │ ╟───────────────────────────────╢ │
+║ ╚╤══════════╝ │ ┘ ║ │ ║ DI ║ 32 │
+║ │ │ 0 │ │ ║ │ ╟───────────────────────────────╢ │
+║ └──│── ── ── ── ┼─ ─┘ ║ │ ║ SI ║ 30 │
+╚════╪════════════╪═════╝ │ ╟───────────────────────────────╢ │
+ │ │ │ ║ BP ║ 28 │CURRENT
+ │ │ │ ╟───────────────────────────────╢ ├TASK
+ │ │ │ ║ SP ║ 26 │STATE
+Changed during task switch.
+ │ │ │ ╟───────────────────────────────╢ │
+ │ │ │ ║ BX ║ 24 │
+ │ │ │ ╟───────────────────────────────╢ │
+ │ │ TASK │ ║ DX ║ 22 │
+ │ └► STATE ┤ ╟───────────────────────────────╢ │
+ │ SEGMENT │ ║ CX ║ 20 │
+ │ │ ╟───────────────────────────────╢ │
+ │ │ ║ AX ║ 18 │
+ │ │ ╟───────────────────────────────╢ │
+ │ │ ║ FLAG WORD ║ 16 │
+ │ │ ╟───────────────────────────────╢ │
+ │ │ ║ IP (ENTRY POINT) ║ 14 │
+ │ │ ╟───────────────────────────────╢ ═╡
+ │ │ ║ SS FOR CPL 2 ║ 12 │
+ │ │ ╟───────────────────────────────╢ │
+ │ │ ║ SP FOR CPL 2 ║ 10 │
+ │ │ ╟───────────────────────────────╢ │INITIAL
+ │ │ ║ SS FOR CPL 1 ║ 8 │STACKS
+ │ │ ╟───────────────────────────────╢ ├FOR
+ │ │ ║ SP FOR CPL 1 ║ 6 │CPL
+ │ │ ╟───────────────────────────────╢ │0,1,2
+Never altered (static) after initialization by O.S. The values as
+initialized for this task are always valid SS:SP values to use upon entry
+to that privilege level (0, 1, or 2) from a level of lesser privilege.
+ │ │ ║ SS FOR CPL 0 ║ 4 │
+ │ │ ╟───────────────────────────────╢ │
+ │ │ ║ SP FOR CPL 0 ║ 2 │
+ │ │ ╟───────────────────────────────╢ ─┘
+ │ │ ║ BACK LINK SELECTOR TO TSS ║ 0 ◄─────
+ └──────────────────────►└─╟───────────────────────────────╢
+ ║ ║
+ • •
+
+
+8.2.1 Task State Segment Descriptors
+
+A special descriptor is used for task state segments. This descriptor must
+be accessible at all times; therefore, it can appear only in the GDT. The
+access byte distinguishes TSS descriptors from data or code segment
+descriptors. When bits 0 through 4 of the access byte are 00001 or 00011,
+the descriptor is for a TSS.
+
+The complete layout of a task state segment descriptor is shown in figure
+8-2.
+
+Like a data segment, the descriptor contains a base address and limit
+field. The limit must be at least 002BH (43) to contain the minimum amount
+of information required for a TSS. An invalid task exception will occur if
+an attempt is made to switch to a task whose TSS descriptor limit is less
+than 43. The error code will identify the bad TSS.
+
+The P-bit (Present) flag indicates whether this descriptor contains
+currently valid information: 1 means yes, 0 no. A task switch that attempts
+to reference a not-present TSS causes a not-present exception code
+identifying the task state segment selector.
+
+The descriptor privilege level (DPL) controls use of the TSS by JMP or CALL
+instructions. By the same reasoning as that for call gates, DPL can prevent
+a program from calling the TSS and thereby cause a task switch. Section 8.3
+discusses privilege considerations during a task switch in greater detail.
+
+Bit 4 is always 0 since TSS is a control segment descriptor. Control
+segments cannot be accessed by SS, DS, or ES. Any attempt to load those
+segment registers with a selector that refers to a control segment causes
+general protection trap. This rule prevents the program from improperly
+changing the contents of a control segment.
+
+TSS descriptors can have two states: idle and busy. Bit 1 of the access
+byte distinguishes them. The distinction is necessary since tasks are not
+re-entrant; a busy TSS may not be invoked.
+
+
+Figure 8-2. TSS Descriptor
+
+ 7 0 7 0
+ ╔═══════════════════════════════╤═══════════════════════════════╗
+ +7║ INTEL RESERVED
+ Must be set to 0 for compatibility with 80836 ║+6
+ ╟───┬───────┬───┬───────────┬───┬───────────────────────────────╢
+ +5║ P │ DPL │ 0 │ 0 0 B │ 1 │ TSB BASE 23-16 ║+4
+ ╟───┴───┴───┴───┴───┴───┴───┴───┴───────────────────────────────╢
+ +3║ TSS BASE 15-0 ║+2
+ ║───────────────────────────────────────────────────────────────║
+ +1║ TSS LIMIT ║ 0
+ ╚═══════════════════════════════════════════════════════════════╝
+ 15 0
+
+ B=1 MEANS TASK IS BUSY AND NOT AVAILABLE
+
+
+8.3 Task Switching
+
+A task switch may occur in one of four ways:
+
+ 1. The destination selector of a long JMP or CALL instruction refers to
+ a TSS descriptor. The offset portion of the destination address is
+ ignored.
+
+ 2. An IRET instruction is executed when the NT bit in the flag word = 1.
+ The new task TSS selector is in the back link field of the current
+ TSS.
+
+ 3. The destination selector of a long JMP or CALL instruction refers to
+ a task gate. The offset portion of the destination address is ignored.
+ The new task TSS selector is in the gate. (See section 8.5 for more
+ information on task gates.)
+
+ 4. An interrupt occurs. This interrupt's vector refers to a task gate in
+ the interrupt descriptor table. The new task TSS selector is in the
+ gate. See section 9.4 for more information on interrupt tasks.
+
+No new instructions are required for a task switch operation. The standard
+8086 JMP, CALL, IRET, or interrupt operations perform this function. The
+distinction between the standard instruction and a task switch is made
+either by the type of descriptor referenced (for CALL, JMP, or INT) or by
+the NT bit (for IRET) in flag word.
+
+Using the CALL or INT instruction to switch tasks implies a return is
+expected from the called task. The JMP and IRET instructions imply no return
+is expected from the new task.
+
+When NT=1, the IRET instruction causes a return to the task that called the
+current one via CALL or INT instruction.
+
+Access to TSS and task gate descriptors is restricted by the rules of
+privilege level. The data access rules are used, thereby allowing task
+switches to be restricted to programs of sufficient privilege. Address space
+separation does not apply to TSS descriptors since they must be in the GDT.
+The access rules for interrupts are discussed in section 9.4.
+
+The task switch operation consists of the following eight steps:
+
+ 1. Validate the requested task switch. For a task switch requested via a
+ JMP, CALL, or an INT instruction, check that the current task is
+ allowed to switch to the requested task. The DPL of the gate or the
+ TSS descriptor for the requested task must be greater than or equal
+ to both the CPL and the RPL of the requesting task. If it is not, the
+ General Protection fault (#13) will occur with an error code
+ identifying the descriptor (i.e., the gate selector if the task
+ switch is requested via a task gate, or the selector for the TSS if
+ the task switch is requested via a TSS descriptor).
+
+ These checks are not performed if a task switch occurs due to an IRET
+ instruction.
+
+ 2. Check that the new TSS is present and that the new task is available
+ (i.e. not Busy). A Not Present exception (#11) is signaled if the new
+ TSS descriptor is marked 'Not Present' (P = 0). The General Protection
+ exception (#13) is raised if the new TSS is marked 'Busy'.
+
+ The task switch operation actually begins now and a detailed
+ verification of the new TSS is carried out. Conditions which may
+ disqualify the new TSS are listed in table 8-1 along with the
+ exception raised and the error code pushed on the stack for each case.
+ These tests are performed at different points during the course of the
+ following remaining steps of the task switch operation.
+
+ 3. Mark the new task to be BUSY by setting the 'BUSY' bit in the new TSS
+ descriptor to 1.
+
+ 4. Save the dynamic portion of the old TSS and load TR with the
+ selector, base and limit for the new TSS. Set all CPU registers to
+ corresponding values from the new TSS except DS, ES, CS, SS, and LDT.
+
+ 5. If nesting tasks, set the Nested Task (NT) flag in the new TSS to 1.
+ Also set the Task Switched flag (TS) of the CPU flag register to 1.
+
+ 6. Validate the LDT selector and the LDT descriptor of the new TSS. Load
+ the LDT cache (LDTR) with the LDT descriptor.
+
+ 7. Validate the SS, CS, DS, and ES fields of the new TSS and load these
+ values in their respective caches (i.e., SS, CS, DS, and ES
+ registers).
+
+ 8. Validate the IP field of the new TSS and then start executing the new
+ task from CS:IP.
+
+A more detailed explanation of steps 3-5 is given in Appendix B (80286
+Instruction Set) under a pseudo procedure 'SWITCH_TASKS'. Notice how the
+exceptions described in table 8-1 may actually occur during a task switch.
+Similarly the exceptions that may occur during steps 1-2, and step 8 are
+explained in greater detail in the pseudo code description of the 286
+instructions CALL, JMP, INT, and IRET in Appendix B. This information can
+be very helpful when debugging any protected mode code.
+
+Note that the state of the outgoing task is always saved. If execution of
+that task is resumed, it will start after the instruction that caused the
+task switch. The values of the registers will be the same as that when the
+task stopped running.
+
+Any task switch sets the Task Switched (TS) bit in the Machine Status Word
+(MSW). This flag is used when processor extensions such as the 80287 Numeric
+Processor Extension are present. The TS bit signals that the context of the
+processor extension may not belong to the current 80286 task. Chapter 11
+discusses the TS bit and processor extensions in more detail.
+
+Validity tests on a selector ensure that the selector is in the proper
+table (i.e., the LDT selector refers to GDT), lies within the bounds of the
+table, and refers to the proper type of descriptor (i.e., the LDT selector
+refers to the LDT descriptor).
+
+Note that between steps 3 and 4 in table 8-1, all the registers of the new
+task are loaded. Several protection rule violations may exist in the new
+segment register contents. If an exception occurs in the context of the new
+task due to checks performed on the newly loaded descriptors, the DS and ES
+segments may not be accessible even though the segment registers contain
+non-zero values. These selector values must be saved for later reuse. When
+the exception handler reloads these segment registers, another protection
+exception may occur unless the exception handler pre-examines them and
+fixes any potential problems.
+
+A task switch allows flexibility in the privilege level of the outgoing and
+incoming tasks. The privilege level at which execution resumes in the
+incoming task is not restricted by the privilege level of the outgoing task.
+This is reasonable, since both tasks are isolated from each other with
+separate address spaces and machine states. The privilege rules prevent
+improper access to a TSS. The only interaction between the tasks is to the
+extent that one started the other and the incoming task may restart the
+outgoing task by executing an IRET instruction.
+
+
+Table 8-1. Checks Made during a Task Switch
+
+
+ Test Exception
+NP = Not-Present Exception
+GP = General Protection Fault
+SF = Stack Fault Error Code
+1 Incoming TSS descriptor NP Incoming TSS selector
+ is present
+2 Incoming TSS is idle G Incoming TSS selector
+3 Limit of incoming TSS Invalid TSS Incoming TSS selector
+ greater than 43
+4 LDT selector of incoming Invalid TSS LDT selector
+ TSS is valid
+5 LDT of incoming TSS Invalid TSS LDT selector
+ is present
+6 CS selector is valid Invalid TSS Code segment selector
+7 Code segment is present NP Code segment selector
+8 Code segment DPL matches Invalid TSS Code segment selector
+ CS RPL
+9 Stack segment is valid SF Stack segment selector
+10 Stack segment is writable GP Stack segment selector
+ data segment
+11 Stack segment is present SF Stack segment selector
+12 Stack segment DPL = CPL SF Stack segment selector
+13 DS/ES selectors are valid GP Segment selector
+14 DS/ES segments are readable GP Segment selector
+15 DS/ES segments are present NP Segment selector
+16 DS/ES segment DPL ≥ CPL if GP Segment
+ not conform
+
+
+8.4 Task Linking
+
+The TSS has a field called "back link" which contains the selector of the
+TSS of a task that should be restarted when the current task completes. The
+back link field of an interrupt-initiated task is automatically written with
+the TSS selector of the interrupted task.
+
+A task switch initiated by a CALL instruction also points the back link at
+the outgoing task's TSS. Such task nesting is indicated to programs via the
+Nested Task (NT) bit in the flag word of the incoming task.
+
+Task nesting is necessary for interrupt functions to be processed as
+separate tasks. The interrupt function is thereby isolated from all other
+tasks in the system. To restart the interrupted task, the interrupt handler
+executes an IRET instruction much in the same manner as an 8086 interrupt
+handler. The IRET instruction will then cause a task switch to the
+interrupted task.
+
+Completion of a task occurs when the IRET instruction is executed with the
+NT bit in the flag word set. The NT bit is automatically set/reset by task
+switch operations as appropriate. Executing an IRET instruction with NT
+cleared causes the normal 8086 interrupt return function to be performed,
+and no task switch occurs.
+
+Executing IRET with NT set causes a task switch to the task defined by the
+back link field of the current TSS. The selector value is fetched and
+verified as pointing to a valid, accessible TSS. The normal task switch
+operation described in section 8.3 then occurs. After the task switch is
+complete, the outgoing task is now idle and considered ready to process
+another interrupt.
+
+Table 8-2 shows how the busy bit, NT bit, and link word of the incoming and
+outgoing task are affected by task switch operations caused by JMP, CALL, or
+IRET instructions.
+
+Violation of any of the busy bit requirements shown in table 8-2 causes a
+general protection fault with the saved machine state appearing as if the
+instruction had not executed. The error code identifies the selector of the
+TSS with the busy bit.
+
+A bus lock is applied during the testing and setting of the TSS descriptor
+busy bit to ensure that two processors do not invoke the same task at the
+same time. See also section 11.4 for other multi-processor considerations.
+
+The linking order of tasks may need to be changed to restart an interrupted
+task before the task that interrupted it completes. To remove a task from
+the list, trusted operating system software must change the backlink field
+in the TSS of the interrupting task first, then clear the busy bit in the
+TSS descriptor of the task removed from the list.
+
+When trusted software deletes the link from one task to another, it should
+place a value in the backlink field, which will pass control to that trusted
+software when the task attempts to resume execution of another task via
+IRET.
+
+
+Table 8-2. Effect of a Task Switch on BUSY and NT Bits and the Link Word
+
+
+ JMP CALL/INT IRET
+Affected Field Instruction Instruction Instruction
+ Effect Effect Effect
+
+Busy bit of incoming Set, must be Set, must be 0 Unchanged,
+ task TSS descriptor 0 before before must be set
+
+Busy bit of outgoing Cleared Unchanged (will Cleared
+ tasl TSS descriptor already be 1)
+
+NT bit in incoming task Cleared Set Unchanged
+ flag word
+
+NT bit in outgoing task Unchanged Unchanged Cleared
+ flag word
+
+Back link in incoming Unchanged Set to outgoing Unchanged
+ task TSS task TSS selector
+
+Back link of outgoing Unchanged Unchanged Unchanged
+ tasl TSS
+
+
+
+8.5 Task Gates
+
+A task may be invoked by several different events. Task gates are provided
+to support this need. Task gates are used in the same way as call and
+interrupt gates. The ultimate effect of jumping to or calling a task gate is
+the same as jumping to or calling directly to the TSS in the task gate.
+
+Figure 8-3 depicts the layout of a task gate.
+
+A task gate is identified by the access byte field in bits 0 through 4
+being 00101. The gate provides an extra level of indirection between the
+destination address and the TSS selector value. The offset portion of the
+JMP or CALL destination address is ignored.
+
+Gate use provides flexibility in controlling access to tasks. Task gates
+can appear in the GDT, IDT, or LDT. The TSS descriptors for all tasks must
+be kept in the GDT. They are normally placed at level 0 to prevent any task
+from improperly invoking another task. Task gates placed in the LDT allow
+private access to selected tasks with full privilege control.
+
+The data segment access rules apply to accessing a task gate via JMP, CALL,
+or INT instructions. The effective privilege level (EPL) of the destination
+selector must be numerically less than or equal to the DPL of the task gate
+descriptor. Any violation of this requirement causes a general protection
+fault with an error code identifying the task gate involved.
+
+Once access to the task gate has been verified, the TSS selector from the
+gate is read. The RPL of the TSS selector is ignored. From this point, all
+the checks and actions performed for a JMP or CALL to a TSS after access has
+been verified are performed (see section 8.4). Figure 8-4 illustrates an
+example of a task switch through a task gate.
+
+
+Figure 8-3. Task Gate Descriptor
+
+ 7 0 7 0
+ ╔═══════════════════════════════════════════════════════════════╗
+ +7║ INTEL RESERVED
+ Must be set to 0 for compatibility with 80386 ║+6
+ ╟───┬───────┬───┬───────────┬───┬───────────────────────────────╢
+ +5║ P │ DPL │ O │ O 1 O │ 1 │ UNUSED ║+4
+ ╟───┴───────┴───┴───┴───┴───┴───┴───────────────────────────────╢
+ +3║ TSS SELECTOR ║+2
+ ║───────────────────────────────────────────────────────────────║
+ +1║ UNUSED ║ 0
+ ╚═══════════════════════════════════════════════════════════════╝
+ 15 0
+
+
+Figure 8-4. Task Switch Through a Task Gate
+
+ TASK A TASK B
+ ╔══════════════╗ ╔══════════════╗ ╔══════════════╗
+ ║ ║ ║ ║ ║ ║
+ ║ ║ ║ ║ ≈ ≈
+ ║ ║ ╟──────────────╢ ║ ║
+ ║ ║TASK┌║LDT DESCRIPTOR╟───►╚══════════════╝
+ ║ ║ B┤╟──────────────╢◄─┐ LDT
+╔═══════╤════════╗ ╟──────────────╢ └║TSS DESCRIPTOR╟─┐│
+║ │SELECTOR║►║ TASK GATE ║────►╟──────────────╢ ││ ╔══════════════╗
+╚═══════╧════════╝ ╟──────────────╢ ║ ║ │└─╢ LDT SELECTOR ║
+ ≈ ≈ ║ ║ │ ╟──────────────╢
+ ║ ║ ║ ║ │ ║ ║
+ ╚══════════════╝◄─┐ ║ ║ │ ║ ║
+ LDT │ ║ ║ │ ║ ║
+ └──╫──────────────╢ │ ║ ║
+ ╔══════════════╗────►║LDT DESCRIPTOR║┐│ ║ ║
+ ║ LDT SELECTOR ║ ╟──────────────╢│└─►╟──────────────╢
+ ╟──────────────╢ ║TSS DESCRIPTOR║┴┐ ║ BACK LINK ║
+ ║ ║ ┌──╫──────────────╢◄───╚══════════════╝
+ ║ ║ │ ║ ║ │ TSS
+ ║ ║ │ ║ ║ └TASK
+ ╚══════════════╝◄─┘ ╚══════════════╝ A
+ TSS GDT
+
+
+Chapter 9 Interrupts and Exceptions
+
+───────────────────────────────────────────────────────────────────────────
+
+Interrupts and exceptions are special cases of control transfer within a
+program. An interrupt occurs as a result of an event that is independent of
+the currently executing program, while exceptions are a direct result of the
+program currently being executed. Interrupts may be external or internal.
+External interrupts are generated by either the INTR or NMI input pins.
+Internal interrupts are caused by the INT instruction. Exceptions occur when
+an instruction cannot be completed normally. Although their causes differ,
+interrupts and exceptions use the same control transfer techniques and
+privilege rules; therefore, in the following discussions the term interrupt
+will also apply to exceptions.
+
+The program used to service an interrupt may execute in the context of the
+task that caused the interrupt (i.e., used the same TSS, LDT, stacks, etc.)
+or may be a separate task. The choice depends on the function to be
+performed and the level of isolation required.
+
+
+9.1 Interrupt Descriptor Table
+
+Many different events may cause an interrupt. To allow the reason for an
+interrupt to be easily identified, each interrupt source is given a number
+called the interrupt vector. Up to 256 different interrupt vectors (numbers)
+are possible. See figure 9-1.
+
+A table is used to define the handler for each interrupt vector. The
+Interrupt Descriptor Table (IDT) defines the interrupt handlers for up to
+256 different interrupts. The IDT is in physical memory, pointed to by the
+contents of the on-chip IDT register that contains a 24-bit base and a
+16-bit limit. The IDTR is normally loaded with the LIDT instruction by code
+that executes at privilege level 0 during system initialization. The IDT may
+be located anywhere in the physical address space of the 80286.
+
+Each IDT entry is a 4-word gate descriptor that contains a pointer to the
+handler. The three types of gates permitted in the IDT are interrupt gates,
+trap gates (discussed in section 9.3), and task gates (discussed in section
+9.5). Interrupt and task gates process interrupts in the same task, while
+task gates cause a task switch. Any other descriptor type in the IDT will
+cause an exception if it is referenced by an interrupt.
+
+The IDT need not contain all 256 entries. A 16-bit limit register allows
+less than the full number of entries. Unused entries may be signaled by
+placing a zero in the access rights byte. If an attempt is made to access an
+entry outside the table limit, or if the wrong descriptor type is found, a
+general protection fault occurs with an error code pushed on the stack
+identifying the invalid interrupt vector (see figure 9-2).
+
+Exception error codes that refer to an IDT entry can be identified by bit 1
+of the error code that will be set. Bit 0 of the error code is 1 if the
+interrupt was caused by an event external to the program (i.e., an external
+interrupt, a single step, a processor extension error, or a processor
+extension not present).
+
+Interrupts 0-31 are reserved for use by Intel. Some of the interrupts are
+used for instruction exceptions. The IDT limit must be at least 255
+(32 * 8 - 1) to accommodate the minimum number of interrupts. The remaining
+224 interrupts are available to the user.
+
+
+Figure 9-1. Interrupt Descriptor Table Definition
+
+ MEMORY
+ • •
+ ║ ║ THE IDT MAY
+ ┌─╠═══════════════╣─┐ CONTAIN
+ │ ║ GATE FOR ║ │ INTERRUPT
+ │ ║ INTERRUPT #n ║ │ GATES, TRAPS
+ │ ╠═══════════════╣ │ OR TASK GATES
+ │ ║ GATE FOR ║ │ ONLY.
+ │ ║INTERRUPT #n-1 ║ │
+ │ ╠═══════════════╣ │
+ │ ║ ∙ ║ │ INTERRUPT
+ ┌─►─┤ ║ ∙ ║ ├─ DESCRIPTOR
+ │ │ ║ ∙ ║ │ TABLE (IDT)
+ CPU │ │ ╠═══════════════╣ │
+ ┌───────────────────┐ │ │ ║ GATE FOR ║ │
+ │ 15 0 │ │ │ ║ INTERRUPT #1 ║ │
+ │ ╔═════════╗ │ │ │ ╠═══════════════╣ │
+ │ ║IDT LIMIT╟──┼──┘ │ ║ GATE FOR ║ │
+ IDTR │ ╔═══╨─────────╢ │ └─║ INTERRUPT #0 ║ │
+ │ ║ IDT BASE ╟──┼───────►╠═══════════════╣─┘
+ │ ╚═════════════╝ │ ║ ║
+ │ 23 0 │ • •
+ └───────────────────┘
+
+
+Figure 9-2. IDT Selector Error Code
+
+ 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+ ╔═══════════════════╤═══════════════════════════════╤═══╤═══╤═══╗
+ ║ │ │ │ │ E ║
+ ║ 0 0 0 0 0 │ IDT VECTOR │ 0 │ 1 │ X ║
+ ║ │ │ │ │ T ║
+ ╚═══════════════════╧═══════════════════════════════╧═══╧═══╧═╤═╝
+ ┌─────────────────────────────────┘
+ ▼
+ 1 An even external to the program
+ caused the exception (i.e. external
+ interrupt, single step, processor
+ extension error)
+
+ 0 An exception occurred while
+ processing an instruction at CS:IP
+ saved on stack
+
+
+9.2 Hardware Initiated Interrupts
+
+Hardware-initiated interrupts are caused by some external event that
+activates either the INTR or NMI input pins of the processor. Events that
+use the INTR input are classified as maskable interrupts. Events that use
+the NMI input are classified as non-maskable interrupts.
+
+All 224 user-defined interrupt sources share the INTR input, but each has
+the ability to use a separate interrupt handler. An 8-bit vector supplied by
+the interrupt controller identifies which interrupt is being signaled. To
+read the interrupt id, the processor performs the interrupt acknowledge bus
+sequence.
+
+Maskable interrupts (from the INTR input) can be inhibited by software by
+setting the interrupt flag bit (IF) to 0 in the flag word. The IF bit does
+not inhibit exceptions or interrupts caused by the INT instruction. The IF
+bit also does not inhibit processor extension interrupts.
+
+The type of gate placed into the IDT for the interrupt vector will control
+whether other maskable interrupts remain enabled or not during the servicing
+of that interrupt. The flag word that was saved on the stack reflects the
+maskable interrupt enable status of the processor prior to the interrupt.
+The procedure servicing a maskable interrupt can also prevent further
+maskable interrupts during its work by resetting the IF flag.
+
+Non-maskable interrupts are caused by the NMI input. They have a higher
+priority than the maskable interrupts (meaning that in case of simultaneous
+requests, the non-maskable interrupt will be serviced first). A non-maskable
+interrupt has a fixed vector (#2) and therefore does not require an
+interrupt acknowledge sequence on the bus. A typical use of an NMI is to
+invoke a procedure to handle a power failure or some other critical hardware
+exception.
+
+A procedure servicing an NMI will not be further interrupted by other
+non-maskable interrupt requests until an IRET instruction is executed. A
+further NMI request is remembered by the hardware and will be serviced after
+the first IRET instruction. Only one NMI request can be remembered. To
+prevent a maskable interrupt from interrupting the NMI interrupt handler,
+the IF flag should be cleared either by using an interrupt gate in the IDT
+or by setting IF = 0 in the flag word of the task involved.
+
+
+9.3 Software Initiated Interrupts
+
+Software initiated interrupts occur explicitly as interrupt instructions or
+may arise as the result of an exceptional condition that prevents the
+continuation of program execution. Software interrupts are not maskable. Two
+interrupt instructions exist which explicitly cause an interrupt: INT n and
+INT 3. The first allows specification of any interrupt vector; the second
+implies interrupt vector 3 (Breakpoint).
+
+Other instructions like INTO, BOUND, DIV, and IDIV may cause an interrupt,
+depending on the overflow flag or values of the operands. These instructions
+have predefined vectors associated with them in the first 32 interrupts
+reserved by Intel.
+
+A whole class of interrupts called exceptions are intended to detect faults
+or programming errors (in the use of operands or privilege levels).
+Exceptions cannot be masked. They also have fixed vectors within the first
+32 interrupts. Many of these exceptions pass an error code on the stack,
+which is not the case with the other interrupt types discussed in section
+9.2. Section 9.5 discusses these error codes as well as the priority among
+interrupts that can occur simultaneously.
+
+
+9.4 Interrupt Gates and Trap Gates
+
+Interrupt gates and trap gates are special types of descriptors that may
+only appear in the interrupt descriptor table. The difference between a trap
+and an interrupt gate is whether the interrupt enable flag is to be cleared
+or not. An interrupt gate specifies a procedure that enters with interrupts
+disabled (i.e., with the interrupt enable flag cleared); entry via a trap
+gate leaves the interrupt enable status unchanged. The NT flag is always
+cleared (after the old NT state is saved on the stack) when an interrupt
+uses these gates. Interrupts that have either gate in the associated IDT
+entry will be processed in the current task.
+
+Interrupts and trap gates have the same structure as the call gates
+discussed in section 7.5.1. The selector and entry point for a code segment
+to handle the interrupt or exception is contained in the gate. See figure
+9-3.
+
+The access byte contains the Present bit, the descriptor privilege level,
+and the type identifier. Bits 0-4 of the access byte have a value of 00110
+for interrupt gates, 00111 for trap gates. Byte 5 of the descriptor is not
+used by either of these gates; it is used only by the call gate, which uses
+it as the parameter word-count.
+
+Trap and interrupt gates allow a privilege level transition to occur when
+passing control to a non-conforming code segment. Like a call gate, the DPL
+of the target code segment selected determines the new CPL. The DPL of the
+new non-conforming code segment must be numerically less than or equal to
+CPL.
+
+No privilege transition occurs if the new code segment is conforming. If
+the DPL of the conforming code segment is greater than the CPL, a general
+protection exception will occur.
+
+As with all descriptors, these gates in the IDT carry a privilege level.
+The DPL controls access to interrupts with the INT n and INT 3 instructions.
+For access, the CPL of the program must be less than or equal to the gate
+DPL. If the CPL is not, a general protection exception will result with an
+error code identifying the selected IDT gate. For exceptions and external
+interrupts, the CPL of the program is ignored while accessing the IDT.
+
+Interrupts using a trap or an interrupt gate are handled in the same manner
+as an 8086 interrupt. The flags and return address of the interrupted
+program are saved on the stack of the interrupt handler. To return to the
+interrupted program, the interrupt handler executes an IRET instruction.
+
+If an increase in privilege is required for handling the interrupt, a new
+stack will be loaded from the TSS. The stack pointer of the old privilege
+level will also be saved on the new stack in the same manner as a call gate.
+Figure 9-4 shows the stack contents after an exception with an error code
+(with and without a privilege level change).
+
+If an interrupt or trap gate is used to handle an exception that passes an
+error code, the error code will be pushed onto the new stack after the
+return address (as shown in figure 9-4). If a task gate is used, the error
+code is pushed onto the stack of the new task. The return address is saved
+in the old TSS.
+
+If an interrupt gate is used to handle an interrupt, it is assumed that the
+selected code segment has sufficient privilege to re-enable interrupts. The
+IRET instruction will not re-enable interrupts if CPL is numerically greater
+than IOPL.
+
+Table 9-1 shows the checks performed during an interrupt operation that
+uses an interrupt or trap gate. EXT equals 1 when an event external to the
+program is involved; 0 otherwise. External events are maskable or
+non-maskable interrupts, single step interrupt, processor extension segment
+overrun interrupt, numeric processor not-present exception or numeric
+processor error. The EXT bit signals that the interrupt or exception is not
+related to the instruction at CS:IP. Each error code has bit 1 set to
+indicate an IDT entry is involved.
+
+When the interrupt has been serviced, the service routine returns control
+via an IRET instruction to the routine that was interrupted. If an error
+code was passed, the exception handler must remove the error code from the
+stack before executing IRET.
+
+The NT flag is cleared when an interrupt occurs which uses an interrupt or
+trap gate. Executing IRET with NT=0 causes the normal interrupt return
+function. Executing IRET with NT=1 causes a task switch (see section 8.4
+for more details).
+
+Like the RET instruction, IRET is restricted to return to a level of equal
+or lesser privilege unless a task switch occurs. The IRET instruction works
+like the inter-segment RET instruction except that the flag word is popped
+and no stack pointer update for parameters is performed since no parameters
+are on the stack. See section 7.5.2 for information on inter-level returns.
+
+To distinguish an inter-level IRET, the new CPL (which is the RPL of the
+return address CS selector) is compared with the current CPL. If they are
+the same, the IP and flags are popped and execution continues.
+
+An inter-level return via IRET has all the same checks as shown in table
+7-4. The only difference is the extra word on the stack for the old flag
+word.
+
+Interrupt gates are typically associated with high-priority hardware
+interrupts for automatically disabling interrupts upon their invocation.
+Trap gates are typically software-invoked since they do not disable the
+maskable hardware interrupts. However, low-priority interrupts (e.g., a
+timer) are often invoked via a trap gate to allow other devices of higher
+priority to interrupt the handler of that lower priority interrupt.
+
+Table 9-2 illustrates how the interrupt enable flag and interrupt type
+interact with the type of gate used.
+
+Table 9-1. Trap and Interrupt Gate Checks
+
+
+Check Exception
+GP = General Protection Exception
+NP = Not Present Exception
+SF = Stack Fault Error Code
+
+Interrupt vector GP IDT entry * 8 + 2 + EXT
+is in IDT limit
+
+Trap, Interrupt, or GP IDT entry * 8 + 2 + EXT
+Task Gate in IDT Entry
+
+If INT instruction, GP IDT entry * 8 + 2 + EXT
+gate DPL ≥ CPL
+
+P bit of gate is set NP IDT entry * 8 + 2 + EXT
+
+Code segment selector GP CS selector * 8 + EXT
+is in descriptor table limit
+
+CS selector refers GP CS selector * 8 + EXT
+to a code segment
+
+If code segment is GP CS selector * 8 + EXT
+non-conforming, Code
+Segment DPL ≤ CPL
+
+If code segment is TS SS selector * 8 + EXT
+non-conforming, and
+DPL < CPL and if
+SS selector in TSS
+is in descriptor
+table limit
+
+If code segment is TS SS selector * 8 + EXT
+non-conforming, and
+DPL < CPL and if
+SS is a writable
+data segment
+
+If code segment is TS Stack segment selector + EXT
+non-conforming, and
+DPL < CPL and
+code segment
+DPL = stack segment DPL
+
+If code segment is SF Stack segment selector + EXT
+non-conforming, and
+DPL < CPL and if
+SS is present
+
+If code segment is SF SS selector + EXT
+non-conforming, and
+DPL < CPL and if
+there is enough space
+for 5 words on the stack
+(or 6 if error code
+is required)
+
+If code segment is GP Code segment selector + EXT
+conforming, then DPL ≤CPL
+
+If code segment NP Code segment selector + EXT
+is not present
+
+If IP is not within GP 0 + EXT
+the limit of code segment
+
+
+Table 9-2. Interrupt and Gate Interactions
+
+Type of Type of Further Further Further Further software
+Interrupt Gate NMIs? INTRs? Exceptions? Interrupts?
+NMI Trap No Yes Yes Yes
+NMI Interrupt No No Yes Yes
+INTR Trap Yes Yes Yes Yes
+INTR Interrupt Yes No Yes Yes
+Software Trap Yes Yes Yes Yes
+Software Interrupt Yes No Yes Yes
+Exception Trap Yes Yes Yes Yes
+Exception Interrupt Yes No Yes Yes
+
+Figure 9-3. Trap/Interrupt Gate Descriptors
+
+ ╔═══════════════════════════════╤═══════════════════════════════╗
+ +7║ INTEL RESERVED
+ Must be set to 0 for compatibility with IAPX 386 ║+6
+ ╟───┬───────┬───┬───────────────┬───────────────────────────────╢
+ +5║ P │ DP2 │ 0 │ 0 1 1 T │ UNUSED ║+4
+ ╟───┴───┴───┴───┴───┴───┴───┴───┴───────────────────────────────╢
+ +3║ INTERRUPT CODE SEGMENT SELECTOR ║+2
+ ║───────────────────────────────────────────────────────────────║
+ +1║ INTERRUPT CODE OFFSET ║ 0
+ ╚═══════════════════════════════════════════════════════════════╝
+
+ T = 1 FOR TRAP GATE
+
+ T = 0 FOR INTERRUPT GATE
+
+
+Figure 9-4. Stack Layout after an Exception with an Error Code
+
+ OLD SP─────►╔════════════════╗ NO PRIVILEGE TRANSITION
+ ║ OLD FLAGS ║
+ ╟────────────────╢
+ ║ OLD CS ║
+ ╟────────────────╢
+ ║ OLD IP ║
+ ╟────────────────╢
+ ║ ERROR CODE ║
+ SP─────►╟────────────────╢
+ ║ ║
+ ║ ║
+ ≈ ≈
+ ║ ║
+ SS─────►╚════════════════╝
+
+ SP FROM TSS─ ─ ─►╔════════════════╗ WITH PRIVILEGE TRANSITION
+ ║ OLD SS ║
+ ╟────────────────╢
+ ║ OLD SP ║
+ ╟────────────────╢
+ ║ OLD FLAGS ║
+ ╟────────────────╢
+ ║ OLD CS ║
+ ╟────────────────╢
+ ║ OLD IP ║
+ ╟────────────────╢
+ ║ ERROR CODE ║
+ SP─────►╟────────────────╢
+ ║ ║
+ ║ ║
+ ≈ ≈
+ ║ ║
+ SP FROM TSS─────►╚════════════════╝
+ STACK SEGMENT
+
+
+9.5 Task Gates and Interrupt Tasks
+
+The 80286 allows interrupts to directly cause a task switch. When an
+interrupt vector selects an entry in the IDT which is a task gate, a task
+switch occurs. The format of a task gate is described in section 8.5. If a
+task gate is used to handle an exception that passes an error code, the
+error code will be pushed onto the new task's stack.
+
+A task gate offers two advantages over interrupt gates:
+
+ 1. It automatically saves all of the processor registers as part of the
+ task-switch operation, whereas an interrupt gate saves only the flag
+ register and CS:IP.
+
+ 2. The new task is completely isolated from the task that was
+ interrupted. Address spaces are isolated and the interrupt-handling
+ task is unaffected by the privilege level of the interrupted task.
+
+An interrupt task switch works like any other task switch once the TSS
+selector is fetched from the task gate. Like a trap or an interrupt gate,
+privilege and presence rules are applied to accessing a task gate during an
+interrupt.
+
+Interrupts that cause a task switch set the NT bit in the flags of the new
+task. The TSS selector of the interrupted task is saved in the back link
+field of the new TSS. The interrupting task executes IRET to perform a task
+switch to return to the interrupted task because NT was previously set. The
+interrupt task state is saved in its TSS before returning control to the
+task that was interrupted; NT is restored to its original value in the
+interrupted task.
+
+Since the interrupt handler state after executing IRET is saved, a re-entry
+of the interrupt service task will result in the execution of the
+instruction that follows IRET. Therefore, when the next interrupt occurs,
+the machine state will be the same as that when the IRET instruction was
+executed.
+
+Note that an interrupt task resumes execution each time it is re-invoked,
+whereas an interrupt procedure starts executing at the beginning of the
+procedure each time. The interrupted task restarts execution at the point of
+interruption because interrupts occur before the execution of an
+instruction.
+
+When an interrupt task is used, the task must be concerned with avoiding
+further interrupts while it is operating. A general protection exception
+will occur if a task gate referring to a busy TSS is used while processing
+an interrupt. If subsequent interrupts can occur while the task is
+executing, the IF bit in the flag word (saved in the TSS) must be zero.
+
+
+9.5.1 Scheduling Considerations
+
+A software-scheduled operating system must be designed to handle the fact
+that interrupts can come along in the middle of scheduled tasks and cause a
+task switch to other tasks. The interrupt-scheduled tasks may call the
+operating system and eventually the scheduler, which needs to recognize
+that the task that just called it is not the one the operating system last
+scheduled.
+
+If the Task Register (TR) does not contain the TSS selector of the last
+scheduled task, an interrupt initiated task switch has occurred. More than
+one task may have been interrupt-scheduled since the scheduler last ran. The
+scheduler must find via the backlink fields in each TSS all tasks that have
+been interrupted. The scheduler can clear those links and reset the busy bit
+in the TSS descriptors, putting them back in the scheduling queue for a new
+analysis of execution priorities. Unless the interrupted tasks are placed
+back in the scheduling queue, they would have to await a later restart via
+the task that interrupted them.
+
+To locate tasks that have been interrupt-scheduled, the scheduler looks
+into the current task's TSS backlink (word one of the TSS), which points at
+the interrupted task. If that task was not the last task scheduled, then
+it's backlink field in the TSS also points to an interrupted task.
+
+The backlink field of each interrupt-scheduled task should be set by the
+scheduler to point to a scheduling task that will reschedule the highest
+priority task when the interrupt-scheduled task executes IRET.
+
+
+9.5.2 Deciding Between Task, Trap, and Interrupt Gates
+
+Interrupts and exceptions can be handled with either a trap/interrupt gate
+or a task gate. The advantages of a task gate are all the registers are
+saved and a new set is loaded with full isolation between the interrupted
+task and the interrupt handler. The advantages of a trap/interrupt gate are
+faster response to an interrupt for simple operations and easy access to
+pointers in the context of the interrupted task. All interrupt handlers use
+IRET to resume the interrupted program.
+
+Trap/interrupt gates require that the interrupt handler be able to execute
+at the same or greater privilege level than the interrupted program. If any
+program executing at level 0 can be interrupted through a trap/task gate,
+the interrupt handler must also execute at level 0 to avoid general
+protection exception. All code, data, and stack segment descriptors must be
+in the GDT to allow access from any task. But, placing all system interrupt
+handlers at privilege level 0 may be in consistent with maintaining the
+integrity of level 0 programs.
+
+Some exceptions require the use of a task gate. The invalid task state
+segment exception (#10) can arise from errors in the original TSS as well as
+in the target TSS. Handling the exception within the same task could lead to
+recursive interrupts or other undesirable effects that are difficult to
+trace. The double fault exception (#8) should also use a task gate to
+prevent shutdown from another protection violation occurring during the
+servicing of the exception.
+
+
+9.6 Protection Exceptions and Reserved Vectors
+
+A protection violation will cause an exception, i.e., a non-maskable
+interrupt. Such a fault can be handled by the task that caused it if an
+interrupt or trap gate is used, or by a different task if a task gate is
+used (in the IDT).
+
+Protection exceptions can be classified into program errors or implicit
+requests for service. The latter include stack overflow and not-present
+faults. Examples of program errors include attempting to write into a
+read-only segment, or violating segment limits.
+
+Requests for service may use different interrupt vectors, but many diverse
+types of protection violation use the same general protection fault vector.
+Table 9-3 shows the reserved exceptions and interrupts. Interrupts 0-31 are
+reserved by Intel.
+
+When simultaneous external interrupt requests occur, they are processed in
+the fixed order shown in table 9-4. For each interrupt serviced, the
+machine state is saved. The new CS:IP is loaded from the gate or TSS. If
+other interrupts remain enabled, they are processed before the first
+instruction of the current interrupt handler, i.e., the last interrupt
+processed is serviced first.
+
+All but two exceptions are restartable after the exceptional condition is
+removed. The two non-restartable exceptions are the processor extension
+segment overrun and writing into read only segments with XCHG, ADC, SBB,
+RCL, and RCR instructions. The return address normally points to the failing
+instruction, including all leading prefixes.
+
+The instruction and data addresses for the processor extension segment
+overrun are contained in the processor extension status registers.
+
+Interrupt handlers for most exceptions receive an error code that
+identifies the selector involved, or a 0 in bits 15-3 of the error code
+field if there is no selector involved. The error code is pushed last,
+after the return address, on the stack that will be active when the trap
+handler begins execution. This ensures that the handler will not have to
+access another stack segment to find the error code.
+
+The following sections describe the exceptions in greater detail.
+
+
+Table 9-3. Reserved Exceptions and Interrupts
+
+Vector Description Restartable Code on
+Number Error Stack
+0 Divide Error Exception Yes No
+1 Single Step Interrupt Yes No
+2 NMI Interrupt Yes No
+3 Breakpoint Interrupt Yes No
+4 INTO Detected Overflow Exception Yes No
+5 BOUND Range Exceeded Exception Yes No
+6 Invalid Opcode Exception Yes No
+7 Processor Extension Not Available
+ Exception Yes No
+8 Double Exception Detected No Yes (Always 0)
+9 Processor Extension Segment Overrun
+ Interrupt No No
+10 Invalid Task State Segment Yes Yes
+11 Segment Not Present Yes Yes
+12 Stack Segment Overrun or Not Present Yes Yes
+13 General Protection Yes
+Except for writes into read-only segments (see section 9.6) Yes
+
+
+Table 9-4. Interrupt Processing Order
+
+Order Interrupt
+ 1 Instruction exception
+ 2 Single step
+ 3 NMI
+ 4 Processor extension segment overrun
+ 5 INTR
+
+
+9.6.1 Invalid OP-Code (Interrupt 6)
+
+When an invalid opcode is detected by the execution unit, interrupt 6 is
+invoked. (It is not detected until an attempt is made to execute it, i.e.,
+prefetching an invalid opcode does not cause this exception.) The saved
+CS:IP will point to the invalid opcode or any leading prefixes; no error
+code is pushed on the stack. The exception can be handled within the same
+task, and is restartable.
+
+This exception will occur for all cases of an invalid operand. Examples
+include an inter-segment jump referencing a register operand, or an LES
+instruction with a register source operand.
+
+
+9.6.2 Double Fault (Interrupt 8)
+
+If two separate faults occur during a single instruction, end if the first
+fault is any of #0, #10, #11, #12, and #13, exception 8 (Double Fault)
+occurs (e.g., a general protection fault in level 3 is followed by a
+not-present fault due to a segment not-present). If another protection
+violation occurs during the processing of exception 8, the 80286 enters
+shutdown, during which time no further instructions or exceptions are
+processed.
+
+Either NMI or RESET can force the CPU out of shutdown. An NMI input can
+bring the CPU out of shutdown if no errors occur while processing the NMI
+interrupt; otherwise, shutdown can only be exited via the RESET input. NMI
+causes the CPU to remain in protected mode, and RESET causes it to exit
+protected mode. Shutdown is signaled externally via a HALT bus operation
+with A1 LOW.
+
+A task gate must be used for the double fault handler to assure a proper
+task state to respond to the exception. The back link field in the current
+TSS will identify the TSS of the task causing the exception. The saved
+address will point at the instruction that was being executed (or was ready
+to execute) when the error was detected. The error code will be null.
+
+The "double fault" exception does not occur when detecting a new exception
+while trying to invoke handlers for the following exceptions: 1, 2, 3, 4, 5,
+6, 7, 9, and 16.
+
+
+9.6.3 Processor Extension Segment Overrun (Interrupt 9)
+
+Interrupt 9 signals that the processor extension (such as the 80287
+numerics processor) has overrun the limit of a segment while attempting to
+read/write the second or subsequent words of an operand. The interrupt is
+generated by the processor extension data channel within the 80286 during
+the limit test performed on each transfer of data between memory and the
+processor extension. This interrupt can be handled in the same task but is
+not restartable.
+
+As with all external interrupts, Interrupt 9 is an asynchronous demand
+caused by the processor extension referencing something outside a segment
+boundary. Since Interrupt 9 can occur any time after the processor extension
+is started, the 80286 does not save any information that identifies what
+particular operation had been initiated in the processor extension. The
+processor extension maintains special registers that identify the last
+instruction it executed and the address of the desired operand.
+
+After this interrupt occurs, no WAIT or escape instruction, except FNINIT,
+can be executed until the interrupt condition is cleared or the processor
+extension is reset. The interrupt signals that the processor extension is
+requesting an invalid data transfer. The processor extension will always be
+busy when waiting on data. Deadlock results if the CPU executes an
+instruction that causes it to wait for the processor extension before
+resetting the processor extension. Deadlock means the CPU is waiting for the
+processor extension to become idle while the processor extension waits for
+the CPU to service its data request.
+
+The FNINIT instruction is guaranteed to reset the processor extension
+without causing deadlock. After the interrupt is cleared, this restriction
+is lifted. It is then possible to read the instruction and operand address
+via FSTENV or FSAVE, causing the segment overrun in the processor
+extension's special registers.
+
+The task interrupted by interrupt 9 is not necessarily the task that
+executed the ESC instruction that caused the interrupt. The operating system
+should keep track of which task last used the NPX (see section 11.4). If
+the interrupted task did not execute the ESC instruction, it can be
+restarted. The task that executed the ESC instruction cannot.
+
+
+9.6.4 Invalid Task State Segment (Interrupt 10)
+
+Interrupt 10 is invoked if during a task switch the new TSS pointed to by
+the task gate is invalid. The EXT bit indicates whether the exception was
+caused by an event outside the control of the program.
+
+A TSS is considered invalid in the cases shown in table 9-5.
+
+Once the existence of the new TSS is verified, the task switch is
+considered complete, with the backlink set to the old task if necessary. All
+errors are handled in the context of the new task.
+
+Exception 10 must be handled through a task gate to insure a proper TSS to
+process it. The handler must reset the busy bit in the new TSS.
+
+
+9.6.5 Not Present (Interrupt 11)
+
+Exception 11 occurs when an attempt is made to load a not-present segment
+or to use a control descriptor that is marked not-present. (If, however, the
+missing segment is an LDT that is needed in a task switch, exception 10
+occurs.) This exception is fully restartable.
+
+Any segment load instruction can cause this exception. Interrupt 11 is
+always processed in the context of the task in which it occurs.
+
+The error code has the form shown in Table 9-5. The EXT bit will be set if
+an event external to the program caused an interrupt that subsequently
+referenced a not-present segment. Bit 1 will be set if the error code refers
+to an IDT entry, e.g., an INT instruction referencing a not-present gate.
+The upper 14 bits are the upper 14 bits of the segment selector involved.
+
+During a task switch, when a not-present exception occurs, the ES and DS
+segment registers may not be usable for referencing memory (the selector
+values are loaded before the descriptors are checked). The not-present
+handler should not rely on being able to use the values found in ES, SS,
+and DS without causing another exception. This is because the task switch
+itself may have changed the values in the registers. The exception occurs in
+the new task and the return pointer points to the first instruction of the
+new task. Caution: the loading of the DS or ES descriptors may not have
+been completed. The exception II handler should ensure that the DS and ES
+descriptors have been properly loaded before the execution of the first
+instruction of the new task.
+
+
+Table 9-5. Conditions That Invalidate the TSS
+
+Reason Error Code
+The limit in the TSS descriptor is less than 43 TSS id + EXT
+Invalid LDT selector or LDT not present LDT id + EXT
+Stack segment selector is null SS id + EXT
+Stack segment selector is outside table limit SS id + EXT
+Stack segment is not a writable segment SS id + EXT
+Stack segment DPL does not match new CPL SS id + EXT
+Stack segment selector RPL <> ECPL SS id + EXT
+Code segment selector is outside table limit CS id + EXT
+Code segment selector does not refer to code segment CS id + EXT
+Non-conforming code segment DPL <> ECPL CS id + EXT
+Conforming code segment DPL > CPL CS id + EXT
+DS or ES segment selector is outside table limits ES/DS id + EXT
+DS or ES are not readable segments ES/DS id + EXT
+
+
+9.6.6 Stack Fault (Interrupt 12)
+
+Stack underflow or overflow causes exception 12, as does a not-present
+stack segment referenced during an inter-task or inter-level transition.
+This exception is fully restartable. A limit violation of the current stack
+results in an error code of 0. The EXT bit of the error code tells whether
+an interrupt external to the program caused the exception.
+
+Any instruction that loads a selector to SS (e.g., POP SS, task switch) can
+cause this exception. This exception must use a task gate if there is a
+possibility that any level 0 stack may not be present.
+
+When a stack fault occurs, the ES and DS segment registers may not be
+usable for referencing memory. During a task switch, the selector values are
+loaded before the descriptors are checked. The stack fault handler should
+check the saved values of SS, CS, DS, and ES to be sure that they refer to
+present segments before restoring them.
+
+
+9.6.7 General Protection Fault (Interrupt 13)
+
+If a protection violation occurs which is not covered in the preceding
+paragraphs, it is classed as Interrupt 13, a general protection fault. The
+error code is zero for limit violations, write to read-only segment
+violations, and accesses relative to DS or ES when they are zero or refer
+to a segment at a greater privilege level than CPL. Other access violations
+(e.g., a wrong descriptor type) push a non-zero error code that identifies
+the selector used on the stack. Error codes with bit 0 cleared and bits
+15-2 non-zero indicate a restartable condition.
+
+Bit 1 of the error code identifies whether the selector is in the IDT or
+LDT/GDT. If bit 1 = 0 then bit 2 separates LDT from GDT. Bit 0 (EXT)
+indicates whether the exception was caused by the program or an event
+external to it (i.e., single stepping, an external interrupt, a processor
+extension not-present or a segment overrun). If bit 0 is set, the selector
+typically has nothing to do with the instruction that was interrupted. The
+selector refers instead to some step of servicing an interrupt that failed.
+
+When bit 0 of the error code is set, the interrupted program can be
+restarted, except for processor extension segment overrun exceptions (see
+section 9.6.3). The exception with the bit 0 of the errorcode = 1 indicates
+some interrupt has been lost due to a fault in the descriptor pointed to by
+the error code.
+
+A non-zero error code with bit 0 cleared may be an operand of the
+interrupted instruction, an operand from a gate referenced by the
+instruction, or a field from the invalid TSS.
+
+During a task switch, when a general protection exception occurs, the ES
+and DS segment registers may not be usable for referencing memory (the
+selector vaues are loaded before the descriptors are checked). The general
+protection handler should not rely on being able to use the values found in
+ES, SS, and DS without causing another exception. This is because the task
+switch itself may have changed the values in the registers. The exception
+occurs in the new task and the return pointer points to the first
+instruction of the new task. Caution: the loading of the DS or ES
+descriptors may not have been completed. The exception 13 handler should
+ensure that the DS and ES descriptors have been properly loaded before the
+execution of the first instruction of the new task.
+
+In Real Address Mode, Interrupt 13 will occur if software attempts to read
+or write a 16-bit word at segment offset 0FFFFH.
+
+
+9.7 Additional Exceptions and Interrupts
+
+Interrupts 0, 5, and 1 have not yet been discussed. Interrupt 0 is the
+divide-error exception, Interrupt 5 the bound-range exceeded exceptions, and
+Interrupt 1 the single step interrupt. The divide-error or bound-range
+exceptions make it appear as if that instruction had never executed: the
+registers are restored and the instruction can be restarted. The
+divide-error exception occurs during a DIV or an IDIV instruction when the
+quotient will be too large to be representable, or when the divisor is
+zero.
+
+Interrupt 5 occurs when a value exceeds the limit set for it. A program can
+use the BOUND instruction to check a signed array index against signed
+limits defined in a two-word block of memory. The block can be located just
+before the array to simplify addressing. The block's first word specifies
+the array's lower limit, the second word specifies the array's upper limit,
+and a register specifies the array index to be tested.
+
+
+9.7.1 Single Step Interrupt (Interrupt 1)
+
+Interrupt 1 allows programs to execute one instruction at a time. This
+single-stepping is controlled by the TF bit in the flag word. Once this bit
+is set, an internal single step interrupt will occur after the next
+instruction has been executed. The interrupt saves the flags and return
+address on the stack, clears the TF bit, and uses an internally supplied
+vector of 1 to transfer control to the service routine via the IDT.
+
+The IRET instruction or a task switch must be used to set the TF bit and to
+transfer control to the next instruction to be single stepped. If TF=1 in a
+TSS and that task is invoked, it will execute the first instruction and then
+be interrupted.
+
+The single-step flag is normally not cleared by privilege changes inside a
+task. INT instructions, however, do clear TF. Therefore, software debuggers
+that single-step code must recognize and emulate INT n or INT 0 rather than
+executing them directly. System software should check the current execution
+privilege level after any single step interrupt to see whether single
+stepping should continue.
+
+The interrupt priorities in hardware guarantee that if an external
+interrupt occurs, single stepping stops. When both an external interrupt and
+a single step interrupt occur together, the single step interrupt is
+processed first. This clears the TF bit. After saving the return address or
+switching tasks, the external interrupt input is examined before the first
+instruction of the single step handler executes. If the external interrupt
+is still pending, it is then serviced. The external interrupt handler is
+not single-stepped. Therefore, to single step an interrupt handler, just
+single step an interrupt instruction that refers to the interrupt handler.
+
+
+Chapter 10 System Control and Initialization
+
+───────────────────────────────────────────────────────────────────────────
+
+Special flags, registers, and instructions provide contol of the critical
+processes and interaction in 80286 operations. The flag register includes 3
+bits that represent the current I/O privilege level (IOPL: 2 bits) and the
+nested task bit (NT). Four additional registers support the virtual
+addressing and memory protection features, one points to the current Task
+State Segment and the other three point to the memory-based descriptor
+tables: GDT, LDT, and IDT. These flags and registers are discussed in the
+next section. The machine status word, (which indicates processor
+configuration and status) and the instructions that load and store it are
+discussed in section 10.2.1.
+
+Similar instructions pertaining to the other registers are the subject of
+sections 10.2 and 10.3. A detailed description of initialization states
+and processes, which appears in section 10.4, is supplemented by the
+extensive example in Appendix A. Instructions that validate descriptors
+and pointers are covered in section 11.3.
+
+
+10.1 System Flags and Registers
+
+The IOPL flag (bits 12 and 13 of the flags word) controls access to I/O
+operations and interrupt control instructions. These two bits represent the
+maximum privilege level (highest numerical CPL) at which the task is
+permitted to perform I/O instructions. Alteration of the IOPL flags is
+restricted to programs at level 0 or to a task switch.
+
+IRET uses the NT flag to select the proper return: if NT=0, the normal
+return within a task is performed. As discussed in Chapter 8, the nested
+task flag (bit 14 of flags) is set when a task initiates a task switch via a
+CALL or INT instruction. The old and new task state segments are marked
+busy and the backlink field of the new TSS is set to the old TSS selector.
+An interrupt that does not cause a task switch will clear NT after the old
+NT state is saved. To prevent a program from causing an illegal task switch
+by setting NT and then executing IRET, a zero selector should be placed in
+the backlink field of the TSS. An illegal task switch using IRET will then
+cause exception 13. The instructions POPF and IRET can also set or clear NT
+when flags are restored from the stack. POPF and IRET can also change the
+interrupt enable flag. If CPL ≤ IOPL, then the Interrupt Flag (IF) can be
+changed by POPF and IRET. Otherwise, the state of the IF bit in the new
+flag word is ignored by these instructions. Note that the CLI and STI
+instructions are valid only when CPL ≤ IOPL; otherwise exception 13 occurs.
+
+
+10.1.1 Descriptor Table Registers
+
+The three descriptor tables used for all memory accesses are based at
+addresses supplied by (stored in) three registers: the global descriptor
+table register (GDTR), the interrupt descriptor table register (IDTR), and
+the local descriptor table register (LDTR). Each register contains a 24-bit
+base field and a 16-bit limit field. The base field gives the real memory
+address of the beginning of the table; the limit field tells the maximum
+offset permitted in accessing table entries. See figures 10-1, 10-2, and
+10-3.
+
+The LDTR also contains a selector field that identifies the descriptor for
+that table. LDT descriptors must reside in the GDT.
+
+The task register (TR) points to the task state segment for the currently
+active task. It is similar to a segment register, with selector, base, and
+limit fields, of which only the selector field is readable under normal
+circumstances. Each such selector serves as a unique identifier for its
+task. The uses of the TR are described in Chapter 8.
+
+The instructions controlling these special registers are described in the
+next section.
+
+
+Figure 10-1. Local and Global Descriptor Table Definition
+
+ MEMORY
+ • •
+ ┌─┬───►╟───────────────╢─┐
+ │ ╟───────────────╢ │
+ CPU │ │ ╟───────────────╢ │
+ ╔═════════════════════╗ │ ║ ∙ ║ │
+ ║ ║ │ │ ║ ∙ ║ ├─ GDT
+ ║ 15 0 ║ │ ║ ∙ ║ │
+ ║ ╔═════════╗ ║ │ │ ╟───────────────╢ │
+ ║ 23 ║LDT LIMIT╟───╫─┘ ╟───────────────╢ │
+ ║ ╔═══╨─────────╢ ║ │ ╟───────────────╢ │
+ GDTR ║ ║ GDT BASE ╟───╫───────►╟───────────────╢─┘
+ ║ ╚═════════════╝ ║ ║ ║
+ ║ ║ ║ ║
+ ╟─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╢ ║ ║
+ ║ ║ ║ LDT{1} ║
+ ║ 15 0 ║ ┌─┬───►╟───────────────╢─┐
+ ║ ╔══════════╗ ║ │ ╟───────────────╢ │
+ ║ ║ LDT ║ ║ │ │ ╟───────────────╢ │
+ ║ ║ SELECTOR ║ ║ │ ║ ∙ ║ │
+ ║ ╚══════════╝ ║ │ │ ║ ∙ ║ ├─ CURRENT LDT
+ ║┌─ ── ── ── ── ── ──┐║ │ ║ ∙ ║ │
+ ║│ 15 0 │║ │ │ ╟───────────────╢ │
+ ║ ╔═════════╗ ║ │ ╟───────────────╢ │
+ ║│ 23 ║LDT LIMIT╟──┼╫─┘ │ ╟───────────────╢ │
+ ║ ╔═══╨─────────╢ ║ ┌────►╟───────────────╢─┘
+ LDTR ║│ ║ LDT BASE ╟──┼╟──┘ ║ ║
+ ║ ╚═════════════╝ ║ ║ ║
+ ║│ PROGRAM INVISIBLE │║ ║ ║
+ ║└─ ── ── ── ── ── ──┘║ ║ LDT{n} ║
+ ╚═════════════════════╝ ╟───────────────╢
+ ╟───────────────╢
+ ╟───────────────╢
+ ╟───────────────╢
+ ║ ∙ ║
+ ║ ∙ ║
+ ║ ∙ ║
+ ╟───────────────╢
+ ╟───────────────╢
+ ╟───────────────╢
+ ╟───────────────╢
+ ╟───────────────╢
+ • •
+
+
+Figure 10-2. Interrupt Descriptor Table Definition
+
+ MEMORY
+ • •
+ ║ ║
+ ┌───┬─►╠═══════════════╣─┐
+ │ ║ GATE FOR ║ │
+ │ │ ║ INTERRUPT #n ║ │
+ │ ╠═══════════════╣ │
+ │ │ ║ GATE FOR ║ │
+ │ ║INTERRUPT #n-1 ║ │
+ │ │ ╠═══════════════╣ │
+ │ ║ ∙ ║ │ INTERRUPT
+ │ │ ║ ∙ ║ ├─ DESCRIPTOR
+ │ ║ ∙ ║ │ TABLE (IDT)
+ CPU │ │ ╠═══════════════╣ │
+ ┌───────────────────┐ │ ║ GATE FOR ║ │
+ │ 15 0 │ │ │ ║ INTERRUPT #1 ║ │
+ │ ╔═════════╗ │ │ ╠═══════════════╣ │
+ │ ║IDT LIMIT╟──┼─┘ │ ║ GATE FOR ║ │
+ │ ╔═══╨─────────╢ │ ║ INTERRUPT #0 ║ │
+ IDTR │ ║ IDT BASE ╟──┼─────┴─►╠═══════════════╣─┘
+ │ ╚═════════════╝ │ ║ ║
+ │ 23 0 │ • •
+ └───────────────────┘
+
+
+Figure 10-3. Data Type for Global Descriptor Table and
+ Interrupt Descriptor Table
+
+ 7 0 7 0
+ ╔═══════════════════════════════╤═══════════════════════════════╗
+ +5║ INTEL RESERVED
+Must be set to 0 for compatibility with the 80386 │ BASE{23-16} ║+4
+ ╟───────────────────────────────┴───────────────────────────────╢
+ +3║ BASE{15-0} ║+2
+ ╟───────────────────────────────┴───────────────────────────────╢
+ +1║ LIMIT{15-0} ║ 0
+ ╚═══════════════════════════════╧═══════════════════════════════╝
+ 0
+
+
+10.2 System Control Instructions
+
+The instructions that load the GDTR and IDTR from memory can only be
+executed in real address mode or at privilege level 0; otherwise exception
+13 occurs. The store instructions for GDTR and IDTR may be executed at any
+privilege level. The four instructions are LIDT, LGDT, SIDT, and SGDT. The
+instructions move 3 words between the indicated descriptor table register
+and the effective real memory address supplied (see figure 10-3). The
+format of the 3 words is: a 2-byte limit, a 3-byte real base address,
+followed by an unused byte. These instructions are normally used during
+system initialization.
+
+The LLDT instruction loads the LDT registers from a descriptor in the GDT.
+LLDT uses a selector operand to that descriptor rather than referencing the
+descriptor directly. LLDT is only executable at privilege level 0; otherwise
+exception 13 occurs. LLDT is normally required only during system
+initialization because the processor automatically exchanges the LDTR
+contents as part of the task-switch operation.
+
+Executing an LLDT instruction does not automatically update the TSS or the
+register caches. To properly change the LDT of the currently running task so
+that the change holds across task switches, you must perform, in order, the
+following three steps:
+
+ 1. Store the new LDT selector into the appropriate word of TSS.
+ 2. Load the new LDT selector into LDTR.
+ 3. Reload the DS and ES registers if they refer to LDT-based
+ descriptors.
+
+Note that the current code segment and stack segment descriptors should
+reside in the GDT or be copied to the same location in the new LDT.
+
+SLDT (store LDT) can be executed at any privilege level. SLDT stores the
+local descriptor table selector from the program visible portion of the LDTR
+register.
+
+Task Register loading or storing is again similar to that of the LDT. The
+LTR instruction, operating only at level 0, loads the LTR at initialization
+time with a selector for the initial TSS. LTR does NOT cause a task switch;
+it just changes the current TSS. Note that the busy bit of the old TSS
+descriptor is not changed while the busy bit of the new TSS selector must be
+zero and will be set by LTR. The LDT and any segment registers referring to
+the old LDT should be reloaded. STR, which permits the storing of TR
+contents into memory, can be executed at any privilege level. LTR is not
+usually needed after initialization because the TR is managed by the
+task-switch operation.
+
+
+10.2.1 Machine Status Word
+
+The Machine Status Word (MSW) indicates the 80286 configuration and status.
+It is not part of a task's state. The MSW word is loaded by the LMSW
+instruction executed in real address mode or at privilege level 0 only, or
+is stored by the SMSW instruction executing at any privilege level. MSW is a
+16-bit register, the lower four bits of which are used by the 80286. These
+bits have the meanings shown in table 10-1. Bits 15-4 of the MSW will be
+used by the 80386. 80286 software should not change these bits. If the bits
+are changed by the 286 software, compatibility with the 80386 will be
+destroyed.
+
+The TS flag is set under hardware control and reset under software control.
+Once the TS flag is set, the next instruction using a processor extension
+causes a processor extension not-present exception (#7). This feature allows
+software to test whether the current processor extension state belongs to
+the current task as discussed in section 11.4. If the current processor
+extension state belongs to a different task, the software can save the state
+of any processor extension with the state of the task that uses it. Thus,
+the TS bit protects a task from processor extension errors that result from
+the actions of a previous task.
+
+The CLTS instruction is used to reset the TS flag after the exception
+handler has set up the proper processor extension state. The CLTS
+instruction can be executed at privilege level 0 only.
+
+The EM flag indicates a processor extension function is to be emulated by
+software. If EM=1 and MP=0, all ESCAPE instructions will be trapped via the
+processor extension not-present exception (#7).
+
+MP flag tells whether a processor extension is present. If MP=1 and TS=1,
+escape and wait instructions will cause exception 7.
+
+If ESC instructions are to be used, either the MP or the EM bit must be
+set, but not both.
+
+The PE flag indicates that the 80286 is in the protected virtual address
+mode. Once the PE flag is set, it can be cleared only by a reset, which then
+puts the system in real address mode emulating the 8086.
+
+Table 10-2 shows the recommended usage of the MSW. Other encodings of
+these bits are not recommended.
+
+Table 10-1. MSW Bit Functions
+
+Bit
+Position Name Function
+0 PE Protected mode enable places the 80286 into protected
+ mode and cannot be cleared except by RESET.
+
+1 MP Monitor processor extension allows WAIT instructions to
+ cause a processor extension not-present exception
+ (number 7) if TS is also set.
+
+2 EM Emulate processor extension causes a processor
+ extension not-present exception (number 7) on
+ ESC instructions to allow a processor extension to
+ be emulated.
+
+3 TS Task switched indicates the next instruction using a
+ processor extension will cause exception 7, allowing
+ software to test whether the current processor
+ extension context belongs to the current task.
+
+
+Table 10-2. Recommended MSW Encodings for Processor Extension Control
+
+
+TS MP EM Recommended Use Instructions
+ Causing
+ Exception
+0 0 0 Initial encoding after RESET. 80286 operation
+ is identical to 8086, 8088. Use this encoding
+ only if no ESC instructions are to be executed. None
+
+0 0 1 No processor extension is available. Software
+ will emulate its function. Wait instructions do
+ not cause exception 7. ESC
+
+1 0 1 No processor extension is available. Software
+ will emulate its function. The current processor
+ extension context may belong to another task. ESC
+
+0 1 0 A processor extension exists. WAIT (if TS=1)
+
+1 1 0 A processor extension exists. The current
+ processor extension context may belong to
+ another task. The exception on WAIT allows
+ software to test for an error pending from a
+ previous processor extension operation. ESC or
+ WAIT (if TS=1)
+
+
+10.2.2 Other Instructions
+
+Instructions that verify or adjust access rights, segment limits, or
+privilege levels can be used to avoid exceptions or faults that are
+correctable. Section 10.3 describes such instructions.
+
+
+10.3 Privileged and Trusted Instructions
+
+Instructions that execute only at CPL=0 are called "privileged." An attempt
+to execute the privileged instructions at any other privilege level causes a
+general protection exception (#13) with an error code of zero. The
+privileged instructions manipulate descriptor tables or system registers.
+Incorrect use of these instructions can produce unrecoverable conditions.
+Some of these instructions (LGDT, LLDT, and LTR) are discussed in section
+10.2.
+
+Other privileged instructions are:
+
+ ■ LIDT──Load interrupt descriptor table register
+ ■ LMSW──Load machine status word
+ ■ CLTS──Clear task switch flag
+ ■ HALT──Halt processor execution
+ ■ POPF (POP flags) or IRET can change the IF value only if the user is
+ operating at a trusted privilege level. POPF does not change IOPL
+ except at Level 0.
+
+"Trusted" instructions are restricted to execution at a privilege level of
+CPL ≥ IOPL. For each task, the operating system defines a privilege level
+below which these instructions cannot be used. Most of these instructions
+deal with input/output or interrupt management. The IOPL field in the flag
+word that holds the privilege level limit can be changed only when CPL=0.
+The trusted instructions are:
+
+ ■ Input/Output──Block I/O, Input, and Output: IN, INW, OUT, OUTW, INSB,
+ INSW, OUTSB, OUTSW
+
+ ■ Interrupts──Enable Interrupts, Disable Interrupts: STI, CLI
+
+ ■ Other──Lock Prefix
+
+
+10.4 Initialization
+
+Whenever the 80286 is initialized or reset, certain registers are set to
+predefined values. All additional desired initialization must be performed
+by user software. (See Appendix A for an example of a 286 initialization
+routine.) RESET forces the 80286 to terminate all execution and local bus
+activity; no instruction or bus action will occur as long as RESET is
+active. Execution in real address mode begins after RESET becomes inactive
+and an internal processing interval (3-4 clocks) occurs. The initial state
+at reset is:
+
+ FLAGS = 0002
+ MSW = FFF0H
+ IP = FFF0H
+ CS Selector = F000H CS.base = FF0000H CS.limit = FFFFH
+ CS Selector = 0000H CS.base = 000000H CS.limit = FFFFH
+ ES Selector = 0000H ES.base = 000000H ES.limit = FFFFH
+ IDT base = 000000H IDT.limit = 03FFH
+
+Two fixed areas of memory are reserved: the system initialization area and
+the interrupt table area. The system initialization area begins at FFFFF0H
+(through FFFFFFH) and the interrupt table area begins at 000000H (through
+0003FFH). The interrupt table area is not reserved.
+
+At this point, segment registers are valid and protection bits are set to
+0. The 80286 begins operation in real address mode, with PE=0. Maskable
+interrupts are disabled, and no processor extension is assumed or emulated
+(EM=MP=0).
+
+DS, ES, and SS are initialized at reset to allow access to the first 64K of
+memory (exactly as in the 8086). The CS:IP combination specifies a starting
+address of FFFF0H. For real address mode, the four most significant bits are
+not used, providing the same FFF0H address as the 8086 reset location. Use
+of (or upgrade to) the protected mode can be supported by a bootstrap
+loader at the high end of the address space. As mentioned in Chapter 5,
+location FFF0H ordinarily contains a JMP instruction whose target is the
+actual beginning of a system initialization or restart program.
+
+After RESET, CS points to the top 64K bytes in the 16-Mbyte physical
+address space. Reloading CS register by a control transfer to a different
+code segment in real address mode will put zeros in the upper 4 bits. Since
+the initial IP is FFF0H, all of the upper 64K bytes of address space may be
+used for initialization.
+
+Sections 10.4.1 and 10.4.2 describe the steps needed to initialize the
+80286 in the real address mode and the protected mode, respectively.
+
+
+10.4.1 Real Address Mode
+
+ 1. Allocate a stack.
+
+ 2. Load programs and data into memory from secondary storage.
+
+ 3. Initialize external devices and the Interrupt Vector Table.
+
+ 4. Set registers and MSW bits to desired values.
+
+ 5. Set FLAG bits to desired values──including the IF bit to enable
+ interrupts──after insuring that a valid interrupt handler exists for
+ each possible interrupt.
+
+ 6. Execute (usually via an inter-segment JMP to the main system
+ program).
+
+
+10.4.2 Protected Mode
+
+The full 80286 virtual address mode initialization procedure requires
+additional steps to operate correctly:
+
+ 1. Load programs and associated descriptor tables.
+
+ 2. Load valid GDT and IDT descriptor tables, setting the GDTR and IDTR to
+ their correct value.
+
+ 3. Set the PE bit to enter protected mode.
+
+ 4. Execute an intra-segment JMP to clear the processor queues.
+
+ 5. Load or construct a valid task state segment for the initial task to
+ be executed in protected mode.
+
+ 6. Load the LDTR selector from the task's GDT or 0000H (null) if an LDT
+ is not needed.
+
+ 7. Set the stack pointer (SS, SP) to a valid location in a valid stack
+ segment.
+
+ 8. Mark all items not in memory as not-present.
+
+ 9. Set FLAGS and MSW bits to correct values for the desired system
+ configuation.
+
+ 10. Initialize external devices.
+
+ 11. Ensure that a valid interrupt handler exists for each possible
+ interrupt.
+
+ 12. Enable interrupts.
+
+ 13. Execute.
+
+The example in Appendix A shows the steps necessary to load all the
+required tables and registers that permit execution of the first task of a
+protected mode system. The program in Appendix A assumes that Intel
+development tools have been used to construct a prototype GDT, IDT, LDT,
+TSS, and all the data segments necessary to start up that first task.
+Typically, these items are stored on EPROM; on most systems it is necessary
+to copy them all into RAM to get going. Otherwise, the 80286 will attempt to
+write into the EPROM to set the accessed or busy bits.
+
+The example in Appendix A also illustrates the ability to allocate unused
+entries in descriptor tables to grow the tables dynamically during
+execution. Using suitable naming conventions, the builder can allocate alias
+data segments that are larger than the prototype EPROM version. The code in
+the example will zero out the extra entries to permit later dynamic usage.
+
+
+Chapter 11 Advanced Topics
+
+───────────────────────────────────────────────────────────────────────────
+
+This chapter describes some of the advanced topics as virtual memory
+management, restartable instructions, special segment attributes, and the
+validation of descriptors and pointers.
+
+
+11.1 Virtual Memory Management
+
+When access to a segment is requested and the access byte in its descriptor
+indicates the segment is not present in real memory, the not-present fault
+occurs (exception 11, or 12 for stacks). The handler for this fault can be
+set up to bring the absent segment into real memory (swapping or
+overwriting another segment if necessary), or to terminate execution of the
+requesting program if this is not possible.
+
+The accessed bit (bit 0) of the access byte is provided in both executable
+and data segment descriptors to support segment usage profiling. Whenever
+the descriptor is accessed by the 80286 hardware, the A-bit will be set in
+memory. This applies to selector test instructions (described below) as
+well as to the loading of a segment register. The reading of the access byte
+and the restoration of it with the A-bit set is an indivisible operation,
+i.e., it is performed as a read-modify-write with bus lock. If an operating
+system develops a profile of segment usage over time, it can recognize
+segments of low or zero access and choose among these candidates for
+replacement.
+
+When a not-present segment is brought into real memory, the task that
+requested access to it can continue its execution because all instructions
+that load a segment register are restartable.
+
+Not-present exceptions occur only on segment register load operations, gate
+accesses, and task switches. The saved instruction pointer refers to the
+first byte of the violating instruction. All other aspects of the saved
+machine state are exactly as they were before execution of the violating
+instruction began. After the fault handler clears up the fault condition and
+performs an IRET, the program continues to execute. The only external
+indication of a segment swap is the additional execution time.
+
+
+11.2 Special Segment Attributes
+
+
+11.2.1 Conforming Code Segments
+
+Code segments intended for use at potentially different privilege levels
+need an attribute that permits them to emulate the privilege level of the
+calling task. Such segments are termed "conforming" segments. Conforming
+segments are also useful for interrupt-driven error routines that need only
+be as privileged as the routine that caused the error.
+
+A conforming code segment has bit 2 of its access byte set to 1. This means
+it can be referenced by a CALL or JMP instruction in a task of equal or
+lesser privilege, i.e., CPL of the task is numerically greater than or equal
+to DPL of this segment. CPL does not change when executing the conforming
+code segment. A conforming segment continues to use the stack from the CPL.
+This is the only case in which the DPL of a code segment can be numerically
+less than the CPL. If bit 2 is a 0, the segment is not conforming and can be
+referenced only by a task of CPL = DPL.
+
+Inter-segment Returns that refer to conforming code segments use the RPL
+field of the code selector of the return address to determine the new CPL.
+The RPL becomes the new CPL if the conforming code segment DPL ≤ RPL.
+
+If a conforming segment is readable, it can be read from any privilege
+level without restriction. This is the only exception to the protection
+rules. This allows constants to be stored with conforming code. For example,
+a read-only look-up table can be embedded in a conforming code segment that
+can be used to convert system-wide logical ID's into character strings that
+represent those logical entities.
+
+
+11.2.2 Expand-Down Data Segments
+
+If bit 2 in the access byte of a data segment is 1, the segment is an
+expand-down segment. All the offsets that reference such a segment must be
+strictly greater than the segment limit, as opposed to normal data segments
+(bit 2 = 0) where all offsets must be less than or equal to the segment
+limit. Figure 11-1 shows an expand-down segment.
+
+The size of the expand down segment can be changed by changing either the
+base or the limit. An expand down segment with Limit = 0 will have a size of
+2^(16)-1 bytes. With a limit value of FFFFH, the expand down segment
+will have a size of 0 bytes. In an expand down segment, the base + offset
+value should always be greater than the base + limit value. Therefore, a
+full size segment (2^(16) bytes) can only be obtained by using an expand up
+segment.
+
+The operating system should check the Expand-Down bit when a protection
+fault indicates that the limit of a data segment has been reached. If the
+Expand-Down bit is not set, the operating system should increase the segment
+limit; if it is set, the limit should be lowered. This supplies more room
+in either case (assuming the segment is not write-protected, i.e., that bit
+1 is not 0). In some cases, if the operating system can ascertain that there
+is not enough room to expand the data segment to meet the need that caused
+the fault, it can move the data segment to a region of memory where there
+is enough room. See figure 11-2.
+
+
+Figure 11-1. Expand-Down Segment
+
+ ║ ║
+ ║ ║
+ ║ ║
+ BASE + FFFEH ────►╟─────────────╢─┐
+ ║▒▒▒▒▒▒▒▒▒▒▒▒▒║ │
+ ║▒▒▒▒▒▒▒▒▒▒▒▒▒║ │
+ ║▒▒▒▒▒▒▒▒▒▒▒▒▒║ │
+ ║▒▒▒▒▒▒▒▒▒▒▒▒▒║ │
+ BASE + OFFSET ────►║▒▒▒▒▒▒▒▒▒▒▒▒▒║ ├─ EXPAND DOWN
+ >BASE + LIMIT ║▒▒▒▒▒▒▒▒▒▒▒▒▒║ │ SEGMENT
+ ║▒▒▒▒▒▒▒▒▒▒▒▒▒║ │
+ ║▒▒▒▒▒▒▒▒▒▒▒▒▒║ │
+ ║▒▒▒▒▒▒▒▒▒▒▒▒▒║ │
+ BASE + LIMIT ────►╟─────────────╢─┘
+ ║ ║
+ ║ ║
+ ║ ║
+ ║ ║
+ ────►║── ── ── ── ─║
+ ║ ║
+
+
+Figure 11-2. Dynamic Segment Relocation and Expansion of Segment Limit
+
+
+ ║▒▒▒▒▒▒▒▒▒▒▒▒▒║ ║▒▒▒▒▒▒▒▒▒▒▒▒▒║
+ ║▒▒▒▒▒▒▒▒▒▒▒▒▒║ ║▒▒▒▒▒▒▒▒▒▒▒▒▒║
+ ║▒▒▒▒▒▒▒▒▒▒▒▒▒║ BASE + 10000H───►╟─────────────╢
+ ║▒▒▒▒▒▒▒▒▒▒▒▒▒║ ║ ║
+ ║ ║ ║ STACK ║
+ ║ SEG. B ║ ║ ║
+ ║ ║ ║ ║
+ BASE + 10000H───►╟─────────────╢ NEW BASE───►╟─────────────╢
+ ║ ║ + NEW LIMIT ║ SEG. B ║
+ ║ STACK ║ ║ ║
+ ║ ║ NEW BASE───►║▒▒▒▒▒▒▒▒▒▒▒▒▒║
+ ║ ║ ║▒▒▒▒▒▒▒▒▒▒▒▒▒║
+ OLD BASE───►╟─────────────╢ ║▒▒▒▒▒▒▒▒▒▒▒▒▒║
+ + OLD LIMIT ║ ║ ║ ║
+ ║ SEG. A ║ ║ SEG. A ║
+ ║ ║ ║ ║
+ OLD BASE───►║▒▒▒▒▒▒▒▒▒▒▒▒▒║ ║▒▒▒▒▒▒▒▒▒▒▒▒▒║
+ ║▒▒▒▒▒▒▒▒▒▒▒▒▒║ ║▒▒▒▒▒▒▒▒▒▒▒▒▒║
+ ║▒▒▒▒▒▒▒▒▒▒▒▒▒║ ║▒▒▒▒▒▒▒▒▒▒▒▒▒║
+ ║▒▒▒▒▒▒▒▒▒▒▒▒▒║ ║▒▒▒▒▒▒▒▒▒▒▒▒▒║
+
+
+11.3 Pointer Validation
+
+Pointer validation is an important part of locating programming errors.
+Pointer validation is necessary for maintaining isolation between the
+privilege levels. Pointer validation consists of the following steps:
+
+ 1. Check if the supplier of the pointer is entitled to access the
+ segment.
+
+ 2. Check if the segment type is appropriate to its intended use.
+
+ 3. Check if the pointer violates the segment limit.
+
+The 80286 hardware automatically performs checks 2 and 3 during instruction
+execution, while software must assist in performing the first check. This
+point is discussed in section 11.3.2. Software can explicitly perform steps
+2 and 3 to check for potential violations (rather than causing an
+exception). The unprivileged instructions LSL, LAR, VERR, and VERW are
+provided for this purpose.
+
+The load access rights (LAR) instruction obtains the access rights byte of
+a descriptor pointed to by the selector used in the instruction. If that
+selector is visible at the CPL, the instruction loads the access byte into
+the specified destination register as the higher byte (the low byte is
+zero) and the zero flag is set. Once loaded, the access bits can be tested.
+System segments such as a task state segment or a descriptor table cannot be
+read or modified. This instruction is used to verify that a pointer refers
+to a segment of the proper privilege level and type. If the RPL or CPL is
+greater than DPL, or the selector is outside the table limit, no access
+value is returned and the zero flag is cleared. Conforming code segments may
+be accessed from any RPL or CPL.
+
+Additional parameter checking can be performed via the load segment limit
+(LSL) instruction. If the descriptor denoted by the given selector (in
+memory or a register) is visible at the CPL, LSL loads the specified
+register with a word that consists of the limit field of that descriptor.
+This can only be done for segments, task state segments, and local
+descriptor tables (i.e., words from control descriptors are inaccessible).
+Interpreting the limit is a function of the segment type. For example,
+downward expandable data segments treat the limit differently than code
+segments do.
+
+For both LAR and LSL, the zero flag (ZF) is set if the loading was
+performed; otherwise, the zero flag is cleared. Both instructions are
+undefined in real address mode, causing an invalid opcode exception
+(interrupt #6).
+
+
+11.3.1 Descriptor Validation
+
+The 80286 has two instructions, VERR and VERW, which determine whether a
+selector points to a segment that can be read or written at the current
+privilege level. Neither instruction causes a protection fault if the result
+is negative.
+
+VERR verifies a segment for reading and loads ZF with 1 if that segment is
+readable from the current privilege level. The validation process checks
+that: 1) the selector points to a descriptor within the bounds of the GDT or
+LDT, 2) it denotes a segment descriptor (as opposed to a control
+descriptor), and 3) the segment is readable and of appropriate privilege
+level. The privilege check for data segments and non-conforming code
+segments is that the DPL must be numerically greater than or equal to both
+the CPL and the selector's RPL. Conforming segments are not checked for
+privilege level.
+
+VERW provides the same capability as VERR for verifying writability. Like
+the VERR instruction, VERW loads ZF if the result of the writability check
+is positive. The instruction checks that the descriptor is within bounds, is
+a segment descriptor, is writable, and that its DPL is numerically greater
+than or equal to both the CPL and the selector's RPL. Code segments are
+never writable, conforming or not.
+
+
+11.3.2 Pointer Integrity: RPL and the "Trojan Horse Problem"
+
+The Requested Privilege Level (RPL) feature can prevent inappropriate use
+of pointers that could corrupt the operation of more privileged code or data
+from a less privileged level.
+
+A common example is a file system procedure, FREAD (file_id, nybytes,
+buffer-ptr). This hypothetical procedure reads data from a file into a
+buffer, overwriting whatever is there. Normally, FREAD would be available at
+the user level, supplying only pointers to the file system procedures and
+data located and operating at a privileged level. Normally, such a procedure
+prevents user-level procedures from directly changing the file tables.
+However, in the absence of a standard protocol for checking pointer
+validity, a user-level procedure could supply a pointer into the file
+tables in place of its buffer pointer, causing the FREAD procedure to
+corrupt them unwittingly.
+
+By using the RPL, you can avoid such problems. The RPL field allows a
+privilege attribute to be assigned to a selector. This privilege attribute
+would normally indicate the privilege level of the code which generated the
+selector. The 80286 hardware will automatically check the RPL of any
+selector loaded into a segment register or a control register to see if the
+RPL allows access.
+
+To guard against invalid pointers, the called procedure need only ensure
+that all selectors passed to it have an RPL at least as high (numerically)
+as the original caller's CPL. This indicates that the selectors were not
+more trusted than their supplier. If one of the selectors is used to access
+a segment that the caller would not be able to access directly, i.e., the
+RPL is numerically greater than the DPL, then a protection fault will result
+when loaded into a segment or control register.
+
+The caller's CPL is available in the CS selector that was pushed on the
+stack as the return address. A special instruction, ARPL, can be used to
+appropriately adjust the RPL field of the pointer. ARPL (Adjust RPL field of
+selector instruction) adjusts the RPL field of a selector to become the
+larger of its original value and the value of the RPL field in a specified
+register. The latter is normally loaded from the caller's CS register which
+can be found on the stack. If the adjustment changes the selector's RPL, ZF
+is set; otherwise, the zero flag is cleared.
+
+
+11.4 NPX Context Switching
+
+The context of a processor extension (such as the 80287 numerics processor)
+is not changed by the task switch operation. A processor extension context
+need only be changed when a different task attempts to use the processor
+extension (which still contains the context of a previous task). The 80286
+detects the first use of a processor extension after a task switch by
+causing the processor extension not-present exception (#7) if the TS bit is
+set. The interrupt handler may then decide whether a context change is
+necessary.
+
+The 286 services numeric errors only when it executes wait or escape
+instructions because the processor extension is running independently.
+Therefore, the numerics error from one task may not be recorded until the
+286 is running a different task. If the 286 task has changed, it makes
+sense to defer handling that error until the original task is restored. For
+example, interrupt handlers that use the NPX should not have their timing
+upset by a numeric error interrupt that pertains to some earlier process.
+It is of little value to service someone else's error.
+
+If the task switch bit is set (bit 3 of MSW) when the CPU begins to execute
+a wait or escape instruction, the processor-extension not-present exception
+results (#7). The handler for this interrupt must know who currently "owns"
+the NPX, i.e., the handler must know the last task to issue a command to the
+NPX. If the owner is the same as the current task, then it was merely
+interrupted and the interrupt handler has since returned; the handler for
+interrupt 7 simply clears the TS bit, restores the working registers, and
+returns (restoring interrupts if enabled).
+
+If the recorded owner is different from the current task, the handler must
+first save the existing NPX context in the save area of the old task. It can
+then re-establish the correct NPX context from the current task's save area.
+
+The code example in figure 11-3 relies on the convention that each TSS
+entry in the GDT is followed by an alias entry for a data segment that
+points to the same physical region of memory that contains the TSS. The
+alias segment also contains an area for saving the NPX context, the kernel
+stack, and certain kernel data. That is, the first 44 bytes in that segment
+are the 286 context, followed by 94 bytes for the processor extension
+context, followed in some cases by the kernel stack and kernel private data
+areas.
+
+The implied convention is that the stack segment selector points to this
+data segment alias so that whenever there is an interrupt at level zero and
+SS is automatically loaded, all of the above information is immediately
+addressable.
+
+It is assumed that the program example knows about only one data segment
+that points to a global data area in which it can find the one word NPX
+owner to begin the processing described. The specific operations needed, and
+shown in the figure, are listed in table 11-1.
+
+
+Table 11-1. NPX Context Switching
+
+Step Operation Lines
+ (Figure 11-3)
+
+1. Save the working registers 28, 29
+2. Set up address for kernel work area 30, 31
+3. Get current task ID from Task Register 32
+4. Clear Task Switch flag to allow NPX work 34
+5. Inhibit interrupts 35
+6. Compare owner with current task ID 37
+
+If same owner:
+7a. Restore working registers 48, 49
+7b. and return 50
+
+If owner is not current task:
+8a. Use owner ID to save old context
+ in its TSS 42, 43, 44
+8b. Restore context of current task; 45
+ restore working registers; 46
+ and return 52
+
+Figure 11-3. Example of NPX Context Switching
+
+ASSEMBLER INVOKED BY: ASM286,86 :FS:SWNPX.A86
+
+LOC OBJ LINE SOURCE
+ 1 + 1 $title('Switch the NPX Context on First Use After a Task Switch')
+ 2
+ 3 name switch_npx_context
+ 4
+ 5 public switch_NPX_context
+ 6 extrn last_npx_task:word
+ 7 ;
+ 8 ; This interrupt handler will switch the NPX context if a new task
+ 9 ; is attempting to use the NPX context of another task after a task
+ 10 ; switch. If the NPX context belongs to the current task, nothing happens.
+ 11 ;
+ 12 ; A trap gate should be placed in IDT entry 7 referring to this routine.
+ 13 ; The DPL of the gate should be 0 to prevent spoofing. The code segment
+ 14 ; must be at privilege level 0.
+ 15 ;
+ 16 ; The kernel stack is assumed to overlay the TSS and the NPX save area
+ 17 ; is placed at the end of the TSS area.
+ 18 ;
+ 19 ; A global word variable LAST_NPX_TASK identifies the TSS selector of
+ 20 ; the last task to use the NPX.
+ 21 ;
+ 002C 22 npx_save_area equ word ptr 44 ; Offset of NPX save area in TSS
+ 23 + 1 $eject
+∙∙∙∙ 24 kernal_code segment er public
+ 25
+0000 26 switch_npx_context proc far wc(0)
+ 27
+0000 50 28 push ax ; Save working registers
+0001 1E 29 push ds
+0002 B8∙∙∙∙ E 30 mov ax,seg last_npx_task ; Get address of id of last NPX task
+0005 8ED8 31 mov ds,ax
+0007 0F00C8 32 str ax ; Get id of this task
+000A 24FC 33 and al,not 3 ; Remove RPL field
+000C 0F06 34 clts ; Clear task switched flag
+000E FA 35 cli ; No interrupts allowed!
+ 36 ;
+ 37 ; Last_npx_word cannot change due to other interrupts after this point.
+ 38 ;
+000F 3B060000 E 39 cmp ax,ds:last_npx_task ; See if same task
+0013 7412 40 je same_task
+ 41
+0015 87060000 E 42 xchg ax,ds:last_npx_task ; Set new task id and get old one
+0019 050800 43 add ax,8 ; Go to TSS alias
+001C 8ED8 44 mov ds,ax ; Address TSS of previous NPX task
+001E DD362C00 45 fsave ds:npx_save_area ; Save old NPX state
+0022 36DD262C00 46 frstor ss:npx_save_area ; Get current NPX state
+0027 47 same_task:
+0027 1F 48 pop ds ; Return to interrupted program
+0028 58 49 pop ax
+0029 CF 50 iret
+ 51
+ 52 switch_npx_context endp
+ 53
+- - - - 54 kernel_code ends
+*** WARNING #160, LINE #54, SEGMENT CONTAINS PRIVILEGED INSTRUCTIONS
+ 55 end
+
+
+11.5 Multiprocessor Condiderations
+
+As mentioned in Chapter 8, a bus lock is applied during the testing and
+setting of the task busy bit to ensure that two processors do not invoke the
+same task at the same time. However, protection traps and conflicting use of
+dynamically varying segments or descriptors must be addressed by an
+inter-processor synchronization protocol. The protocol can use the
+indivisible semaphore operation of the base instruction set. Coordination of
+interrupt and trap vectoring must also be addressed when multiple concurrent
+processors are operating.
+
+The interrupt bus cycles are locked so no interleaving occurs on those
+cycles. Descriptor caching is locked so that a descriptor reference cannot
+be altered while it is being fetched.
+
+When a program changes a descriptor that is shared with other processors,
+it should broadcast this fact to the other processors. This broadcasting can
+be done with an inter-processor interrupt. The handler for this interrupt
+must ensure that the segment registers, the LDTR and the TR, are re-loaded.
+This happens automatically if the interrupt is serviced by a task switch.
+
+Modification of descriptors of shared segments in multi-processor systems
+may require that the on-chip descriptors also be updated. For example, one
+processor may attempt to mark the descriptor of a shared segment as
+not-present while another is using it. Software has to ensure that the
+descriptors in the segment register caches are updated with the new
+information. The segment register caches can be updated by a re-entrant
+procedure that is invoked by an inter-processor interrupt. The handler must
+ensure that the segment registers, the LDTR and the TR, are re-loaded. This
+happens automatically if the interrupt is serviced by a task switch.
+
+
+11.6 Shutdown
+
+Shutdown occurs when a severe error condition prevents further processing.
+Shutdown is very similar to HLT in that the 80286 stops executing
+instructions. The 80286 externally signals shutdown as a Halt bus cycle with
+A1=0. The NMI or RESET input will force the 80286 out of shutdown. The INTR
+input is ignored during shutdown.
+
+
+Appendix A 80286 System Initialization
+
+───────────────────────────────────────────────────────────────────────────
+
+$title('Switch the 80286 from Real Address Mode to Protected Mode')
+ name switch 80286_modes
+ public idt_desc,gdt_desc
+;
+; Switch the 80286 from real address mode into protected mode.
+; The initial EPROM GDT, IDT, TSS, and LDT (if any) constructed by BLD286
+; will be copied from EPROM into RAM. The RAM areas are defined by data
+; segments allocated as fixed entries in the GDT. The CPU registers for
+; GDT, IDT, TSS, and LDT will be set to point at the RAM-based
+; segments. The base fields in the RAM-based GDT will also be updated to
+; point at the RAM-based segments.
+;
+; This code is used by adding it to the list of object modules given
+; to BLD286. BLD286 must then be told to place the setment
+; init_code at address FFFE10H. Execution of the mode switch code begins
+; after RESET. This happens because the mode switch code will start at
+; physical address FFFFF0H, which is the power up address. This code then
+; sets up RAM copies of the EPROM-based segments before jumping to the
+; initial tsk placed at a fixed GDT entry. After the jump, the CPU
+; executes in the state of the first task defined by BLD286.
+;
+; This code will not use any of the EPROM-based tables directly.
+; Such use would result in the 80286 writing into EPROM to set
+; the A bit. Any use of a GDT or TSS will always be in the RAM copy.
+; The limit and size of the EPROM-based GDT and IDT must be stored at
+; the public symbols idt_desc and gdt_desc. The location commands of BLD286
+; provide this function.
+;
+; Interrupts are disabled during this mode switching code. Full error
+; checking is made of the EPROM-based GDT, IDT, TSS, and LDT to assure
+; they are valid before copying them to RAM. If any of the RAM-based
+; aslias segments are smaller than the EPROM segments they are to hold,
+; halt or shutdown will occur. In general, any exception or NMI will
+; cause shutdown to occur until the first task is invoked.
+;
+; If the RAM segment is larger than the EPROM segment, the RAM segment
+; will be expanded with zeros. If the initial TSS specifies an LDT,
+; the LDT will also be copied into ldt_alias with zero fill if needed.
+; The IPROM-based or RAM-based GDT, IDT, TSS, and LDT segments may be located
+; anywhere in physical memory.
+;
+;
+; Define layout of a descriptor.
+;
+desc struc
+limit dw 0 ; Offset of last byte in segment
+base_low dw 0 ; Low 16 bits of 24-bit address
+base_high db 0 ; High 8 bits of 24-bit address
+access db 0 ; Access rights byte
+res dw 0 ; Reserved word
+ desc ends
+;
+; Define the fixed GDT selector values for the descriptors that
+; define the EPROM-based tables. BLD286 must be instructed to place the
+; appropriate descriptors into the GDT.
+;
+gdt_alias equ 1*size desc ; GDT(1) is data segment in RAM for GDT
+idt_alias equ 2*size desc ; GDT(2) is data segment in RAM for IDT
+start_TSS_alias equ 3*size desc ; GDT(3) is data segment in RAM for TSS
+start_task equ 4*size desc ; GDT(4) is TSS for starting task
+start_LDT_alias equ 5*size desc ; GDT(5) is data segment in RAM for LDT
+;
+; Define machine status word bit positions.
+;
+PE equ 1 ; Protection enable
+MP equ 2 ; Monitor processor extension
+EM equ 4 ; Emulate processor extension
+;
+; Define particular values of descriptor access rights byte.
+;
+DT_ACCESS equ 82H ; Access byte value for an LDT
+DS_ACCESS equ 92H ; Access byte value for data segment
+ ; which is grow up, at level 0, writeable
+TSS_ACCESS equ 81H ; Access byte value for an idle TSS
+DPL equ 60H ; Privilege level field of access rights
+ACCESSED equ 1 ; Define accessed bit
+TI equ 4 ; Position of TI bit
+TSS_SIZE equ 44 ; Size of a TSS
+LDT_OFFSET equ 42 ; Position of LDT in TSS
+TIRPL_MASK equ size desc-1 ; TI and RPL field mask
+;
+; Pass control from the power-up address to the mode switch code.
+; The segment containing this code must be at physical address FFFE10H
+; to place the JMP instruction at physical address FFFFF0H. The base
+; address is chosen according to the size of this segment.
+;
+init_code segment er
+
+cs_offset equ 0FE10H ; Low 16 bits of starting address
+ org 0FFF0H-cs_offset; Start at address FFFFF0H
+ jmp reset_startup ; Do not change CS!
+;
+; Define the template for a temporary GDT used to locate the initial
+; GDT and stack. This data will be copied to location 0.
+; This space is also used for a temporary stack and finally serves
+; as the TSS written into when entering the initial TSS.
+;
+ org 0 ; Place remaining code below power_up
+
+initial_gdt desc <> ; Filler and null IDT descriptor
+gdt_desc desc <> ; Descriptor for EPROM GDT
+idt_desc desc <> ; Descriptor for EPROM IDT
+temp_desc desc <> ; Temporary descriptor
+;
+; Define a descriptor that will point the GDT at location 0.
+; This descriptor will also be loaded into SS to define the initial
+; protected mode stack segment.
+;
+temp_stack desc <end_gdt-initial_gdt-1,0,0,DS_ACCESS,0>
+;
+; Define the TSS descriptor used to allow the task switch to the
+; first task to overwrite this region of memory. The TSS will overlay
+; the initial GDT and stack at location 0.
+;
+save_tss desc <end_gdt-initial_gdt-1,0,0,TSS_ACCESS,0>
+;
+; Define the initial stack space and filler for the end of the TSS.
+;
+ dw 8 dup (0)
+end_gdt label word
+
+start_pointer label dword
+ dw 0,start_task ; Pointer to initial task
+;
+; Define template for the task definition list.
+;
+task_entry struc ; Define layout of task description
+TSS_sel dw ? ; Selector for TSS
+TSS_alias dw ? ; Data segment alias for TSS
+LDT_alias dw ? ; Data segment alias for LDT if any
+task_entry ends
+
+task_list task_entry <start_task,start_TSS_alias,start_LDT_alias>
+ dw 0 ; Terminate list
+
+reset_startup:
+ cli ; No interrupts allowed!
+ cld ; Use autoincrement mode
+ xor di,di ; Point ES:DI at physical address 000000H
+ mov ds,di
+ mov es,di
+ mov ss,di ; Set stack at end of reserved area
+ mov sp,end_gdt-initial_gdt
+;
+;
+; Form an adjustment factor from the real CS base of FF0000H to the
+; segment base address assumed by ASM286. Any data reference mode
+; into CS must add an indexing term [BP] to compensate for the difference
+; between the offset generated by ASM286 and the offset required from
+; the base of FF0000H.
+;
+start proc ; The value of IP at run time will not be
+ ; the same as the one used by ASM286!
+ call start1 ; Get true offset of start1
+start1:
+ pop bp
+ sub bp, offset start1 ; Subtract ASM286 offset of start1
+ ; leaving adjustment factor in BP
+ lidt initial_gdt[bp] ; Setup null IDT to force shutdown
+ ; on any protection error or interrupt
+;
+; Copy the EPROM-based temporary GDT into RAM.
+;
+ lea si,initial_gdt[bp] ; Setup pointer to temporary GDT
+ ; template in EPROM
+ mov cs,(end_gdt-initial_gdt)/2 ; Set length
+ rep movs es:word ptr [di],cs:[si]; Put into reserved RAM area
+;
+; Look for 80287 processor extension. Assume all ones will be read
+; if an 80287 is not present.
+;
+ fninit ; Initialize 80287 if present
+ mov bx,EM ; Assume no 80287
+ fstsw ax ; Look at status of 80287
+ or al,al ; No errors should be present
+ jnz set_mode ; Jump if no 80287
+
+ fsetpm ; Put 80287 into protected mode
+ mov bx,MP
+;
+; Switch to protected mode and setup a stack, GDT, and LDT.
+;
+set_mode;
+ smsw ax ; Get current MSW
+ or ax,PE ; Set PE bit
+ or ax,bx ; Set NPX status flags
+ lmsw ax ; nter protected mode!
+ jmp $+2 ; Clear queue of instructions decoded
+ ; while in Real Address Mode
+ ; CPL is now 0, CS still points at
+ ; FFFE10 in physical memory
+ lgdt temp_stack[bp] ; Use initial GDT in RAM area
+ mov ax,temp_stack-initial_gdt ; Setup SS with valid protected mode
+ mov ss,ax ; selector to the RAM GDT and stack
+ xor ax,ax ; Set the current LDT to null
+ lidt ax ; Any references to it will cause
+ ; an exception causing shutdown
+ mov ax,save_tss-initial_gdt ; Set initial TSS into the low RAM
+ ltr ax ; The task switch needs a valid TSS
+;
+; Copy the EPROM-based GDT into the RAM data segment alias.
+; First the descriptor for the RAM data segment must be copied into
+; the temporary GDT.
+;
+ mov ax,gdt_desc[bp].limit ; Get size of GDT
+ cmp ax,6*size desc-1 ; Be sure the last entry expected by
+ ; this code is inside the GDT
+ jb bad_gdt ; Jump if GDT is not big enough
+
+ mov bx,gdt_desc-initial_gdt ; Form selector to EPROM GDT
+ mov si,gdt_alias ; Get selector of GDT alias
+ call copy_EPROM_dt ; Copy into EPROM
+ mov si,idt_alias ; Get selector of IDT alias
+ mov bx,ldt_desc-initial_gdt ; Indicate EPROM IDT
+ call copy_EPROM_dt
+ mov ax,gdt_desc-initial_gdt ; Setup addressing into EPROM GDT
+ mov ds,ax
+ mov bx,gdt_alias ; Get GDT alias data segment selector
+ lgdt [bx] ; Set GDT to RAM GDT
+ ; SS and TR remain in low RAM
+;
+; Copy all task's TSS and LDT segments into RAM
+;
+ lea bx,task_list[bp] ; Define list of tasks to setup
+copy_task_loop:
+ call copy_tasks ; Copy them into RAM
+ add bx,size task_entry ; Go to next entry
+ mov ax,cs:[bx].tss_sel ; See if there is another entry
+ or ax,ax
+ jnz copy_task_loop
+;
+; With TSS, GDT, and LDT set, startup the initial task!
+;
+ mov bx,gdt_alias ; Point DS at GDT
+ mov ds,bx
+ mov bx,idt_alias ; Get IDT alias data segment selector
+ lidt [bx] ; Start the first task!
+ jmp start_pointer[bp] ; The low RAM area is overwritten with
+ ; the current CPU context
+
+bad_gdt: ; Wait here if GDT is not big enough
+ hlt
+astart endp
+;
+; Copy the TSS and LDT for the task pointed at by CS:BX.
+; If the task has an LDT it will also be copied down.
+; BX and BP are transparent.
+;
+bad_tss:
+ hlt ; Halt here if TSS is invalid
+copy_tasks proc
+
+ mov si,gdt_alias ; Get addressability to GDT
+ mov ds,si
+ mov si,cs:[bx].tss_alias ; Get selector for TSS alias
+ mov es,si ; Point ES at alias data segment
+ lsl ax,si ; Get length of TSS alias
+ mov si,cs:[bx].tss_sel ; Get TSS selector
+ lar dx,si ; Get alias access rights
+ jnz bad_tss ; Jump if invalid reference
+
+ mov dl,dh ; Save TSS descriptor access byte
+ and dh,not DPL ; Ignore privilege
+ cmp dh,TSS_ACCESS ; See if TSS
+ jnz bad_tss ; Jump if not
+
+ lsl cs,si ; Get length of EPROM based TSS
+ cmp cs,TSS_SIZE-1 ; Verify it is of proper size
+ jb bad_tss ; Jump if it is not big enough
+;
+; Setup for moving the EPROM-based TSS to RAM
+; DS points at GDT
+;
+ mov [si].access,DS_ACCESS ; Make TSS into data segment
+ mov ds,si ; Point DS at EPROM TSS
+ call copy_with_fill ; Copy DS segment to ES with zero fill
+ ; CX has copy count, AX-CX fill count
+;
+; Set the GDT TSS limit and base address to the RAM values
+;
+ mov ax,gdt_alias ; Restore GDT addressing
+ mov ds,ax
+ mov es,ax
+ mov di,cs:[bx].tss_sel ; Get TSS selector
+ mov si,cs:[bx].tss_alias ; Get RAM alias selector
+ movsw ; Copy limit
+ movsw ; Copy low 16 bits of adress
+ lodsw ; Get high 8 bits of address
+ mov ah,dl ; Mark as TSS descriptor
+ stosw ; Fill in high address and access bytes
+ movsw ; Copy reserved word
+;
+; See if a valid LDT is specified for the startup task
+; If so then copy the EPROM version into the RAM alias.
+;
+ mov ds,cs:[bx].tss_alias ; Address TSS to get LDT
+ mov si,ds:word ptr LDT_OFFSET
+ and si,not TIRPL_MASK ; Ignore TI and RPL
+ jz no_ldt ; Skip this if no LDT used
+
+ push si ; Save LDT selector
+ lar dx,si ; Test descriptor
+ jnz bad_ldt ; Jump if invalid selector
+
+ mov dl,dh ; Save LDT descriptor access byte
+ and dh,not DPL ; Ignore privilege
+ cmp dh, DT_ACCESS ; Be sure it is an LDT descriptor
+ jne bad_ldt ; Jump if invalid
+
+ mov es:[si].access,DS_ACCESS ; Mark LDT as data segment
+ mov ds,si ; Point DS at EPROM LDT
+ lsl ax,si ; Get LDT limit
+ call test_dt_limit ; Verify it is valid
+ mov cx,ax ; Save for later
+
+;
+; Examine the LDT alias segment and, if good, copy to RAM
+;
+ mov si,cs:[bx].ldt_alias ; Get ldt alias selector
+ mov es,si ; Point ES at alias segment
+ lsl ax,si ; Get length of alias segmewnt
+ call test_dt_limit ; Verify it is valid
+ call copy_with_fill ; Copy LDT into RAM alias segment
+;
+; Set the LDT limit and base address to the RAM copy of the LDT.
+;
+ mov si,cs:[bx].ldt_alias ; Restore LDT alias selector
+ pop di ; Restore LDT selector
+ mov ax,gdt_alias ; Restore GDT addressing
+ mov ds,ax
+ mov es,ax
+ movsw ; Move the RAM LDT limit
+ movsw ; Move the low 16 bits across
+ lodsw ; Get the high 8 bits
+ mov ah,dl ; Set high address and access rights
+ stosw ; Copy reserved word
+ movsw
+no_ldt:
+ ret ; All done
+bad_ldt:
+ hit ; Halt here if LDT is invalid
+copy_tasks endp
+
+;
+; Test the descriptor table size in AX to verify that it is an
+; even number of descriptors in length.
+;
+test_dt_limit proc
+
+ push ax ; Save length
+ end al,7 ; Look at low order bits
+ cmp al,7 ; Must be all ones
+ pop ax ; Restore length
+ jne bad_dt_limit;
+
+ ret ; All OK
+bad_dt_limit:
+ hit: ; Die!
+
+test_dt_limit endp
+
+;
+; Copy the EPROM DT at selector BX in the temporary GDT to the alias
+; data segment at selector SI. Any improper descriptors or limits
+; will cause shutdown!
+;
+copy_EPROM_dt proc
+
+ mov ax,ss ; Point ES:DI at temporary descriptor
+ mov es,ax
+ mov es:[bx].access,DS_ACCESS ; Mark descriptor as a data segment
+ mov es:[bx].res,0 ; Clear reserved word
+ lsl ax,bx ; Get limit of EPROM DT
+ mov cx,ax ; Save for later
+ call test_dt_limit ; Verify it is a proper limit
+ mov di,gdt_desc-initial_gdt ; Address EPROM GDT in DS
+ mov ds,di
+ mov di,temp_desc-initial_gdt ; Get selector for temporary descriptor
+ push di ; Save offset for later use as selector
+ lodsw ; Get alias segment size
+ call test_dt_limit ; Verify it is an even multiple of
+ ; descriptors in length
+ stosw ; Put length into temporary
+ movsw ; Copy remaining entries into temporary
+ movsw
+ movsw
+ pop es ; ES now points at the GDT alias area
+ mov ds,bx ; DS now points at EPROM DT as data
+ ; Copy segment ot alias with zero fill
+ ; CX is copy count, AX-CX is fill count
+ ; Fall into copy_with_fill
+
+copy_EPROM_dt endp
+
+;
+; Copy the segment at DS to the segment at ES for length CX.
+; Fill th end with AX-CX zeros.s Use word operations for speed but
+; allow odd byte operations.
+;
+copy_with_fill proc
+
+ xor si,si ; Start at beginning of segments
+ xor di,di
+ sub ax,cx ; Form fill count
+ add cs,1 ; Convert laimit to count
+ rcr cs,1 ; Allow full 64K move
+ rep movsw ; Copy DT into alias area
+ xchg ax,cx ; Get fill count and zero AX
+ jnc even_copy ; Jump if even byte count on copy
+
+ movsb ; Copy odd byte
+ or cx,cx
+ jz exit_copy ; Exit if no fill
+
+ stosb ; Even out the segment offset
+ dec cx ; Adjust remaining fill count
+even_copy:
+ shr cx,1 ; Form word count on fill
+ rep stosw ; Clear unused words at end
+ jnc exit_copy ; Exit if no odd byte remains
+
+ stosb ; Clear last odd byte
+exit_copy:
+ ret
+
+copy_with_fill endp
+
+init_code ends
+ end
+
+
+$B
+
+
+Appendix B The 80286 Instruction Set
+
+───────────────────────────────────────────────────────────────────────────
+
+This section presents the 80286 instruction set using Intel's ASM286
+notation. All possible operand types are shown. Instructions are organized
+alphabetically according to generic operations. Within each operation, many
+different instructions are possible depending on the operand. The pages are
+presented in a standardized format, the elements of which are described in
+the following paragraphs.
+
+Opcode
+
+This column gives the complete object code produced for each form of the
+instruction. Where possible, the codes are given as hexadecimal bytes,
+presented in the order in which they will appear in memory. Several
+shorthand conventions are used for the parts of instructions which specify
+operands. These conventions are as follows:
+
+/n: (n is a digit from 0 through 7) A ModRM byte, plus a possible immediate
+and displacement field follow the opcode. See figure B-1 for the encoding
+of the fields. The digit n is the value of the REG field of the ModRM byte.
+To obtain the possible hexadecimal values for /n, refer to column n of table
+B-1. Each row gives a possible value for the effective address operand
+to the instruction. The entry at the end of the row indicates whether the
+effective address operand is a register or memory; if memory, the entry
+indicates what kind of indexing and/or displacement is used. Entries with
+D8 or D16 signify that a one-byte or two-byte displacement quantity
+immediately follows the ModRM and optional immediate field bytes. The
+signed displacement is added to the effective address offset.
+
+/r: A ModRM byte that contains both a register operand and an effective
+address operand, followed by a possible immediate and displacement field.
+See figure B-2 for the encoding of the fields. The ModRM byte could be any
+value appearing in table B-1. The column determines which register
+operand was selected; the row determines the form of effective address. If
+the row entry mentions D8 or D16, then a one-byte or two-byte displacement
+follows, as described in the previous paragraph.
+
+cb: A one-byte signed displacement in the range of -128 to +127 follows the
+opcode. The displacement is sign-extended to 16 bits, and added modulo 65536
+to the offset of the instruction FOLLOWING this instruction to obtain the
+new IP value.
+
+cw: A two-byte displacement is added modulo 65536 to the offset of the
+instruction FOLLOWING this instruction to obtain the new IP value.
+
+cd: A two-word pointer which will be the new CS:IP value. The offset is
+given first, followed by the selector.
+
+db: An immediate byte operand to the instruction which follows the opcode
+and ModRM bytes. The opcode determines if it is a signed value.
+
+dw: An immediate word operand to the instruction which follows the opcode
+and ModRM bytes. All words are given in the 80286 with the low-order byte
+first.
+
++rb: A register code from 0 through 7 which is added to the hexadecimal byte
+given at the left of the plus sign to form a single opcode byte. The codes
+are: AL=0, CL=1, DL=2, BL=3, AH=4, CH=5, DH=6, and BH=7.
+
++rw: A register code from 0 through 7 which is added to the hexadecimal byte
+given at the left of the plus sign to form a single opcode byte. The codes
+are: AX=0, CX=1, DX=2, BX=3, SP=4, BP=5, SI=6, and DI=7.
+
+
+Table B-1. ModRM Values
+
+
+Rb = AL CL DL BL AH CH DH BH
+Rw = AX CX DX BX SP BP SI DI
+REG = 0 1 2 3 4 5 6 7
+
+ ModRM values Effective address
+
+ 00 08 10 18 20 28 30 38 [BX + SI]
+ 01 09 11 19 21 29 31 39 [BX + DI]
+ 02 0A 12 1A 22 2A 32 3A [BP + SI]
+ 03 0B 13 1B 23 2B 33 3B [BP + DI]
+mod=00 04 0C 14 1C 24 2C 34 3C [SI]
+ 05 0D 15 1D 25 2D 35 3D [DI]
+ 06 0E 16 1E 26 2E 36 3E D16 (simple var)
+ 07 0F 17 1F 27 2F 37 3F [BX]
+
+ 40 48 50 58 60 68 70 78 [BX + SI] + D8
+D8 denotes an 8-bit displacement following the ModRM byte that is
+sign-extended and added to the index.
+
+
+
+ 41 49 51 59 61 69 71 79 [BX + DI] + D8
+ 42 4A 52 5A 62 6A 72 7A [BP + SI] + D8
+ 43 4B 53 5B 63 6B 73 7B [BP + DI] + D8
+mod=01 44 4C 54 5C 64 6C 74 7C [SI] + D8
+ 45 4D 55 5D 65 6D 75 7D [DI] + D8
+ 46 4E 56 5E 66 6E 76 7E [BP] + D8
+Default segment register is SS for effective addresses containing a BP
+index; DS is for other memory effective addresses.
+
+
+
+ 47 4F 57 5F 67 6F 77 7F [BX] + D8
+
+ 80 88 90 98 A0 A8 B0 B8 [BX + SI] + D16
+D16 denotes the 16-bit displacement following the ModRM byte that is
+added to the index.
+
+
+
+ 81 89 91 99 A1 A9 B1 B9 [BX + DI] + D16
+ 82 8A 92 9A A2 AA B2 BA [BP +SI] + D16
+ 83 8B 93 9B A3 AB B3 BB [BP + DI] + D16
+mod=10 84 8C 94 9C A4 AC B4 BC [SI] + D16
+ 85 8D 95 9D A5 AD B5 BD [DI] + D16
+ 86 8E 96 9E A6 AE B6 BE [BP] + D16
+Default segment register is SS for effective addresses containing a BP
+index; DS is for other memory effective addresses.
+
+
+
+ 87 8F 97 9F A7 AF B7 BF [BX] + D16
+
+ C0 C8 D0 D8 E0 E8 F0 F8 Ew=AX Eb=AL
+ C1 C9 D1 D9 E1 E9 F1 F9 Ew=CX Eb=CL
+ C2 CA D2 DA E2 EA F2 FA Ew=DX Eb=DL
+ C3 CB D3 DB E3 EB F3 FB Ew=BX Eb=BL
+mod=11 C4 CC D4 DC E4 EC F4 FC Ew=SP Eb=AH
+ C5 CD D5 DD E5 ED F5 FD Ew=BP Eb=CH
+ C6 CE D6 DE E6 EE F6 FE Ew=SI Eb=DH
+ C7 CF D7 DF E7 EF F7 FF Ew=DI Eb=BH
+
+
+
+Figure B-1. /n Instruction Byte Format
+
+ pp/n Instruction Byte Format
+ ╔════╤═══════╤═══════╤════════════╤════════════╤════════════╤════════════╗
+ ║ mod│ n │ r/m │ imm. low
+Opcode indicates presence and size of immediate field. │ imm. high
+Opcode indicates presence and size of immediate field. │ disp-low │ disp-high ║
+ ╚════╧═══════╧═══════╧════════════╧════════════╧════════════╧════════════╝
+ 7 6 5 4 3 2 1 0 7 0 7 0 7 0 7 0
+
+ "mod" Field Bit Assignments
+ ╔══════════╤═════════════════════════════════════════════════════════════╗
+ ║ mod │ Displacement ║
+ ╠══════════╪═════════════════════════════════════════════════════════════╣
+ ║ 00 │DISP = 0
+ Except if mod = 00 and r/m = 110 then EA = disp-high:disp-low., disp-low and disp-high are absent ║
+ ║ 01 │DISP = disp-low sign-extended to 16-bit, disp-high is absent ║
+ ║ 10 │DISP = disp-high: disp-low ║
+ ║ 11 │r/m is treated as a "reg" field ║
+ ╚══════════╧═════════════════════════════════════════════════════════════╝
+
+ "r/m" Field Bit Assignments
+ ╔════════════════════════════════════╤═══════════════════════════════════╗
+ ║ r/m │ Operand Address ║
+ ╠════════════════════════════════════╪═══════════════════════════════════╣
+ ║ 000 │ (BX) + (SI) + DISP ║
+ ║ 001 │ (BX) + (DI) + DISP ║
+ ║ 010 │ (BP) + (SI) + DISP ║
+ ║ 011 │ (BP) + (DI) + DISP ║
+ ║ 100 │ (SI) + DISP ║
+ ║ 101 │ (DI) + DISP ║
+ ║ 110 │ (BP) + DISP
+ Except if mod = 00 and r/m = 110 then EA = disp-high:disp-low. ║
+ ║ 111 │ (BX) + DISP ║
+ ╚════════════════════════════════════╧═══════════════════════════════════╝
+ DISP follows 2nd byte of instruction (before data if required).
+
+
+Figure B-2. /r Instruction Byte Format
+
+ /r Instruction Byte Format
+ ╔════╤═══════╤═══════╤════════════╤════════════╤════════════╤════════════╗
+ ║ mod│ r │ r/m │ imm. low
+Opcode indicates presence and size of immediate field. │ imm. high
+ Opcode indicates presence and size of immediate field. │ disp-low │ disp-high ║
+ ╚════╧═══════╧═══════╧════════════╧════════════╧════════════╧════════════╝
+ 7 6 5 4 3 2 1 0 7 0 7 0 7 0 7 0
+
+ "mod" Field Bit Assignments
+ ╔══════════╤═════════════════════════════════════════════════════════════╗
+ ║ mod │ Displacement ║
+ ╠══════════╪═════════════════════════════════════════════════════════════╣
+ ║ 00 │DISP = 0
+Except if mod = 00 and r/m = 110 then EA = disp-high:disp-low., disp-low and disp-high are absent ║
+ ║ 01 │DISP = disp-low sign-extended to 16-bit, disp-high is absent ║
+ ║ 10 │DISP = disp-high: disp-low ║
+ ║ 11 │r/m is treated as a "reg" field ║
+ ╚══════════╧═════════════════════════════════════════════════════════════╝
+
+ "r" Field Bit Assignments
+ ╔═══════════════════════╤═══════════════════════╤════════════════════════╗
+ ║ 16-Bit (w = 1) │ 6-Bit (w = 0) │ Segment ║
+ ╠═══════════════════════╪═══════════════════════╪════════════════════════╣
+ ║ 000 AX │ 000 AL │ 00 ES ║
+ ║ 001 CX │ 001 CL │ 01 CS ║
+ ║ 010 DX │ 010 DL │ 10 SS ║
+ ║ 011 BX │ 011 BL │ 11 DS ║
+ ║ 100 SP │ 100 AH │ ║
+ ║ 101 BP │ 101 CH │ ║
+ ║ 110 SI │ 110 DH │ ║
+ ║ 111 DI │ 111 BH │ ║
+ ╚═══════════════════════╧═══════════════════════╧════════════════════════╝
+
+ "r/m" Field Bit Assignments
+ ╔════════════════════════════════════╤═══════════════════════════════════╗
+ ║ r/m │ Operand Address ║
+ ╠════════════════════════════════════╪═══════════════════════════════════╣
+ ║ 000 │ (BX) + (SI) + DISP ║
+ ║ 001 │ (BX) + (DI) + DISP ║
+ ║ 010 │ (BP) + (SI) + DISP ║
+ ║ 011 │ (BP) + (DI) + DISP ║
+ ║ 100 │ (SI) + DISP ║
+ ║ 101 │ (DI) + DISP ║
+ ║ 110 │ (BP) + DISP
+Except if mod = 00 and r/m = 110 then EA = disp-high:disp-low. ║
+ ║ 111 │ (BX) + DISP ║
+ ╚════════════════════════════════════╧═══════════════════════════════════╝
+ DISP follows 2nd byte of instruction (before data if required).
+
+
+Instruction
+
+This column gives the instruction mnemonic and possible operands. The type
+of operand used will determine the opcode and operand encodings. The
+following entries list the type of operand which can be encoded in the
+format shown in the instruction column. The Intel convention is to place
+the destination operand as the left hand operand. Source-only operands
+follow the destination operand.
+
+In many cases, the same instruction can be encoded several ways. It is
+recommended that you use the shortest encoding. The short encodings are
+provided to save memory space.
+
+cb: a destination instruction offset in the range of 128 bytes before the
+end of this instruction to 127 bytes after the end of this instruction.
+
+cw: a destination offset within the same code segment as this instruction.
+Some instructions allow a short form of destination offset. See cb type for
+more information.
+
+cd: a destination address, typically in a different code segment from this
+instruction. Using the cd: address form with call instructions saves the
+code segment selector.
+
+db: a signed value between -128 and +127 inclusive which is an operand of
+the instruction. For instructions in which the db is to be combined in some
+way with a word operand, the immediate value is sign-extended to form a
+word. The upper byte of the word is filled with the topmost bit of the
+immediate value.
+
+dw: an immediate word value which is an operand of the instruction.
+
+eb: a byte-sized operand. This is either a byte register or a (possibly
+indexed) byte memory variable. Either operand location may be encoded in the
+ModRM field. Any memory addressing mode may be used.
+
+ed: a memory-based pointer operand. Any memory addressing mode may be used.
+Use of a register addressing mode will cause exception 6.
+
+ew: a word-sized operand. This is either a word register or a (possibly
+indexed) word memory variable. Either operand location may be encoded in the
+ModRM field. Any memory addressing mode may be used.
+
+m: a memory location. Operands in registers do not have a memory address.
+Any memory addressing mode may be used. Use of a register addressing mode
+will cause exception 6.
+
+mb: a memory-based byte-sized operand. Any memory addressing mode may be
+used.
+
+mw: a memory-based word operand. Any memory addressing mode may be used.
+
+rb: one of the byte registers AL, CL, DL, BL, AH, CH, DH, or BH; rb has the
+value 0,1,2,3,4,5,6, and 7, respectively.
+
+rw: one of the word registers AX, CX, DX, BX, SP, BP, SI, or DI; rw has the
+value 0,1,2,3,4,5,6, and 7, respectively.
+
+xb: a simple byte memory variable without a base or index register. MOV
+instructions between AL and memory have this optimized form if no indexing
+is required.
+
+xw: a simple word memory variable without a base or index register. MOV
+instructions between AX and memory have this optimized form if no indexing
+is required.
+
+
+Clocks
+
+This column gives the number of clock cycles that this form of the
+instruction takes to execute. The amount of time for each clock cycle is
+computed by dividing one microsecond by the number of MHz at which the 80286
+is running. For example, a 10-MHz 80286 (with the CLK pin connected to
+a 20-MHz crystal) takes 100 nanoseconds for each clock cycle.
+
+Add one clock to instructions that use the base plus index plus
+displacement form of addressing. Add two clocks for each 16-bit memory based
+operand reference located on an odd physical address. Add one clock for each
+wait state added to each memory read. Wait states inserted in memory writes
+or instruction fetches do not necessarily increase execution time.
+
+The clock counts establish the maximum execution rate of the 80286. With no
+delays in bus cycles, the actual clock count of an 80286 program will
+average 5-10% more than the calculated clock count due to instruction
+sequences that execute faster than they can be fetched from memory.
+
+Some instruction forms give two clock counts, one unlabelled and one
+labelled. These counts indicate that the instruction has two different clock
+times for two different circumstances. Following are the circumstances for
+each possible label:
+
+mem: The instruction has an operand that can either be a register or a
+memory variable. The unlabelled time is for the register; the mem time is
+for the memory variable. Also, one additional clock cycle is taken for
+indexed memory variables for which all three possible indices (base
+register, index register, and displacement) must be added.
+
+noj: The instruction involves a conditional jump or interrupt. The
+unlabelled time holds when the jump is made; the noj time holds when the
+jump is not made.
+
+pm: If the instruction takes more time to execute when the 80286 is in
+Protected Mode. The unlabelled time is for Real Address Mode; the pm time is
+for Protected Mode.
+
+
+Description
+
+This is a concise description of the operation performed for this form of
+the instruction. More details are given in the "Operation" section that
+appears later in this chapter.
+
+
+Flags Modified
+
+This is a list of the flags that are set to a meaningful value by the
+instruction. If a flag is always set to the same value by the instruction,
+the value is given ("=0" or "=1") after the flag name.
+
+
+Flags Undefined
+
+This is a list of the flags that have an undefined (meaningless) setting
+after the instruction is executed.
+
+All flags not mentioned under "Flags Modified" or "Flags Undefined" are
+unchanged by the instruction.
+
+
+Operation
+
+This section fully describes the operation performed by the instruction.
+For some of the more complicated instructions, suggested usage is also
+indicated.
+
+
+Protected Mode Exceptions
+
+The possible exceptions involved with this instruction when running under
+the 80286 Protected Mode are listed below. These exceptions are abbreviated
+with a pound sign (#) followed by two capital letters and an optional error
+code in parenthesis. For example, #GP(0) denotes the general protection
+exception with an error code of zero. The next section describes all of the
+80286 exceptions and the machine state upon entry to the exception.
+
+If you are an applications programmer, consult the documentation provided
+with your operating system to determine what actions are taken by the system
+when exceptions occur.
+
+
+Real Address Mode Exceptions
+
+Since less error checking is performed by the 80286 when it is in Real
+Address Mode, there are fewer exceptions in this mode. One exception that is
+possible in many instructions is #GP(0). Exception 13 is generated whenever
+a word operand is accessed from effective address 0FFFFH in a segment. This
+happens because the second byte of the word is considered located at
+location 10000H, not at location 0, and thus exceeds the segment's
+addressability limit.
+
+
+Protection Exceptions
+
+In parallel with the execution of instructions, the protected-mode 80286
+checks all memory references for validity of addressing and type of access.
+Violation of the memory protection rules built into the processor will cause
+a transfer of program control to one of the interrupt procedures described
+in this section. The interrupts have dedicated positions within the
+Interrupt Descriptor Table, which is shown in table B-2. The interrupts are
+referenced within the instruction set pages by a pound sign (#) followed by
+a two-letter mnemonic and the optional error code in parenthesis.
+
+
+Table B-2. Protection Exceptions of the 80286
+
+Abbreviation Interrupt Number Description
+
+ #UD 6 Undefined Opcode
+ #NM 7 No Math Unit Available
+ #DF 8 Double Fault
+ #MP 9 Math Unit Protection Fault
+ #TS 10 Invalid Task State Segment
+ #NP 11 Not Present
+ #SS 12 Stack Fault
+ #GP 13 General Protection
+ #MF 16 Math Fault
+
+
+Error Codes
+
+Some exceptions cause the 80286 to pass a 16-bit error code to the
+interrupt procedure. When this happens, the error code is the last item
+pushed onto the stack before control is tranferred to the interrupt
+procedure. If stacks were switched as a result of the interrupt (causing a
+privilege change or task switch), the error code appears on the interrupt
+procedure's stack, not on the stack of the task that was interrupted.
+
+The error code generally contains the selector of the segment that caused
+the protection violation. The RPL field (bottom two bits) of the error code
+does not, however, contain the privilege level. Instead, it contains the
+following information:
+
+ ■ Bit 0 contains the value 1 if the exception was detected during an
+ interrupt caused by an event external to the program (i.e., an external
+ interrupt, a single step, a processor extension not-present exception,
+ or a processor extension segment overrun). Bit 0 is 0 if the exception
+ was detected while processing the regular instruction stream, even if
+ the instruction stream is part of an external interrupt handling
+ procedure or task. If bit 0 is set, the instruction pointed to by the
+ saved CS:IP address is not responsible for the error. The current task
+ can be restarted unless this is exception 9.
+
+ ■ Bit 1 is 1 if the selector points to the Interrupt Descriptor Table.
+ In this case, bit 2 can be ignored, and bits 3-10 contain the index
+ into the IDT.
+
+ ■ Bit 1 is 0 if the selector points to the Global or Local Descriptor
+ Tables. In this case, bits 2-15 have their usual selector
+ interpretation: bit 2 selects the table (1=Local, 0=Global), and
+ bits 3-15 are the index into the table.
+
+In some cases the 80286 chooses to pass an error code with no information
+in it. In these cases, all 16 bits of the error code are zero.
+
+The existence and type of error codes are described under each of the
+following individual exceptions.
+
+
+#DF 8 Double Fault (Zero Error Code)
+
+This exception is generated when a second exception is detected while the
+processor is attempting to transfer control to the handler for an exception.
+For instance, it is generated if the code segment containing the exception
+handler is marked not present. It is also generated if invoking the
+exception handler causes a stack overflow.
+
+This exception is not generated during the execution of an exeception
+handler. Faults detected within the instruction stream are handled by
+regular exceptions.
+
+The error code is normally zero. The saved CS:IP will point at the
+instruction that was attempting to execute when the double fault occurred.
+Since the error code is normally zero, no information on the source of the
+exception is available. Restart is not possible.
+
+The "double fault" exception does not occur when detecting a new exception
+while trying to invoke handlers for the following exceptions: 1, 2, 3, 4, 5,
+6, 7, 9, and 16.
+
+If another exception is detected while attempting to perform the double
+fault exception, the 80286 will enter shutdown (see section 11.5).
+
+
+#GP 13 General Protection (Selector or Zero Error Code)
+
+This exception is generated for all protection violations not covered by
+the other exceptions in this section. Examples of this include:
+
+ 1. An attempt to address a memory location by using an offset that
+ exceeds the limit for the segment involved.
+
+ 2. An attempt to jump to a data segment.
+
+ 3. An attempt to load SS with a selector for a read-only segment.
+
+ 4. An attempt to write to a read-only segment.
+
+ 5. Exceeding the maximum instruction length of 10 bytes.
+
+If #GP occurred while loading a descriptor, the error code passed contains
+the selector involved. Otherwise, the error code is zero.
+
+If the error code is not zero, the instruction can be restarted if the
+erroneous condition is rectified. If the error code is zero either a limit
+violation, a write protect violation, or an illegal use of invalid segment
+register occurred. An invalid segment register contains the values 0-3. A
+write protect fault on ADC, SBB, RCL, RCR, or XCHG is not restartable.
+
+
+#MF 16 Math Fault (No Error Code)
+
+This exception is generated when the numeric processor extension (the
+80287) detects an error signalled by the ERROR input pin leading from the
+80287 to the 80286. The ERROR pin is tested at the beginning of most
+floating point instructions, and when a WAIT instruction is executed with
+the EM bit of the Machine Status Word set to 0 (i.e., no emulation of the
+math unit). The floating point instructions that do not cause the ERROR pin
+to be tested are FNCLEX, FNINIT, FSETPM, FNSTCW, FNSTSW, FNSAVE, and
+FNSTENV.
+
+If the handler corrects the error condition causing the exception, the
+floating point instruction that caused #MF can be restarted. This is not
+accomplished by IRET, however, since the fault occurs at the floating point
+instruction that follows the offending instruction. Before restarting the
+numeric instruction, the handler must obtain from the 80287 the address of
+the offending instruction and the address of the optional numeric operand.
+
+
+#MP 9 Math Unit Protection Fault (No Error Code)
+
+This exception is generated if the numeric operand is larger than one word
+and has the second or subsequent words outside the segment's limit. Not all
+math addressing errors cause exception 9. If the effective address of an
+ESCAPE instruction is not in the segment's limit, or if a write is
+attempted on a read-only segment, or if a one-word operand violates a
+segment limit, exception 13 will occur.
+
+The #MP exception occurs during the execution of the numeric instruction by
+the 80287. Thus, the 80286 may be in an unrelated instruction stream at the
+time. Exception 9 may occur in a task unrelated to the task that executed
+the ESC instruction. The operating system should keep track of which task
+last used the NPX (see section 11.4).
+
+The offending floating point instruction cannot be restarted; the task
+which attempted to execute the offending numeric instruction must be
+aborted. However, if exception 9 interrupted another task, the interrupted
+task may be restarted.
+
+The exception 9 handler must execute FNINIT before executing any ESCAPE or
+WAIT instruction.
+
+
+#NM 7 No Math Unit Available (No Error Code)
+
+This exception occurs when any floating point instruction is executed while
+the EM bit or the TS bit of the Machine Status Word is 1. It also occurs
+when a WAIT instruction is encountered and both the MP and TS bits of the
+Machine Status Word are 1.
+
+Depending on the setting of the MSW bits that caused this exception, the
+exception handler could provide emulation of the 80287, or it could perform
+a context switch of the math processor to prepare it for use by another
+task.
+
+The instruction causing #NM can be restarted if the handler performs a
+numeric context switch. If the handler provided emulation of the math unit,
+it should advance the return pointer beyond the floating point instruction
+that caused NM.
+
+
+#NP 11 Not Present (Selector Error Code)
+
+This exception occurs when CS, DS, ES, or the Task Register is loaded with
+a descriptor that is marked not present but is otherwise valid. It can occur
+in an LLDT instruction, but the #NP exception will not occur if the
+processor attempts to load the LDT register during a task switch. A
+not-present LDT encountered during a task switch causes the #TS exception.
+
+The error code passed is the selector of the descriptor that is marked not
+present.
+
+Typically, the Not Present exception handler is used to implement a virtual
+memory system. The operating system can swap inactive memory segments to a
+mass-storage device such as a disk. Applications programs need not be told
+about this; the next time they attempt to access the swapped-out memory
+segment, the Not Present handler will be invoked, the segment will be
+brought back into memory, and the offending instruction within the
+applications program will be restarted.
+
+If #NP is detected on loading CS, DS, or ES in a task switch, the exception
+occurs in the new task, and the IRET from the exception handler jumps
+directly to the next instruction in the new task.
+
+The Not Present exception handler must contain special code to complete the
+loading of segment registers when #NP is detected in loading the CS or DS
+registers in a task switch and a trap or interrupt gate was used. The DS and
+ES registers have been loaded but their descriptors have not been loaded.
+Any memory reference using the segment register may cause exception 13. The
+#NP exception handler should execute code such as the following to ensure
+full loading of the segment registers:
+
+ MOV AX,DS
+ MOV DS,AX
+ MOV AX,ES
+ MOV ES,AX
+
+#SS 12 Stack Fault (Selector or Zero Error Code)
+
+This exception is generated when a limit violation is detected in
+addressing through the SS register. It can occur on stack-oriented
+instructions such as PUSH or POP, as well as other types of memory
+references using SS such as MOV AX,[BP+28]. It also can occur on an ENTER
+instruction when there is not enough space on the stack for the indicated
+local variable space, even if the stack exception is not triggered by
+pushing BP or copying the display stack. A stack exception can therefore
+indicate a stack overflow, a stack underflow or a wild offset. The error
+code will be zero.
+
+#SS is also generated on an attempt to load SS with a descriptor that is
+marked not present but is otherwise valid. This can occur in a task switch,
+an inter-level call, an inter-level return, a move to the SS instruction or
+a pop to the SS instruction. The error code will be non-zero.
+
+#SS is never generated when addressing through the DS or ES registers even
+if the offending register points to the same segment as the SS register.
+
+The #SS exception handler must contain special code to complete the loading
+of segment registers. The DS and ES registers will not be fully loaded if a
+not-present condition is detected while loading the SS register. Therefore,
+the #SS exception handler should execute code such as the following to
+insure full loading of the segment registers:
+
+ MOV AX,DS
+ MOV DS,AX
+ MOV AX,ES
+ MOV ES,AX
+
+Generally, the instruction causing #SS can be restarted, but there is one
+special case when it cannot: when a PUSHA or POPA instruction attempts to
+wrap around the 64K boundary of a stack segment. This condition is
+identified by the value of the saved SP, which can be either 0000H, 0001H,
+0FFFEH, or 0FFFFH.
+
+
+#TS 10 Invalid Task State Segment (Selector Error Code)
+
+This exception is generated during a task switch when the new task state
+segment is invalid, that is, when a task state segment is too small; when
+the LDT indicated in a TSS is invalid or not present; when the SS, CS, DS,
+or ES indicated in a TSS are invalid (task switch); when the back link in a
+TSS is invalid (inter-task IRET).
+
+#TS is not generated when the SS, CS, DS, or ES back link or privileged
+stack selectors point to a descriptor that is not present but otherwise is
+valid. #NP is generated in these cases.
+
+The error code passed to the exception handler contains the selector of the
+offending segment, which can either be the Task State Segment itself, or a
+selector found within the Task State Segment.
+
+The instruction causing #TS can be restarted.
+
+#TS must be handled through a task gate.
+
+The exception handler must reset the busy bit in the new TSS.
+
+
+#UD 6 Undefined Opcode (No Error Code)
+
+This exception is generated when an invalid operation code is detected in
+the instruction stream. Following are the cases in which #UD can occur:
+
+ 1. The first byte of an instruction is completely invalid (e.g., 64H).
+
+ 2. The first byte indicates a 2-byte opcode and the second byte is
+ invalid (e.g., 0FH followed by 0FFH).
+
+ 3. An invalid register is used with an otherwise valid opcode (e.g., MOV
+ CS,AX).
+
+ 4. An invalid opcode extension is given in the REG field of the ModRM
+ byte (e.g., 0F6H /1).
+
+ 5. A register operand is given in an instruction that requires a memory
+ operand (e.g., LGDT AX).
+
+Since the offending opcode will always be invalid, it cannot be restarted.
+However, the #UD handler might be coded to implement an extension of the
+80286 instruction set. In that case, the handler could advance the return
+pointer beyond the extended instruction and return control to the program
+after the extended instruction is emulated. Any such extensions may be
+incompatible with the 80386.
+
+
+Privilege Level and Task Switching on the 80286
+
+The 80286 supports many of the functions necessary to implement a
+protected, multi-tasking operating system in hardware. This support is
+provided not by additional instructions, but by extension of the semantics
+of 8086/8088 instructions that change the value of CS:IP.
+
+Whenever the 80286 performs an inter-segment jump, call, interrupt, or
+return, it consults the Access Rights (AR) byte found in the descriptor
+table entry of the selector associated with the new CS value. The AR byte
+determines whether the long jump being made is through a gate, or is a task
+switch, or is a simple long jump to the same privilege level. Table B-3
+lists the possible values of the AR byte. The "privilege" headings at the
+top of the table give the Descriptor Privilege Level, which is referred to
+as the DPL within the instruction descriptions.
+
+Each of the CALL, INT, IRET, JMP, and RET instructions contains on its
+instruction set pages a listing of the access rights checking and actions
+taken to implement the instruction. Instructions involving task switches
+contain the symbol SWITCH_TASKS, which is an abbreviation for the following
+list of checks and actions:
+
+SWITCH_TASKS:
+ Locked set AR byte of new TSS descriptor to Busy TSS (Bit 1 = 1)
+ Current TSS cache must be valid with limit ≥ 41 else #TS (error code will
+ be new TSS, but back link points at old TSS)
+ Save machine state in current TSS
+ If nesting tasks, set the new TSS link to the current TSS selector
+ Any exception will be in new context Else set the AR byte of current TSS
+ descriptor to Available TSS (Bit 1 = 0)
+ Set the current TR to selector, base and limit of new TSS
+ New TSS limit ≥ 43 else #TS (new TSS)
+ Set all machine registers to values from new TSS without loading
+ descriptors for DS, ES, CS, SS, LDT
+ Clear valid flags for LDT, SS, CS, DS, ES (not valid yet)
+ If nesting tasks, set the Nested Task flag to 1
+ Set the Task Switched flag to 1
+ LDT from the new TSS must be within GDT talbe limits else #TS(LDT)
+ AR byte from LDT descriptor must specifiy LDT segment else #TS(LDT)
+ AR byte from LDT descriptor must indicate PRESENT else #TS(LDT)
+ Load LDT cache with new LDT descriptor and set valid bit
+ Set CPL to the RPL of the CS selector in the new TSS
+ If new stack selector is null #TS(SS)
+ SS selector must be within its descriptor table limits else #TS(SS)
+ SS selector RPL must be equal to CPL else #TS(SS)
+ DPL of SS descriptor must equal to CPL else #TS(SS)
+ SS descriptor AR byte must indicate writable data segment else #TS(SS)
+ SS descriptor AR byte must indicate PRESENT else #TS(SS)
+ Load SS cache with new stack segment and set valid bit
+ New CS selector must not be null else #TS(SS)
+ CS selector must be within its descriptor table limits else #TS(SS)
+ CS descriptor AR byte must indicate code segment else #TS(SS)
+ If non-conforming then DPL must equal CPL else #TS(SS)
+ If conforming then DPL must be ≤ CPL else #TS(SS)
+ CS descriptor AR byte must indicate PRESENT else #TS(SS)
+ Load CS cache with new code segment descriptor and set valid bit
+ For DS and ES:
+ If new selector is not null then perform following checks:
+ Index must be within its descriptor table limits else
+ #TS(segment selector)
+ AR byte must indicate data or readable code else
+ #TS(segment selector)
+ If data or non-conforming code then:
+ DPL must be ≥ CPL else #TS(SS)
+ DPL must be ≥ RPL else #TS(SS)
+ AR byte must indicate PRESENT else #TS(SS)
+ Load cache with new segment descriptor and set valid bit
+
+
+Table B-3. Hexadecimal Values for the Access Rights Byte
+
+
+ Not present, Present, Descriptor Type
+ privilege= privilege=
+0 1 2 3 0 1 2 3
+
+00 20 40 60 80 A0 C0 E0 Illegal
+01 21 41 61 81 A1 C1 E1 Available Task State Segment
+02 22 42 62 82 A2 C2 E2 Local Descriptor Table Segment
+03 23 43 63 83 A3 C3 E3 Busy Task State Segment
+04 24 44 64 84 A4 C4 E4 Call Gate
+05 25 45 65 85 A5 C5 E5 Task Gate
+06 26 46 66 86 A6 C6 E6 Interrupt Gate
+07 27 47 67 87 A7 C7 E7 Trap Gate
+08 28 48 68 88 A8 C8 E8 Illegal
+09 29 49 69 89 A9 C9 E9 Illegal
+0A 2A 4A 6A 8A AA CA EA Illegal
+0B 2B 4B 6B 8B AB CB EB Illegal
+0C 2C 4C 6C 8C AC CC EC Illegal
+0D 2D 4D 6D 8D AD CD ED Illegal
+0E 2E 4E 6E 8E AE CE EE Illegal
+0F 2F 4F 6F 8F AF CF EF Illegal
+10 30 50 70 90 B0 D0 F0 Expand-up, read only, ignored Data Segment
+11 31 51 71 91 B1 D1 F1 Expand-up, read only, accessed Data Segment
+12 32 52 72 92 B2 D2 F2 Expand-up, writable, ignored Data Segment
+13 33 53 73 93 B3 D3 F3 Expand-up, writable, accessed Data Segment
+14 34 54 74 94 B4 D4 F4 Expand-down, read only, ignored Data Segment
+15 35 55 75 95 B5 D5 F5 Expand-down, read only, accessed Data Segment
+16 36 56 76 96 B6 D6 F6 Expand-down, writable, ignored Data Segment
+17 37 57 77 97 B7 D7 F7 Expand-down, writable, accessed Data Segment
+18 38 58 78 98 B8 D8 F8 Non-conform, no read, ignored Code Segment
+19 39 59 79 99 B9 D9 F9 Non-conform, no read, accessed Code Segment
+1A 3A 5A 7A 9A BA DA FA Non-conform, readable, ignored Code Segment
+1B 3B 5B 7B 9B BB DB FB Non-conform, readable, accessed Code Segment
+1C 3C 5C 7C 9C BC DC FC Conforming, no read, ignored Code Segment
+1D 3D 5D 7D 9D BD DD FD Conforming, no read, accessed Code Segment
+1E 3E 5E 7E 9E BE DE FE Conforming, readable, ignored Code Segment
+1F 3F 5F 7F 9F BF DF FF Conforming, readable, accessed Code Segment
+
+
+AAA──ASCII Adjust AL After Addition
+
+Opcode Instruction Clocks Description
+
+ 37 AAA 3 ASCII adjust AL after addition
+
+Flags Mofified
+
+Auxiliary carry, carry
+
+Flags Undefined
+
+Overflow, sign, zero, parity
+
+Operation
+
+AAA should be executed only after an ADD instruction which leaves a byte
+result in the AL register. The lower nibbles of the operands to the ADD
+instruction should be in the range 0 through 9 (BCD digits). In this case,
+the AAA instruction will adjust AL to contain the correct decimal digit
+result. If the addition produced a decimal carry, the AH register is
+incremented, and the carry and auxiliary carry flags are set to 1. If there
+was no decimal carry, the carry and auxiliary carry flags are set to 0, and
+AH is unchanged. In any case, AL is left with its top nibble set to 0. To
+convert AL to an ASCII result, you can follow the AAA instruction with OR
+AL,30H.
+
+The precise definition of AAA is as follows: if the lower 4 bits of AL are
+greater than nine, or if the auxiliary carry flag is 1, then increment AL by
+6, AH by 1, and set the carry and auxiliary carry flags. Otherwise, reset
+the carry and auxiliary carry flags. In any case, conclude the AAA
+operation by setting the upper four bits of AL to zero.
+
+Protected Mode Exceptions
+
+None
+
+Real Address Mode Exceptions
+
+None
+
+AAD──ASCII Adjust AX Before Division
+
+Opcode Instruction Clocks Description
+
+ D5 0A AAD 14 ASCII adjust AX before division
+
+Flags Modified
+
+Sign, zero, parity
+
+Flags Undefined
+
+Overflow, auxiliary carry, carry
+
+Operation
+
+AAD is used to prepare two unpacked BCD digits (least significant in AL,
+most significant in AH) for a division operation which will yield an
+unpacked result. This is accomplished by setting AL to AL + (10 * AH), and
+then setting AH to 0. This leaves AX equal to the binary equivalent of the
+original unpacked 2-digit number.
+
+Protected Mode Exceptions
+
+None
+
+Real Address Mode Exceptions
+
+None
+
+
+AAM──ASCII Adjust AX After Multiply
+
+Opcode Instruction Clocks Description
+
+ D4 0A AAM 16 ASCII adjust AX after multiply
+
+Flags Modified
+
+Sign, zero, parity
+
+Flags Undefined
+
+Overflow, auxiliary carry, carry
+
+Operation
+
+AAM should be used only after executing a MUL instruction between two
+unpacked BCD digits, leaving the result in the AX register. Since the result
+is less than one hundred, it is contained entirely in the AL register. AAM
+unpacks the AL result by dividing AL by ten, leaving the quotient (most
+significant digit) in AH, and the remainder (least significant digit) in
+AL.
+
+Protected Mode Exceptions
+
+None
+
+Real Address Mode Exceptions
+
+None
+
+
+AAS──ASCII Adjust AL After Subtraction
+
+Opcode Instruction Clocks Description
+
+ 3F AAS 3 ASCII adjust AL after subtraction
+
+Flags Modified
+
+Auxiliary carry, carry
+
+Flags Undefined
+
+Overflow, sign, zero, parity
+
+Operation
+
+AAS should be executed only after a subtraction instruction which left the
+byte result in the AL register. The lower nibbles of the operands to the SUB
+instruction should have been in the range 0 through 9 (BCD digits). In this
+case, the AAS instruction will adjust AL to contain the correct decimal
+digit result. If the subtraction produced a decimal carry, the AH register
+is decremented, and the carry and auxiliary carry flags are set to 1. If
+there was no decimal carry, the carry and auxiliary carry flags are set to
+0, and AH is unchanged. In any case, AL is left with its top nibble set to
+0. To convert AL to an ASCII result, you can follow the AAS instruction with
+OR AL,30H.
+
+The precise definition of AAS is as follows: if the lower four bits of AL
+are greater than 9, or if the auxiliary carry flag is 1, then decrement AL
+by 6, AH by 1, and set the carry and auxiliary carry flags. Otherwise, reset
+the carry and auxiliary carry flags. In any case, conclude the AAS
+operation by setting the upper four bits of AL to zero.
+
+Protected Mode Exceptions
+
+None
+
+Real Address Mode Exceptions
+
+None
+
+
+ADC/ADD──Integer Addition
+
+
+Opcode Instruction Clocks Description
+
+10 /r ADC eb,rb 2,mem=7 Add with carry byte register into EA byte
+11 /r ADC ew,rw 2,mem=7 Add with carry word register into EA word
+12 /r ADC rb,eb 2,mem=7 Add with carry EA byte into byte register
+13 /r ADC rw,ew 2,mem=7 Add with carry EA word into word register
+14 db ADC AL,db 3 Add with carry immediate byte into AL
+15 dw ADC AX,dw 3 Add with carry immediate word into AX
+80 /2 db ADC eb,db 3,mem=7 Add with carry immediate byte into EA byte
+81 /2 dw ADC ew,dw 3,mem=7 Add with carry immediate word into EA word
+83 /2 db ADC ew,db 3,mem=7 Add with carry immediate byte into EA word
+00 /r ADD eb,rb 2,mem=7 Add byte register into EA byte
+01 /r ADD ew,rw 2,mem=7 Add word register into EA word
+02 /r ADD rb,eb 2,mem=7 Add EA byte into byte register
+03 /r ADD rw,ew 2,mem=7 Add EA word into word register
+04 db ADD AL,db 3 Add immediate byte into AL
+05 dw ADD AX,dw 3 Add immediate word into AX
+80 /0 db ADD eb,db 3,mem=7 Add immediate byte into EA byte
+81 /0 dw ADD ew,dw 3,mem=7 Add immediate word into EA word
+83 /0 db ADD ew,db 3,mem=7 Add immediate byte into EA word
+
+
+Flags Modified
+
+Overflow, sign, zero, auxiliary carry, parity, carry
+
+Flags Undefined
+
+None
+
+Operation
+
+ADD and ADC perform an integer addition on the two operands. The ADC
+instruction also adds in the initial state of the carry flag. The result of
+the addition goes to the first operand. ADC is usually executed as part of a
+multi-byte or multi-word addition operation.
+
+When a byte immediate value is added to a word operand, the immediate value
+is first sign-extended.
+
+Protected Mode Exceptions
+
+#GP(0) if the result is in a non-writable segment. #GP(0) for an illegal
+memory operand effective address in the CS, DS, or ES segments; #SS(0) for
+an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+AND──Logical AND
+
+Opcode Instruction Clocks Description
+
+20 /r AND eb,rb 2,mem=7 Logical-AND byte register into EA byte
+21 /r AND ew,rw 2,mem=7 Logical-AND word register into EA word
+22 /r AND rb,eb 2,mem=7 Logical-AND EA byte into byte register
+23 /r AND rw,ew 2,mem=7 Logical-AND EA word into word register
+24 db AND AL,db 3 Logical-AND immediate byte into AL
+25 dw AND AX,dw 3 Logical-AND immediate word into AX
+80 /4 db AND eb,db 3,mem=7 Logical-AND immediate byte into EA byte
+81 /4 dw AND ew,dw 3,mem=7 Logical-AND immediate word into EA word
+
+Flags Modified
+
+Overflow=0, sign, zero, parity, carry=0
+
+Flags Undefined
+
+Auxiliary carry
+
+Operation
+
+Each bit of the result is a 1 if both corresponding bits of the operands
+were 1; it is 0 otherwise.
+
+Protected Mode Exceptions
+
+#GP(0) if the result is in a non-writable segment. #GP(0) for an illegal
+memory operand effective address in the CS, DS, or ES segments; #SS(0) for
+an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+ARPL──Adjust RPL Field of Selector
+
+Opcode Instruction Clocks Description
+
+63 /r ARPL ew,rw 10,mem=11 Adjust RPL of EA word not less than
+ RPL of rw
+
+Flags Modified
+
+Zero
+
+Flags Undefined
+
+None
+
+Operation
+
+The ARPL instruction has two operands. The first operand is a 16-bit memory
+variable or word register that contains the value of a selector. The second
+operand is a word register. If the RPL field (bottom two bits) of the first
+operand is less than the RPL field of the second operand, then the zero
+flag is set to 1 and the RPL field of the first operand is increased to
+match the second RPL. Otherwise, the zero flag is set to 0 and no change is
+made to the first operand.
+
+ARPL appears in operating systems software, not in applications programs.
+It is used to guarantee that a selector parameter to a subroutine does not
+request more privilege than the caller was entitled to. The second operand
+used by ARPL would normally be a register that contains the CS selector
+value of the caller.
+
+Protected Mode Exceptions
+
+#GP(0) if the result is in a non-writable segment. #GP(0) for an illegal
+memory operand effective address in the CS, DS, or ES segments; #SS(0) for
+an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 6. ARPL is not recognized in Real Address mode.
+
+
+BOUND──Check Array Index Against Bounds
+
+Opcode Instruction Clocks Description
+
+ 62 /r BOUND rw,md noj=13 INT 5 if rw not within bounds
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+BOUND is used to ensure that a signed array index is within the limits
+defined by a two-word block of memory. The first operand (a register) must
+be greater than or equal to the first word in memory, and less than or equal
+to the second word in memory. If the register is not within the bounds, an
+INTERRUPT 5 occurs.
+
+The two-word block might typically be found just before the array itself
+and therefore would be accessible at a constant offset of -4 from the array,
+simplifying the addressing.
+
+Protected Mode Exceptions
+
+INTERRUPT 5 if the bounds test fails, as described above. #GP(0) for an
+illegal memory operand effective address in the CS, DS, or ES segments;
+#SS(0) for an illegal address in the SS segment.
+
+The second operand must be a memory operand, not a register. If the BOUND
+instruction is executed with a ModRM byte representing a register second
+operand, then fault #UD will occur.
+
+Real Address Mode Exceptions
+
+INTERRUPT 5 if the bounds test fails, as described above. Interrupt 13 for
+a second operand at offset 0FFFDH or higher. Interrupt 6 if the second
+operand is a register, as described in the paragraph above.
+
+
+CALL──Call Procedure
+
+
+Opcode Instruction Clocks
+Add one clock for each byte in the next instruction executed. Description
+
+E8 cw CALL cw 7 Call near, offset relative to
+ next instruction
+FF /2 CALL ew 7,mem=11 Call near, offset absolute at EA word
+9A cd CALL cd 13,pm=26 Call inter-segment, immediate
+ 4-byte address
+9A cd CALL cd 41 Call gate, same privilege
+9A cd CALL cd 82 Call gate, more privilege,
+ no parameters
+9A cd CALL cd 86+4X Call gate, more privilege,
+ X parameters
+9A cd CALL cd 177 Call via Task State Segment
+9A cd CALL cd 182 Call via task gate
+FF /3 CALL ed 16,mem=29 Call inter-segment, address at
+ EA doubleword
+FF /3 CALL ed 44 Call gate, same privilege
+FF /3 CALL ed 83 Call gate, more privilege,
+ no parameters
+FF /3 CALL ed 90+4X Call gate, more privilege,
+ X parameters
+FF /3 CALL ed 180 Call via Task State Segment
+FF /3 CALL ed 185 Call via task gate
+
+
+Flags Modified
+
+None, except when a task switch occurs
+
+Flags Undefined
+
+None
+
+Operation
+
+The CALL instruction causes the procedure named in the operand to be
+executed. When the procedure is complete (a return instruction is executed
+within the procedure), execution continues at the instruction that follows
+the CALL instruction.
+
+The CALL cw form of the instruction adds modulo 65536 (the 2-byte operand)
+to the offset of the instruction following the CALL and sets IP to the
+resulting offset. The 2-byte offset of the instruction that follows the CALL
+is pushed onto the stack. It will be popped by a near RET instruction
+within the procedure. The CS register is not changed by this form.
+
+The CALL ew form of the instruction is the same as CALL cw except that the
+operand specifies a memory location from which the absolute 2-byte offset
+for the procedure is fetched.
+
+The CALL cd form of the instruction uses the 4-byte operand as a pointer to
+the procedure called. The CALL ed form fetches the long pointer from the
+memory location specified. Both long pointer forms consult the AR byte in
+the descriptor indexed by the selector part of the long pointer. The AR byte
+can indicate one of the following descriptor types:
+
+ 1. Code Segment──The access rights are checked, the return pointer is
+ pushed onto the stack, and the procedure is jumped to.
+
+ 2. Call Gate──The offset part of the pointer is ignored. Instead, the
+ entire address of the procedure is taken from the call gate descriptor
+ entry. If the routine being entered is more privileged, then a new
+ stack (both SS and SP) is loaded from the task state segment for the
+ new privilege level, and parameters determined by the wordcount field
+ of the call gate are copied from the old stack to the new stack.
+
+ 3. Task Gate──The current task's context is saved in its Task State
+ Segment (TSS), and the TSS named in the task-gate is used to load the
+ new context. The selector for the outgoing task (from TR) is stored
+ into the new TSS's link field, and the new task's Nested Task flag is
+ set. The outgoing task is left marked busy, the new TSS is marked
+ busy, and execution resumes at the point at which the new task was
+ last suspended.
+
+ 4. Task State Segment──The current task is suspended and the new task
+ initiated as in 3 above except that there is no intervening gate.
+
+For long calls involving no task switch, the return link is the pointer of
+the instruction that follows the CALL, i.e., the caller's CS and updated IP.
+Task switches invoked by CALLs are linked by storing the outgoing task's TSS
+selector in the incoming TSS's link field and setting the Nested Task flag
+in the new task. Nested tasks must be terminated by an IRET. IRET releases
+the nested task and follows the back link to the calling task if the NT flag
+is set.
+
+A precise list of the protection checks made and the actions taken is given
+by the following list:
+
+CALL FAR:
+ If indirect then check access of EA doubleword #GP(0) if limit violation
+ New CS selector must not be null else #GP(0)
+ Check that new CS selector index is within its descriptor table limits;
+ else #GP (new CS selector)
+ Examine AR byte of selected descriptor for various legal values:
+
+ CALL CONFORMING CODE SEGMENT:
+ DPL must be ≤ CPL else #GP (code segment selector)
+ Segment must be PRESENT else #NP (code segment selector)
+ Stack must be big enough for return address else #SS(0)
+ IP must be in code segment limit else #GP(0)
+ Load code segment descriptor into CS cache
+ Load CS with new code segment selector
+ Load IP with new offset
+
+ CALL NONCONFORMING CODE SEGMENT:
+ RPL must be ≤ CPL else #GP (code segment selector)
+ DPL must be = CPL else #GP (code segment selector)
+ Segment must be PRESENT else #NP (code segment selector)
+ Stack must be big enough for return address else #SS(0)
+ IP must be in code segment limit else #GP(0)
+ Load code segment descriptor into CS cache
+ Load CS with new code segment selector
+ Set RPL of CS to CPL
+ Load IP with new offset
+
+ CALL TO CALL GATE:
+ Call gate DPL must be ≥ CPL else #GP (call gate selector)
+ Call gate DPL must be ≥ RPL else #GP (call gate selector)
+ Call gate must be PRESENT else #NP (call gate selector)
+ Examine code segment selector in call gate descriptor:
+ Selector must not be null else #GP(0)
+ Selector must be within its descriptor table limits else #GP (code
+ segment selector)
+ AR byte of selected descriptor must indicate code segment else #GP
+ (code segment selector)
+ DPL of selected descriptor must be ≤ CPL else #GP(code segment
+ selector)
+ If non-conforming code segment and DPL < CPL then
+
+ CALL GATE TO MORE PRIVILEGE:
+ Get new SS selector for new privilege level from TSS
+ Check selector and descriptor for new SS:
+ Selector must not be null else #TS(0)
+ Selector index must be within its descriptor table limits else #TS
+ (SS selector)
+ Selector's RPL must equal DPL of code segment else #TS (SS selector)
+ Stack segment DPL must equal DPL of code segment else #TS
+ (SS selector)
+ Descriptor must indicate writable data segment else #TS (SS selector)
+ Segment PRESENT else #SS (SS selector)
+ New stack must have room for parameters plus 8 bytes else #SS(0)
+ IP must be in code segment limit else #GP(0)
+ Load new SS:SP value from TSS
+ Load new CS:IP value from gate
+ Load CS descriptor
+ Load SS descriptor
+ Push long pointer of old stack onto new stack
+ Get word count from call gate, mask to 5 bits
+ Copy parameters from old stack onto new stack
+ Push return address onto new stack
+ Set CPL to stack segment DPL
+ Set RPL of CS to CPL
+ Else
+ CALL GATE TO SAME PRIVILEGE:
+ Stack must have room for 4-byte return address else #SS(0)
+ IP must be in code segment limit else #GP(0)
+ Load CS:IP from gate
+ Push return address onto stack
+ Load code segment descriptor into CS-cache
+ Set RPL of CS to CPL
+
+ CALL TASK GATE:
+ Task gate DPL must be ≥ CPL else #GP (gate selector)
+ Task gate DPL must be ≥ RPL else #GP (gate selector)
+ Task Gate must be PRESENT else #NP (gate selector)
+ Examine selector to TSS, given in Task Gate descriptor:
+ Must specify global in the local/global bit else #GP
+ (TSS selector)
+ Index must be within GDT limits else #GP (TSS selector)
+ TSS descriptor AR byte must specify available TSS (bottom bits
+ 00001) else #GP (TSS selector)
+ Task State Segment must be PRESENT else #NP (TSS selector)
+ SWITCH_TASKS with nesting to TSS
+ IP must be in code segment limit else #GP(0)
+
+ TASK STATE SEGMENT:
+ TSS DPL must be ≥ CPL else #GP (TSS selector)
+ TSS DPL must be ≥ RPL else #GP (TSS selector)
+ TSS descriptor AR byte must specify available TSS else #GP
+ (TSS selector)
+ Task State Segment must be PRESENT else #NP (TSS selector)
+ SWITCH_TASKS with nesting to TSS
+ IP must be in code segment limit else #GP(0)
+
+ ELSE #GP (code segment selector)
+
+Protected Mode Exceptions
+
+FAR calls: #GP, #NP, #SS, and #TS, as indicated in the list above.
+
+NEAR direct calls: #GP(0) if procedure location is beyond the code segment
+limits.
+
+NEAR indirect CALL: #GP(0) for an illegal memory operand effective address
+in the CS, DS, or ES segments; #SS(0) for an illegal address in the SS
+segment. #GP if the indirect offset obtained is beyond the code segment
+limits.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+CBW──Convert Byte into Word
+
+Opcode Instruction Clocks Description
+
+ 98 CBW 2 Convert byte into word (AH = top bit of AL)
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+CBW converts the signed byte in AL to a signed word in AX. It does so by
+extending the top bit of AL into all of the bits of AH.
+
+Protected Mode Exceptions
+
+None
+
+Real Address Mode Exceptions
+
+None
+
+
+CLC──Clear Carry Flag
+
+Opcode Instruction Clocks Description
+
+ F8 CLC 2 Clear carry flag
+
+Flags Modified
+
+Carry=0
+
+Flags Undefined
+
+None
+
+Operation
+
+CLC sets the carry flag to zero. No other flags or registers are affected.
+
+Protected Mode Exceptions
+
+None
+
+Real Address Mode Exceptions
+
+None
+
+
+CLD──Clear Direction Flag
+
+Opcode Instruction Clocks Description
+
+ FC CLD 2 Clear direction flag, SI and DI
+ will increment
+
+Flags Modified
+
+Direction=0
+
+Flags Undefined
+
+None
+
+Operation
+
+CLD clears the direction flag. No other flags or registers are affected.
+After CLD is executed, string operations will increment the index registers
+(SI and/or DI) that they use.
+
+Protected Mode Exceptions
+
+None
+
+Real Address Mode Exceptions
+
+None
+
+
+CLI──Clear Interrupt Flag
+
+Opcode Instruction Clocks Description
+
+ FA CLI 3 Clear interrupt flag; interrupts disabled
+
+Flags Modified
+
+Interrupt=0
+
+Flags Undefined
+
+None
+
+Operation
+
+CLI clears the interrupt enable flag if the current privilege level is at
+least as privileged as IOPL. No other flags are affected. External
+interrupts will not be recognized at the end of the CLI instruction or
+thereafter until the interrupt flag is set.
+
+Protected Mode Exceptions
+
+#GP(0) if the current privilege level is bigger (has less privilege) than
+the IOPL in the flags register. IOPL specifies the least privileged level at
+which I/O may be performed.
+
+Real Address Mode Exceptions
+
+None
+
+
+CLTS──Clear Task Switched Flag
+
+Opcode Instruction Clocks Description
+
+ 0F 06 CLTS 2 Clear task switched flag
+
+Flags Modified
+
+Task switched=0
+
+Flags Undefined
+
+None
+
+Operation
+
+CLTS clears the task switched flag in the Machine Status Word. This flag is
+set by the 80286 every time a task switch occurs. The TS flag is used to
+manage processor extensions as follows: every execution of a WAIT or an ESC
+instruction will be trapped if the MP flag of MSW is set and the task
+switched flag is set. Thus, if a processor extension is present and a task
+switch has been made since the last ESC instruction was begun, the processor
+extension's context must be saved before a new instruction can be issued.
+The fault routine will save the context and reset the task switched flag or
+place the task requesting the processor extension into a queue until the
+current processor extension instruction is completed.
+
+CLTS appears in operating systems software, not in applications programs.
+It is a privileged instruction that can only be executed at level 0.
+
+Protected Mode Exceptions
+
+#GP(0) if CLTS is executed with a current privilege level other than 0.
+
+Real Address Mode Exceptions
+
+None (valid in REAL ADDRESS MODE to allow power-up initialization for
+Protected Mode)
+
+
+CMC──Complement Carry Flag
+
+Opcode Instruction Clocks Description
+
+ F5 CMC 2 Complement carry flag
+
+Flags Modified
+
+Carry
+
+Flags Undefined
+
+None
+
+Operation
+
+CMC reverses the setting of the carry flag. No other flags are affected.
+
+Protected Mode Exceptions
+
+None
+
+Real Address Mode Exceptions
+
+None
+
+
+CMP──Compare Two Operands
+
+Opcode Instruction Clocks Description
+
+3C db CMP AL,db 3 Compare immediate byte from AL
+3D dw CMP AX,dw 3 Compare immediate word from AX
+80 /7 db CMP eb,db 3,mem=6 Compare immediate byte from EA byte
+38 /r CMP eb,rb 2,mem=7 Compare byte register from EA byte
+83 /7 db CMP ew,db 3,mem=6 Compare immediate byte from EA word
+81 /7 dw CMP ew,dw 3,mem=6 Compare immediate word from EA word
+39 /r CMP ew,rw 2,mem=7 Compare word register from EA word
+3A /r CMP rb,eb 2,mem=6 Compare EA byte from byte register
+3B /r CMP rw,ew 2,mem=6 Compare EA word from word register
+
+Flags Modified
+
+Overflow, sign, zero, auxiliary carry, parity, carry
+
+Flags Undefined
+
+None
+
+Operation
+
+CMP subtracts the second operand from the first operand, but it does not
+place the result anywhere. Only the flags are changed by this instruction.
+CMP is usually followed by a conditional jump instruction. See the "Jcond"
+instructions in this chapter for the list of signed and unsigned flag tests
+provided by the 80286.
+
+If a word operand is compared to an immediate byte value, the byte value is
+first sign-extended.
+
+Protected Mode Exceptions
+
+#GP(0) for an illegal memory operand effective address in the CS, DS, or ES
+segments; #SS(0) for an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+CMPS/CMPSB/CMPSW──Compare string operands
+
+Opcode Instruction Clocks Description
+
+A6 CMPS mb,mb 8 Compare bytes ES:[DI] from [SI]
+A6 CMPSB 8 Compare bytes ES:[DI] from DS:[SI]
+A7 CMPSW 8 Compare words ES:[DI] from DS:[SI]
+
+Flags Modified
+
+Overflow, sign, zero, auxiliary carry, parity, carry
+
+Flags Undefined
+
+None
+
+Operation
+
+CMPS compares the byte or word pointed to by SI with the byte or word
+pointed to by DI by performing the subtraction [SI] - [DI]. The result is
+not placed anywhere; only the flags reflect the result of the subtraction.
+The types of the operands to CMPS determine whether bytes or words are
+compared. The segment addressability of the first (SI) operand determines
+whether a segment override byte will be produced or whether the default
+segment register DS is used. The second (DI) operand must be addressible
+from the ES register; no segment override is possible.
+
+After the comparison is made, both SI and DI are automatically advanced. If
+the direction flag is 0 (CLD was executed), the registers increment; if the
+direction flag is 1 (STD was executed), the registers decrement. The
+registers increment or decrement by 1 if a byte was moved; by 2 if a word
+was moved.
+
+CMPS cn be preceded by the REPE or REPNE prefix for block comparison of CX
+bytes or words. Refer to the REP instruction for details of this operation.
+
+Protected Mode Exceptions
+
+#GP(0) for an illegal memory operand effective address in the CS, DS, or ES
+segments; #SS(0) for an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+CWD──Convert Word to Doubleword
+
+Opcode Instruction Clocks Description
+
+99 CWD 2 Convert word to doubleword (DX:AX = AX)
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+CWD converts the signed word in AX to a signed doubleword in DX:AX. It does
+so by extending the top bit of AX into all the bits of DX.
+
+Protected Mode Exceptions
+
+None
+
+Real Address Mode Exceptions
+
+None
+
+
+DAA──Decimal Adjust AL After Addition
+
+Opcode Instruction Clocks Description
+
+27 DAA 3 Decimal adjust AL after addition
+
+Flags Modified
+
+Sign, zero, auxiliary carry, parity, carry
+
+Flags Undefined
+
+Overflow
+
+Operation
+
+DAA should be executed only after an ADD instruction which leaves a
+two-BCD-digit byte result in the AL register. The ADD operands should
+consist of two packed BCD digits. In this case, the DAA instruction will
+adjust AL to contain the correct two-digit packed decimal result.
+
+The precise definition of DAA is as follows:
+
+ 1. If the lower 4 bits of AL are greater than nine, or if the auxiliary
+ carry flag is 1, then increment AL by 6, and set the auxiliary carry
+ flag. Otherwise, reset the auxiliary carry flag.
+
+ 2. If AL is now greater than 9FH, or if the carry flag is set, then
+ increment AL by 60H, and set the carry flag. Otherwise, clear the
+ carry flag.
+
+Protected Mode Exceptions
+
+None
+
+Real Address Mode Exceptions
+
+None
+
+
+DAS──Decimal Adjust AL After Subtraction
+
+Opcode Instruction Clocks Description
+
+2F DAS 3 Decimal adjust AL after subtraction
+
+Flags Modified
+
+Sign, zero, auxiliary carry, parity, carry
+
+Flags Undefined
+
+Overflow
+
+Operation
+
+DAS should be executed only after a subtraction instruction which leaves a
+two-BCD-digit byte result in the AL register. The operands should consist of
+two packed BCD digits. In this case, the DAS instruction will adjust AL to
+contain the correct packed two-digit decimal result.
+
+The precise definition of DAS is as follows:
+
+ 1. If the lower four bits of AL are greater than 9, or if the auxiliary
+ carry flag is 1, then decrement AL by 6, and set the auxiliary carry
+ flag. Otherwise, reset the auxiliary carry flag.
+
+ 2. If AL is now greater than 9FH, or if the carry flag is set, then
+ decrement AL by 60H, and set the carry flag. Otherwise, clear the
+ carry flag.
+
+Protected Mode Exceptions
+
+None
+
+Real Address Mode Exceptions
+
+None
+
+
+DEC──Decrement by 1
+
+Opcode Instruction Clocks Description
+
+FE /1 DEC eb 2,mem=7 Decrement EA byte by 1
+FF /1 DEC ew 2,mem=7 Decrement EA word by 1
+48+ rw DEC rw 2 Decrement word register by 1
+
+Flags Modified
+
+Overflow, sign, zero, auxiliary carry, parity
+
+Flags Undefined
+
+None
+
+Operation
+
+1 is subtracted from the operand. Note that the carry flag is not changed
+by this instruction. If you want the carry flag set, use the SUB instruction
+with a second operand of 1.
+
+Protected Mode Exceptions
+
+#GP(0) if the operand is in a non-writable segment. #GP(0) for an illegal
+memory operand effective address in the CS, DS, or ES segments; #SS(0) for
+an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+DIV──Unsigned Divide
+
+Opcode Instruction Clocks Description
+
+F6 /6 DIV eb 14,mem=17 Unsigned divide AX by EA byte
+F7 /6 DIV ew 22,mem=25 Unsigned divide DX:AX by
+ EA word
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+Overflow, sign, zero, auxiliary carry, parity, carry
+
+Operation
+
+DIV performs an unsigned divide. The dividend is implicit; only the divisor
+is given as an operand. If the source operand is a BYTE operand, divide AX
+by the byte. The quotient is stored in AL, and the remainder is stored in
+AH. If the source operand is a WORD operand, divide DX:AX by the word. The
+high-order 16 bits of the dividend are kept in DX. The quotient is stored
+in AX, and the remainder is stored in DX. Non-integral quotients are
+truncated towards 0. The remainder is always less than the dividend.
+
+Protected Mode Exceptions
+
+Interrupt 0 if the quotient is too big to fit in the designated register
+(AL or AX), or if the divisor is zero. #GP(0) for an illegal memory operand
+effective address in the CS, DS, or ES segments; #SS(0) for an illegal
+address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 0 if the quotient is too big to fit in the designated register
+(AL or AX), or if the divisor is zero. Interrupt 13 for a word operand at
+offset 0FFFFH.
+
+
+ENTER──Make Stack Frame for Procedure Parameters
+
+Opcode Instruction Clocks Description
+
+C8 dw 00 ENTER dw,0 11 Make stack frame for procedure parameters
+C8 dw 01 ENTER dw,1 15 Make stack frame for procedure parameters
+C8 dw db ENTER dw,db 12+4db Make stack frame for procedure parameters
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+ENTER is used to create the stack frame required by most block-structured
+high-level languages. The first operand specifies how many bytes of dynamic
+storage are to be allocated on the stack for the routine being entered. The
+second operand gives the lexical nesting level of the routine within the
+high-level-language source code. It determines how many stack frame
+pointers are copied into the new stack frame from the preceding frame. BP is
+used as the current stack frame pointer.
+
+If the second operand is 0, ENTER pushes BP, sets BP to SP, and subtracts
+the first operand from SP.
+
+For example, a procedure with 12 bytes of local variables would have an
+ENTER 12,0 instruction at its entry point and a LEAVE instruction before
+every RET. The 12 local bytes would be addressed as negative offsets from
+[BP]. See also section 4.2.
+
+The formal definition of the ENTER instruction for all cases is given by
+the following listing. LEVEL denotes the value of the second operand.
+
+LEVEL:=LEVEL MOD 32
+Push BP
+Set a temporary value FRAME_PTR := SP
+If LEVEL > 0 then
+ Repeat (LEVEL-1) times:
+ BP := BP - 2
+ Push the word pointed to by BP
+ End repeat
+ Push FRAME_PTR
+End if
+BP := FRAME-PTR
+SP := SP - first operand
+
+Protected Mode Exceptions
+
+#SS(0) if SP were to go outside of the stack limit within any part of the
+instruction execution.
+
+Real Address Mode Exceptions
+
+None
+
+
+HLT──Halt
+
+Opcode Instruction Clocks Description
+
+F4 HLT 2 Halt
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+Successful execution of HLT causes the 80286 to cease executing
+instructions and to enter a HALT state. Execution resumes only upon receipt
+of an enabled interrupt or a reset. If an interrupt is used to resume
+program execution after HLT, the saved CS:IP value will point to the
+instruction that follows HLT.
+
+Protected Mode Exceptions
+
+HLT is a privileged instruction. #GP(0) if the current privilege level is
+not 0.
+
+Real Address Mode Exceptions
+
+None
+
+
+IDIV──Signed Divide
+
+Opcode Instruction Clocks Description
+
+F6 /7 IDIV eb 17,mem=20 Signed divide AX by EA byte
+ (AL=Quo,AH=Rem)
+F7 /7 IDIV ew 25,mem=28 Signed divide DX:AX by
+ EA word (AX=Quo,DX=Rem)
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+Overflow, sign, zero, auxiliary carry, parity, carry
+
+Operation
+
+IDIV performs a signed divide. The dividend is implicit; only the divisor
+is given as an operand. If the source operand is a BYTE operand, divide AX
+by the byte. The quotient is stored in AL, and the remainder is stored in
+AH. If the source operand is a WORD operand, divide DX:AX by the word. The
+high-order 16 bits of the dividend are in DX. The quotient is stored in AX,
+and the remainder is stored in DX. Non-integral quotients are truncated
+towards 0. The remainder has the same sign as the dividend and always has
+less magnitude than the dividend.
+
+Protected Mode Exceptions
+
+Interrupt 0 if the quotient is too big to fit in the designated register
+(AL or AX), or if the divisor is 0. #GP(0) for an illegal memory operand
+effective address in the CS, DS, or ES segments; #SS(0) for an illegal
+address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 0 if the quotient is too big to fit in the designated register
+(AL or AX), or if the divisor is 0. Interrupt 13 for a word operand at
+offset 0FFFFH.
+
+
+IMUL──Signed Multiply
+
+Opcode Instruction Clocks Description
+
+F6 /5 IMUL eb 13,mem=16 Signed multiply (AX = AL * EA byte)
+F7 /5 IMUL ew 21,mem=24 Signed multiply (DXAX = AX * EA word)
+6B /r db IMUL rw,db 21,mem=24 Signed multiply imm. byte
+ into word reg.
+69 /r dw IMUL rw,ew,dw 21,mem=24 Signed multiply
+ (rw = EA word * imm. word)
+6B /r db IMUL rw,ew,db 21,mem=24 Signed multiply
+ (rw = EA word * imm. byte)
+
+Flags Modified
+
+Overflow, carry
+
+Flags Undefined
+
+Sign, zero, auxiliary carry, parity
+
+Operation
+
+IMUL performs signed multiplication. If IMUL has a single byte source
+operand, then the source is multiplied by AL and the 16-bit signed result is
+left in AX. Carry and overflow are set to 0 if AH is a sign extension of AL;
+they are set to 1 otherwise.
+
+If IMUL has a single word source operand, then the source operand is
+multiplied by AX and the 32-bit signed result is left in DX:AX. DX contains
+the high-order 16 bits of the product. Carry and overflow are set to 0 if DX
+is a sign extension of AX; they are set to 1 otherwise.
+
+If IMUL has three operands, then the second operand (an effective address
+word) is multiplied by the third operand (an immediate word), and the 16
+bits of the result are placed in the first operand (a word register). Carry
+and overflow are set to 0 if the result fits in a signed word (between
+-32768 and +32767, inclusive); they are set to 1 otherwise.
+
+The low 16 bits of the product of a 16-bit signed multiply are the same as
+those of an unsigned multiply. The three operand IMUL instruction can be
+used for unsigned operands as well.
+
+Protected Mode Exceptions
+
+#GP(0) for an illegal memory operand effective address in the CS, DS, or ES
+segments; #SS(0) for an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+IN──Input from Port
+
+Opcode Instruction Clocks Description
+
+E4 db IN AL,db 5 Input byte from immediate portinto AL
+EC IN AL,DX 5 Input byte from port DX into AL
+E5 db IN AX,db 5 Input word from immediate portinto AX
+ED IN AX,DX 5 Input word from port DX into AX
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+IN transfers a data byte or data word from the port numbered by the second
+operand into the register (AL or AX) given as the first operand. You can
+access any port from 0 to 65535 by placing the port number in the DX
+register then using an IN instruction with DX as the second parameter.
+These I/O instructions can be shortened by using an 8-bit port I/O in the
+instruction. The upper 8 bits of the port address will be zero when an 8-bit
+port I/O is used.
+
+Intel has reserved I/O port addresses 00F8H through 00FFH; they should not
+be used.
+
+Protected Mode Exceptions
+
+#GP(0) if the current privilege level is bigger (has less privilege) than
+IOPL, which is the privilege level found in the flags register.
+
+Real Address Mode Exceptions
+
+None
+
+
+INC──Increment by 1
+
+Opcode Instruction Clocks Description
+
+FE /0 INC eb 2,mem=7 Increment EA byte by 1
+FF /0 INC ew 2,mem=7 Increment EA word by 1
+40+rw INC rw 2 Increment word register by 1
+
+Flags Modified
+
+Overflow, sign, zero, auxiliary carry, parity
+
+Flags Undefined
+
+None
+
+Operation
+
+1 is added to the operand. Note that the carry flag is not changed by this
+instruction. If you want the carry flag set, use the ADD instruction with a
+second operand of 1.
+
+Protected Mode Exceptions
+
+#GP(0) if the operand is in a non-writable segment. #GP(0) for an illegal
+memory operand effective address in the CS, DS, or ES segments; #SS(0) for
+an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+INS/INSB/INSW──Input from Port to String
+
+Opcode Instruction Clocks Description
+
+6C INS eb,DX 5 Input byte from port DX into ES:[DI]
+6D INS ew,DX 5 Input word from port DX into ES:[DI]
+6C INSB 5 Input byte from port DX into ES:[DI]
+6D INSW 5 Input word from port DX into ES:[DI]
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+INS transfers data from the input port numbered by the DX register to the
+memory byte or word at ES:DI. The memory operand must be addressable from
+the ES register; no segment override ispossible.
+
+INS does not allow the specification of the port number as an immediate
+value. The port must be addressed through the DX register.
+
+After the transfer is made, DI is automatically advanced. If the direction
+flag is 0 (CLD was executed), DI increments; if the direction flag is 1 (STD
+was executed), DI decrements. DI increments or decrements by 1 if a byte was
+moved; by 2 if a word was moved.
+
+INS can be preceded by the REP prefix for block input of CX bytes or words.
+Refer to the REP instruction for details of this operation.
+
+Intel has reserved I/O port addresses 00F8H through 00FFH; they should not
+be used.
+
+Not all input port devices can handle the rate at which this instruction
+transfers input data to memory.
+
+Protected Mode Exceptions
+
+#GP(0) if CPL > IOPL. #GP(0) if the destination is in a non-writable
+segment. #GP(0) for an illegal memory operand effective address in the CS,
+DS, or ES segments; #SS(0) for an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+INT/INTO──Call to Interrupt Procedure
+
+Opcode Instruction Clocks
+Add one clock for each byte of the next instruction executed. Description
+
+CC INT 3 23
+(real mode) Interrupt 3 (trap to debugger)
+CC INT 3 40 Interrupt 3, protected mode, same privilege
+CC INT 3 78 Interrupt 3, protected mode, more privilege
+CC INT 3 167 Interrupt 3, protected mode, via task gate
+CD db INT db 23
+(real mode) Interrupt numbered by immediate byte
+CD db INT db 40 Interrupt, protected mode, same privilege
+CD db INT db 78 Interrupt, protected mode, more privilege
+CD db INT db 167 Interrupt, protected mode, via task gate
+CE INTO 24,noj=3
+(real mode) Interrupt 4 if overflow flag is 1
+
+
+Flags Modified
+
+All if a task switch takes place; Trap Flag reset if no task switch takes
+place. Interrupt Flag is always reset in Real Mode, and reset in Protected
+Mode when INT references an interrupt gate.
+
+Flags Undefined
+
+None
+
+Operation
+
+The INT instruction generates via software a call to an interrupt
+procedure. The immediate operand, from 0 to 255, gives the index number into
+the Interrupt Descriptor Table of the interrupt routine to be called. In
+protected mode, the IDT consists of 8-byte descriptors; the descriptor for
+the interrupt invoked must indicate an interrupt gate, a trap gate, or a
+task gate. In real address mode, the IDT is an array of 4-byte long pointers
+at the fixed location 00000H.
+
+The INTO instruction is identical to the INT instruction except that the
+interrupt number is implicitly 4, and the interrupt is made only if the
+overflow flag of the 80286 is on. The clock counts for the four forms of
+INT db are valid for INTO, with the number of clocks increased by 1 for the
+overflow flag test.
+
+The first 32 interrupts are reserved by Intel for systems use. Some of
+these interrupts are exception handlers for internally-generated faults.
+Most of these exception handlers should not be invoked with the INT
+instruction.
+
+Generally, interrupts behave like far CALLs except that the flags register
+is pushed onto the stack before the return address. Interrupt procedures
+return via the IRET instruction, which pops the flags from the stack.
+
+In Real Address mode, INT pushes the flags, CS and the return IP onto the
+stack in that order, then resets the Trap Flag, then jumps to the long
+pointer indexed by the interrupt number, in the interrupt vector table.
+
+In Protected mode, INT also resets the Trap Flag. In Protected mode, the
+precise semantics of the INT instruction are given by the following:
+
+INTERRUPT
+ Interrupt vector must be within IDT table limits else #GP (vector number *
+ 8+2+EXT)
+ Descriptor AR byte must indicate interrupt gate, trap gate, or task gate
+ else #GP (vector number * 8+2+EXT)
+ If INT instruction then gate descriptor DPL must be ≥ CPL else #GP (vector
+ number * 8+2+EXT)
+ Gate must be PRESENT else #NP (vector number * 8+2+EXT)
+ If TRAP GATE or INTERRUPT GATE:
+ Examine CS selector and descriptor given in the gate descriptor:
+ Selector must be non-null else #GP (EXT)
+ Selector must be within its descriptor table limits else
+ #GP (selector+EXT)
+ Descriptor AR byte must indicate code segment else
+ #GP (selector + EXT)
+ Segment must be PRESENT else #NP (selector+EXT)
+ If code segment is non-conforming and DPL < CPL then
+ INTERRUPT TO INNER PRIVILEGE:
+ Check selector and descriptor for new stack in current Task State
+ Segment:
+ Selector must be non-null else #TS(EXT)
+ Selector index must be within its descriptor table limits else
+ #TS (SS selector+EXT)
+ Selector's RPL must equal DPL of code segment else
+ #TS (SS selector+EXT)
+ Stack segment DPL must equal DPL of code segment else #TS (SS
+ selector+EXT)
+ Descriptor must indicate writable data segment else #TS (SS
+ selector+EXT)
+ Segment must be PRESENT else #SS (SS selector+EXT)
+ New stack must have room for 10 bytes else #SS(0)
+ IP must be in CS limit else #GP(0)
+ Load new SS and SP value from TSS
+ Load new CS and IP value from gate
+ Load CS descriptor
+ Load SS descriptor
+ Push long pointer to old stack onto new stack
+ Push return address onto new stack
+ Set CPL to new code segment DPL
+ Set RPL of CS to CPL
+ If INTERRUPT GATE then set the Interrupts Enabled Flag to 0 (disabled)
+ Set the Trap Flag to 0
+ Set the Nested Task Flag to 0
+ If code segment is conforming or code segment DPL = CPL then
+ INTERRUPT TO SAME PRIVILEGE LEVEL:
+ Current stack limits must allow pushing 6 bytes else #SS(0)
+ If interrupt was caused by fault with error code then
+ Stack limits must allow push of two more bytes else #SS(0)
+ IP must be in CS limit else #GP(0)
+ Push flags onto stack
+ Push current CS selector onto stack
+ Push return offset onto stack
+ Load CS:IP from gate
+ Load CS descriptor
+ Set the RPL field of CS to CPL
+ Push error code (if any) onto stack
+ If INTERRUPT GATE then set the Interrupts Enabled Flag to 0 (disabled)
+ Set the Trap Flag to 0
+ Set the Nested Task Flag to 0
+
+Else #GP (CS selector + EXT)
+
+If TASK GATE:
+ Examine selector to TSS, given in Task Gate descriptor:
+ Must specify global in the local/global bit else #GP (TSS selector)
+ Index must be within GDT limits else #GP (TSS selector)
+ AR byte must specify available TSS (bottom bits 00001) else #GP (TSS
+ selector)
+ Task State Segment must be PRESENT else #NP (TSS selector)
+SWITCH_TASKS with nesting to TSS
+If interrupt was caused by fault with error code then
+ Stack limits must allow push of two more bytes else #SS(0)
+ Push error code onto stack
+IP must be in CS limit else #GP(0)
+
+EXT is 1 if an external event (i.e., a single step, an external interrupt,
+an MF exception, or an MP exception) caused the interrupt; 0 if not (i.e.,
+an INT instruction or other exceptions).
+
+Protected Mode Exceptions
+
+#GP, #NP, #SS, and #TS, as indicated in the list above.
+
+Real Address Mode Exceptions
+
+None; the 80286 will shut down if the SP = 1, 3, or 5 before executing the
+INT or INTO instruction──due to lack of stack space.
+
+
+IRET──Interrupt Return
+
+Opcode Instruction Clocks
+Add one clock for each byte in the next instruction executed. Description
+
+ CF IRET 17,pm=31 Interrupt return (far return and pop flags)
+ CF IRET 55 Interrupt return, lesser privilege
+ CF IRET 169 Interrupt return, different task (NT=1)
+
+
+Flags Modified
+
+Entire flags register popped from stack
+
+Flags Undefined
+
+None
+
+Operation
+
+In real address mode, IRET pops IP, CS, and FLAGS from the stack in that
+order, and resumes the interrupted routine.
+
+In protected mode, the action of IRET depends on the setting of the Nested
+Task Flag (NT) bit in the flag register. When popping the new flag image
+from the stack, note that the IOPL bits in the flag register are changed
+only when CPL=0.
+
+If NT=0, IRET returns from an interrupt procedure without a task switch.
+The code returned to must be equally or less privileged than the interrupt
+routine as indicated by the RPL bits of the CS selector popped from the
+stack. If the destination code is of less privilege, IRET then also pops SP
+and SS from the stack.
+
+If NT=1, IRET reverses the operation of a CALL or INT that caused a task
+switch. The task executing IRET has its updated state saved in its Task
+State Segment. This means that if the task is re-entered, the code that
+follows IRET will be executed.
+
+The exact checks and actions performed by IRET in protected mode are given
+on the following page.
+
+INTERRUPT RETURN:
+ If Nested Task Flag=1 then
+ RETURN FROM NESTED TASK:
+ Examine Back Link Selector in TSS addressed by the current Task
+ Register:
+ Must specify global in the local/global bit else
+ #TS (new TSS selector)
+ Index must be within GDT limits else #TS (new TSS selector)
+ AR byte must specify TSS else #TS (new TSS selector)
+ New TSS must be busy else #TS (new TSS selector)
+ Task State Segment must be PRESENT else #NP (new TSS selector)
+ SWITCH_TASKS without nesting to TSS specified by back link selector
+ Mark the task just abandoned as NOT BUSY
+ IP must be in code segment limit else #GP(0)
+ If Nested Task Flag=0 then
+ INTERRUPT RETURN ON STACK:
+ Second word on stack must be within stack limits else #SS(0)
+ Return CS selector RPL must be ≥ CPL else #GP (Return selector)
+ If return selector RPL = CPL then
+ INTERRUPT RETURN TO SAME LEVEL:
+ Top 6 bytes on stack must be within limits else #SS(0)
+ Return CS selector (at SP+2) must be non-null else #GP(0)
+ Selector index must be within its descriptor table limits else
+ #GP (Return selector)
+ AR byte must indicate code segment else #GP (Return selector)
+ If non-conforming then code segment DPL must = CPL else
+ #GP (Return selector)
+ If conforming then code segment DPL must be ≤ CPL else
+ #GP (Return selector)
+ Segment must be PRESENT else #NP (Return selector)
+ IP must be in code segment limit else #GP(0)
+ Load CS:IP from stack
+ Load CS-cache with new code segment descriptor
+ Load flags with third word on stack
+ Increment SP by 6
+ Else
+ INTERRUPT RETURN TO OUTER PRIVILEGE LEVEL:
+ Top 10 bytes on stack must be within limits else #SS(0)
+ Examine return CS selector (at SP+2) and associated descriptor:
+ Selector must be non-null else #GP(0)
+ Selector index must be within its descriptor table limits else
+ #GP (Return selector)
+ AR byte must indicate code segment else #GP (Return selector)
+ If non-conforming then code segment DPL must = CS selector RPL else
+ #GP (Return selector)
+ If conforming then code segment DPL must be > CPL else #GP (Return
+ selector)
+ Segment must be PRESENT else #NP (Return selector)
+ Examine return SS selector (at SP+8) and associated descriptor:
+ Selector must be non-null else #GP(0)
+ Selector index must be within its descriptor table limits else
+ #GP (SS selector)
+ Selector RPL must equal the RPL of the return CS selector else
+ #GP (SS selector)
+ AR byte must indicate a writable data segment else
+ #GP (SS selector)
+ Stack segment DPL must equal the RPL of the return CS selector else
+ #GP (SS selector)
+ SS must be PRESENT else #SS (SS selector)
+ IP must be in code segment limit else #GP(0)
+ Load CS:IP from stack
+ Load flags with values at (SP+4)
+ Load SS:SP from stack
+ Set CPL to the RPL of the return CS selector
+ Load the CS-cache with the CS descriptor
+ Load the SS-cache with the SS descriptor
+ For each of ES and DS:
+ If the current register setting is not valid for the outer level,
+ then zero the register and clear the valid flag
+ To be valid, the register setting must satisfy the following
+ properties:
+ Selector index must be within descriptor table limits
+ AR byte must indicate data or readable code segment
+ If segment is data or non-conforming code, then:
+ DPL must be ≥ CPL, or
+ DPL must be ≥ RPL.
+
+
+Protected Mode Exceptions
+
+#GP, #NP, or #SS, as indicated in the above listing.
+
+Real Address Mode Exceptions
+
+Interrupt 13 if the stack is popped when it has offset 0FFFFH.
+
+
+Jcond──Jump Short If Condition Met
+
+
+Opcode Instruction Clocks
+When a jump is taken, add one clock for every byte of the next instruction
+executed. Description
+77 cb JA cb 7,noj=3 Jump short if above (CF=0 and ZF=0)
+73 cb JAE cb 7,noj=3 Jump short if above or equal (CF=0)
+72 cb JB cb 7,noj=3 Jump short if below (CF=1)
+76 cb JBE cb 7,noj=3 Jump short if below or equal (CF=1 or ZF=1)
+72 cb JC cb 7,noj=3 Jump short if carry (CF=1)
+E3 cb JCXZ cb 8,noj=4 Jump short if CX register is zero
+74 cb JE cb 7,noj=3 Jump short if equal (ZF=1)
+7F cb JG cb 7,noj=3 Jump short if greater (ZF=0 and SF=OF)
+7D cb JGE cb 7,noj=3 Jump short if greater or equal (SF=OF)
+7C cb JL cb 7,noj=3 Jump short if less (SF/=OF)
+7E cb JLE cb 7,noj=3 Jump short if less or equal (ZF=1 or SF/=OF)
+76 cb JNA cb 7,noj=3 Jump short if not above (CF=1 or ZF=1)
+72 cb JNAE cb 7,noj=3 Jump short if not above/equal (CF=1)
+73 cb JNB cb 7,noj=3 Jump short if not below (CF=0)
+77 cb JNBE cb 7,noj=3 Jump short if not below/equal
+ (CF=0 and ZF=0)
+73 cb JNC cb 7,noj=3 Jump short if not carry (CF=0)
+75 cb JNE cb 7,noj=3 Jump short if not equal (ZF=0)
+7E cb JNG cb 7,noj=3 Jump short if not greater (ZF=1 or SF/=OF)
+7C cb JNGE cb 7,noj=3 Jump short if not greater/equal (SF/=OF)
+7D cb JNL cb 7,noj=3 Jump short if not less (SF=OF)
+7F cb JNLE cb 7,noj=3 Jump short if not less/equal
+ (ZF=0 and SF=OF)
+71 cb JNO cb 7,noj=3 Jump short if notoverflow (OF=0)
+7B cb JNP cb 7,noj=3 Jump short if not parity (PF=0)
+79 cb JNS cb 7,noj=3 Jump short if not sign (SF=0)
+75 cb JNZ cb 7,noj=3 Jump short if not zero (ZF=0)
+70 cb JO cb 7,noj=3 Jump short if overflow (OF=1)
+7A cb JP cb 7,noj=3 Jump short if parity (PF=1)
+7A cb JPE cb 7,noj=3 Jump short if parity even (PF=1)
+7B cb JPO cb 7,noj=3 Jump short if parity odd (PF=0)
+78 cb JS cb 7,noj=3 Jump short if sign (SF=1)
+74 cb JZ cb 7,noj=3 Jump short if zero (ZF=1)
+
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+Conditional jumps (except for JCXZ, explained below) test the flags, which
+presumably have been set in some meaningful way by a previous instruction.
+The conditions for each mnemonic are given in parentheses after each
+description above. The terms "less" and "greater" are used for comparing
+signed integers; "above" and "below" are used for unsigned integers.
+
+If the given condition is true, then a short jump is made to the label
+provided as the operand. Instruction encoding is most efficient when the
+target for the conditional jump is in the current code segment and within
+-128 to +127 bytes of the first byte of the next instruction.
+Alternatively, the opposite sense (e.g., JNZ has opposite sense to that of
+JZ) of the conditional jump can skip around an unconditional jump to the
+destination.
+
+This range is necessary for the assembler to construct a one-byte signed
+displacement from the end of the current instruction. If the label is
+out-of-range, or if the label is a FAR label, then you must perform a jump
+with the opposite condition around an unconditional jump to the non-short
+label.
+
+Because there are, in many instances, several ways to interpret a
+particular state of the flags, ASM286 provides more than one mnemonic for
+most of the conditional jump opcodes. For example, consider that a
+programmer who has just compared a character to another in AL might wish to
+jump if the two were equal (JE), while another programmer who had just ANDed
+AX with a bit field mask would prefer to consider only whether the result
+was zero or not (he would use JZ, a synonym for JE).
+
+JCXZ differs from the other conditional jumps in that it actually tests the
+contents of the CX register for zero, rather than interrogating the flags.
+This instruction is useful following a conditionally repeated string
+operation (REPE SCASB, for example) or a conditional loop instruction (such
+as LOOPNE TARGETLABEL). These instructions implicitly use a limiting count
+in the CX register. Looping (repeating) ends when either the CX register
+goes to zero or the condition specified in the instruction (flags indicating
+equals in both of the above cases) occurs. JCXZ is useful when the
+terminations must be handled differently.
+
+Protected Mode Exceptions
+
+#GP(0) if the offset jumped to is beyond the limits of the code segment.
+
+Real Address Mode Exceptions
+
+None
+
+
+JMP──Jump
+
+Opcode Instruction Clocks
+Add one clock for every byte of the next instruction executed. Description
+
+ EB cb JMP cb 7 Jump short
+ EA cd JMP cd 180 Jump to task gate
+ E9 cw JMP cw 7 Jump near
+ EA cd JMP cd 11,pm=23 Jump far (4-byte immediate address)
+ EA cd JMP cd 38 Jump to call gate, same privilege
+ EA cd JMP cd 175 Jump via Task State Segment
+ FF /4 JMP ew 7,mem=11 Jump near to EA word
+ (absolute offset)
+ FF /5 JMP ed 15,pm=26 Jump far (4-byte effective address
+ in memory doubleword)
+ FF /5 JMP ed 41 Jump to call gate, same privilege
+ FF /5 JMP ed 178 Jump via Task State Segment
+ FF /5 JMP ed 183 Jump to task gate
+
+
+Flags Modified
+
+All if a task switch takes place; none if no task switch occurs.
+
+Flags Undefined
+
+None
+
+Operation
+
+The JMP instruction transfers program control to a different instruction
+stream without recording any return information.
+
+For inter-segment jumps, the destination can be a code segment, a call
+gate, a task gate, or a Task State Segment. The latter two destinations
+cause a complete task switch to take place.
+
+Control transfers within a segment use the JMP cw or JMP cb forms. The
+operand is a relative offset added modulo 65536 to the offset of the
+instruction that follows the JMP. The result is the new value of IP; the
+value of CS is unchanged. The byte operand is sign-extended before it is
+added; it can therefore be used to address labels within 128 bytes in either
+direction from the next instruction.
+
+Indirect jumps within a segment use the JMP ew form. The contents of the
+register or memory operand is an absolute offset, which becomes the new
+value of IP. Again, CS is unchanged.
+
+Inter-segment jumps in real address mode simply set IP to the offset part
+of the long pointer and set CS to the selector part of the pointer.
+
+In protected mode, inter-segment jumps cause the 80286 to consult the
+descriptor addressed by the selector part of the long pointer. The AR byte
+of the descriptor determines the type of the destination. (See table B-3
+for possible values of the AR byte.) Following are the possible
+destinations:
+
+ 1. Code segment──The addressability and visibility of the destination
+ are verified, and CS and IP are loaded with the destination pointer
+ values.
+
+ 2. Call gate──The offset part of the destination pointer is ignored.
+ After checking for validity, the processor jumps to the location
+ stored in the call gate descriptor.
+
+ 3. Task gate──The current task's state is saved in its Task State
+ Segment (TSS), and the TSS named in the task gate is used to load a
+ new context. The outgoing task is marked not busy, the new TSS is
+ marked busy, and execution resumes at the point at which the new task
+ was last suspended.
+
+ 4. TSS──The current task is suspended and the new task is initiated as
+ in 3 above except that there is no intervening gate.
+
+Following is the list of checks and actions taken for long jumps in
+protected mode:
+
+JUMP FAR:
+ If indirect then check access of EA doubleword #GP(0) or #SS(0) if limit
+ violation
+ Destination selector is not null else #GP(0)
+ Destination selector index is within its descriptor table limits else
+ #GP (selector)
+ Examine AR byte of destination selector for legal values:
+
+ JUMP CONFORMING CODE SEGMENT:
+ Descriptor DPL must be ≤ CPL else #GP (selector)
+ Segment must be PRESENT else #NP (selector)
+ IP must be in code segment limit else #GP(0)
+ Load CS:IP from destination pointer
+ Load CS-cache with new segment descriptor
+
+ JUMP NONCONFORMING CODE SEGMENT:
+ RPL of destination selector must be ≤ CPL else #GP (selector)
+ Descriptor DPL must = CPL else #GP (selector)
+ Segment must be PRESENT else #NP (selector)
+ IP must be in code segment limit else #GP(0)
+ Load CS:IP from destination pointer
+ Load CS-cache with new segment descriptor
+ Set RPL field of CS register to CPL
+
+ JUMP TO CALL GATE:
+ Descriptor DPL must be ≥ CPL else #GP (gate selector)
+ Descriptor DPL must be ≥ gate selector RPL else #GP (gate selector)
+ Gate must be PRESENT else #NP (gate selector)
+ Examine selector to code segment given in call gate descriptor:
+ Selector must not be null else #GP(0)
+ Selector must be within its descriptor table limits else
+ #GP (CS selector)
+ Descriptor AR byte must indicate code segment else #GP (CS selector)
+ If non-conforming, code segment descriptor DPL must = CPL else
+ #GP (CS selector)
+ If conforming, then code segment descriptor DPL must be ≤ CPL else
+ #GP (CS selector)
+ Code Segment must be PRESENT else #NP (CS selector)
+ IP must be in code segment limit else #GP(0)
+ Load CS:IP from call gate
+ Load CS-cache with new code segment
+ Set RPL of CS to CPL
+
+ JUMP TASK GATE:
+ Gate descriptor DPL must be ≥ CPL else #GP (gate selector)
+ Gate descriptor DPL must be ≥ gate selector RPL else
+ #GP (gate selector)
+ Task Gate must be PRESENT else #NP (gate selector)
+ Examine selector to TSS, given in Task Gate descriptor:
+ Must specify global in the local/global bit else #GP (TSS selector)
+ Index must be within GDT limits else #GP (TSS selector)
+ Descriptor AR byte must specify available TSS (bottom bits 00001) else
+ #GP (TSS selector)
+ Task State Segment must be PRESENT else #NP (TSS selector)
+ SWITCH_TASKS without nesting to TSS
+ IP must be in code segment limit else #GP(0)
+
+ JUMP TASK STATE SEGMENT:
+ TSS DPL must be ≥ CPL else #GP (TSS selector)
+ TSS DPL must be ≥ TSS selector RPL else #GP (TSS selector)
+ Descriptor AR byte must specify available TSS (bottom bits 00001) else
+ #GP (TSS selector)
+ Task State Segment must be PRESENT else #NP (TSS selector)
+ SWITCH_TASKS with nesting to TS.
+ IP must be in code segment limit else #GP(0)
+
+ Else GP (selector)
+
+Protected Mode Exceptions
+
+For NEAR jumps, #GP(0) if the destination offset is beyond the limits of
+the current code segment. For FAR jumps, #GP, #NP, #SS, and #TS, as
+indicated above. #UD if indirect inter-segment jump operand is a register.
+
+Real Address Mode Exceptions
+
+#UD if indirect inter-segment jump operand is a register.
+
+
+LAHF──Load Flags into AH Register
+
+Opcode Instruction Clocks Description
+
+ 9F LAHF 2 Load: AH = flags
+ SF ZF xx AF xx PF xx CF
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+The low byte of the flags word is transferred to AH. The bits, from MSB to
+LSB, are as follows: sign, zero, indeterminate, auxiliary carry,
+indeterminate, parity, indeterminate, and carry. See figure 3-5.
+
+Protected Mode Exceptions
+
+None
+
+Real Address Mode Exceptions
+
+None
+
+
+LAR──Load Access Rights Byte
+
+Opcode Instruction Clocks Description
+
+0F 02 /r LAR rw,ew 14,mem=16 Load: high(rw)= Access Rights
+ byte, selector ew
+
+Flags Modified
+
+Zero
+
+Flags Undefined
+
+None
+
+Operation
+
+LAR expects the second operand (memory or register word) to contain a
+selector. If the associated descriptor is visible at the current privilege
+level and at the selector RPL, then the access rights byte of the descriptor
+is loaded into the high byte of the first (register) operand, and the low
+byte is set to zero. The zero flag is set if the loading was performed
+(i.e., the selector index is within the table limit, descriptor DPL ≥ CPL,
+and descriptor DPL ≥ selector RPL); the zero flag is cleared otherwise.
+
+Selector operands cannot cause protection exceptions.
+
+Protected Mode Exceptions
+
+#GP(0) for an illegal memory operand effective address in the CS, DS, or ES
+segments; #SS(0) for an illegal address in the SS segment.
+
+Real Address Mode Exception
+
+INTERRUPT 6; LAR is unrecognized in Real Address mode.
+
+
+LDS/LES──Load Doubleword Pointer
+
+Opcode Instruction Clocks Description
+
+C5 /r LDS rw,ed 7,pm=21 Load EA doubleword into DS and word register
+C4 /r LES rw,ed 7,pm=21 Load EA doubleword into ES and word register
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+The four-byte pointer at the memory location indicated by the second
+operand is loaded into a segment register and a word register. The first
+word of the pointer (the offset) is loaded into the register indicated by
+the first operand. The last word of the pointer (the selector) is loaded
+into the segment register (DS or ES) given by the instruction opcode.
+
+When the segment register is loaded, its associated cache is also loaded.
+The data for the cache is obtained from the descriptor table entry for the
+selector given.
+
+A null selector (values 0000-0003) can be loaded into DS or ES without a
+protection exception. Any memory reference using such a segment register
+value will cause a #GP(0) exception but will not result in a memory
+reference. The saved segment register value will be null.
+
+Following is a list of checks and actions taken when loading the DS or ES
+registers:
+
+If selector is non-null then:
+ Selector index must be within its descriptor table limits else
+ #GP(selector)
+ Examine descriptor AR byte:
+
+ Data segment or readable non-conforming code segment
+ Descriptor DPL ≥ CPL else #GP (selector)
+ Descriptor DPL ≥ selector RPL else #GP (selector)
+
+ Readable conforming code segment
+ No DPL, RPL, or CPL checks
+
+ Else #GP (selector)
+
+ Segment must be present else #NP (selector)
+ Load registers from operand
+ Load segment register descriptor cache
+
+If selector is null then:
+ Load registers from operand
+ Mark segment register cache as invalid
+
+Protected Mode Exceptions
+
+#GP or #NP, as indicated in the list above. #GP(0) or #SS(0) if operand
+lies outside segment limit. #UD if the source operand is a register.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for operand at offset 0FFFFH or 0FFFDH. #UD if the source
+operand is a register.
+
+
+LEA──Load Effective Address Offset
+
+Opcode Instruction Clocks Description
+
+8D /r LEA rw,m 3 Calculate EA offset given by m, place in rw
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+The effective address (offset part) of the second operand is placed in the
+first (register) operand.
+
+Protected Mode Exceptions
+
+#UD if second operand is a register.
+
+Real Address Mode Exceptions
+
+#UD if second operand is a register.
+
+
+LEAVE──High Level Procedure Exit
+
+Opcode Instruction Clocks Description
+
+C9 LEAVE 5 Set SP to BP, then POP BP
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+LEAVE is the complementary operation to ENTER; it reverses the effects of
+that instruction. By copying BP to SP, LEAVE releases the stack space used
+by a procedure for its dynamics and display. The old frame pointer is now
+popped into BP, restoring the caller's frame, and a subsequent RET
+instruction will follow the back-link and remove any arguments pushed on
+the stack for the exiting procedure.
+
+Protected Mode Exceptions
+
+#SS(0) if BP does not point to a location within the current stack segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+LGDT/LIDT──Load Global/Interrupt Descriptor Table Register
+
+Opcode Instruction Clocks Description
+
+0F 01 /2 LGDT m 11 Load m into Global Descriptor Table reg
+0F 01 /3 LIDT m 12 Load m into Interrupt Descriptor Table reg
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+The Global or the Interrupt Descriptor Table Register is loaded from the
+six bytes of memory pointed to by the effective address operand (see figure
+10-3). The LIMIT field of the descriptor table register loads from the
+first word; the next three bytes go to the BASE field of the register; the
+last byte is ignored.
+
+LGDT and LIDT appear in operating systems software; they are not used in
+application programs. These are the only instructions that directly load a
+physical memory address in 80286 protected mode.
+
+Protected Mode Exceptions
+
+#GP(0) if the current privilege level is not 0.
+
+#UD if source operand is a register.
+
+#GP(0) for an illegal memory operand effective address in the CS, DS, or ES
+segments; #SS(0) for an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+These instructions are valid in Real Address mode to allow the power-up
+initialization for Protected mode.
+
+Interrupt 13 for a word operand at offset 0FFFFH. #UD if source operand is
+a register.
+
+
+LLDT──Load Local Descriptor Table Register
+
+Opcode Instruction Clocks Description
+
+0F 00 /2 LLDT ew 17,mem=19 Load selector ew into Local
+ Descriptor Table register
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+The word operand (memory or register) to LLDT should contain a selector
+pointing to the Global Descriptor Table. The GDT entry should be a Local
+Descriptor Table Descriptor. If so, then the Local Descriptor Table Register
+is loaded from the entry. The descriptor cache entries for DS, ES, SS, and
+CS are not affected. The LDT field in the TSS is not changed.
+
+The selector operand is allowed to be zero. In that case, the Local
+Descriptor Table Register is marked invalid. All descriptor references
+(except by LAR, VERR, VERW or LSL instructions) will cause a #GP fault.
+
+LLDT appears in operating systems software; it does not appear in
+applications programs.
+
+Protected Mode Exceptions
+
+#GP(0) if the current privilege level is not 0. #GP (selector) if the
+selector operand does not point into the Global Descriptor Table, or if the
+entry in the GDT is not a Local Descriptor Table. #NP (selector) if LDT
+descriptor is not present. #GP(0) for an illegal memory operand effective
+address in the CS, DS, or ES segments; #SS(0) for an illegal address in the
+SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 6; LLDT is not recognized in Real Address Mode.
+
+
+LMSW──Load Machine Status Word
+
+Opcode Instruction Clocks Description
+
+0F 01 /6 LMSW ew 3,mem=6 Load EA word into Machine Status Word
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+The Machine Status Word is loaded from the source operand. This instruction
+may be used to switch to protected mode. If so, then it must be followed by
+an intra-segment jump to flush the instruction queue. LMSW will not switch
+back to Real Address Mode.
+
+LMSW appears only in operating systems software. It does not appear in
+applications programs.
+
+Protected Mode Exceptions
+
+#GP(0) if the current privilege level is not 0. #GP(0) for an illegal
+memory operand effective address in the CS, DS, or ES segments; #SS(0) for
+an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+LOCK──Assert BUS LOCK Signal
+
+Opcode Instruction Clocks Description
+
+F0 LOCK 0 Assert BUSLOCK signal for the next instruction
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+LOCK is a prefix that will cause the BUS LOCK signal of the 80286 to be
+asserted for the duration of the instruction that it prefixes. In a
+multiprocessor environment, this signal should be used to ensure that the
+80286 has exclusive use of any shared memory while BUS LOCK is asserted.
+The read-modify-write sequence typically used to implement TEST-AND-SET in
+the 80286 is the XCHG instruction.
+
+The 80286 LOCK prefix activates the lock signal for the following
+instructions: MOVS, INS, and OUTS. XCHG always asserts BUS LOCK regardless
+of the presence or absence of the LOCK prefix.
+
+Protected Mode Exceptions
+
+#GP(0) if the current privilege level is bigger (less privileged) than the
+I/O privilege level.
+
+Other exceptions may be generated by the subsequent (locked) instruction.
+
+Real Address Mode Exceptions
+
+None. Exceptions may still be generated by the subsequent (locked)
+instruction.
+
+
+LODS/LODSB/LODSW──Load String Operand
+
+ Opcode Instruction Clocks Description
+
+ AC LODS mb 5 Load byte [SI] into AL
+ AD LODS mw 5 Load word [SI] into AX
+ AC LODSB 5 Load byte DS:[SI] into AL
+ AD LODSW 5 Load word DS:[SI] into AX
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+LODS loads the AL or AX register with the memory byte or word at SI. After
+the transfer is made, SI is automatically advanced. If the direction flag is
+0 (CLD was executed), SI increments; if the direction flag is 1 (STD was
+executed), SI decrements. SI increments or decrements by 1 if a byte was
+moved; by 2 if a word was moved.
+
+Protected Address Mode Exceptions
+
+#GP(0) for an illegal memory operand effective address in the CS, DS, or ES
+segments; #SS(0) for an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+LOOP/LOOPcond──Loop Control with CX Counter
+
+Opcode Instruction Clocks Description
+
+E2 cb LOOP cb 8,noj=4 DEC CX; jump short if CX<>0
+E1 cb LOOPE cb 8,noj=4 DEC CX; jump short if CX<>E0 and equal
+ (ZF=1)
+E0 cb LOOPNE cb 8,noj=4 DEC CX; jump short if CX<>E0 and not equal
+ (ZF=0)
+E0 cb LOOPNZ cb 8,noj=4 DEC CX; jump short if CX<>E0 and ZF=0
+E1 cb LOOPZ cb 8,noj=4 DEC CX; jump short if CX<>E0 and zero (ZF=1)
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+LOOP first decrements the CX register without changing any of the flags.
+Then, conditions are checked as given in the description above for the form
+of LOOP being used. If the conditions are met, then an intra-segment jump is
+made. The destination to LOOP is in the range from 126 (decimal) bytes
+before the instruction to 127 bytes beyond the instruction.
+
+The LOOP instructions are intended to provide iteration control and to
+combine loop index management with conditional branching. To use the LOOP
+instruction you load an unsigned iteration count into CX, then code the LOOP
+at the end of a series of instructions to be iterated. The destination of
+LOOP is a label that points to the beginning of the iteration.
+
+Protected Address Mode Exceptions
+
+#GP(0) if the offset jumped to is beyond the limits of the current code
+segment.
+
+Real Address Mode Exceptions
+
+None
+
+
+LSL──Load Segment Limit
+
+Opcode Instruction Clocks Description
+
+0F 03 /r LSL rw,ew 14,mem=16 Load: rw = Segment Limit, selector ew
+
+Flags Modified
+
+Zero
+
+Flags Undefined
+
+None
+
+Operation
+
+If the descriptor denoted by the selector in the second (memory or
+register) operand is visible at the CPL, a word that consists of the limit
+field of the descriptor is loaded into the left operand, which must be a
+register. The value is the limit field for that segment. The zero flag is
+set if the loading was performed (that is, if the selector is non-null, the
+selector index is within the descriptor table limits, the descriptor is a
+non-conforming segment descriptor with DPL ≥ CPL, and the descriptor DPL ≥
+selector RPL); the zero flag is cleared otherwise.
+
+The LSL instruction returns only the limit field of segments, task state
+segments, and local descriptor tables. The interpretation of the limit value
+depends on the type of segment.
+
+The selector operand's value cannot result in a protection exception.
+
+Protected Address Mode Exceptions
+
+#GP(0) for an illegal memory operand effective address in the CS, DS, or ES
+segments; #SS(0) for an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 6; LSL is not recognized in Real Address mode.
+
+
+LTR──Load Task Register
+
+Opcode Instruction Clocks Description
+
+0F 00 /3 LTR ew 17,mem=19 Load EA word into Task Register
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+The Task Register is loaded from the source register or memory location
+given by the operand. The loaded TSS is marked busy. A task switch operation
+does not occur.
+
+LTR appears only in operating systems software. It is not used in
+applications programs.
+
+Protected Address Mode Exceptions
+
+#GP for an illegal memory operand effective address in the CS, DS, or ES
+segments; #SS for an illegal address in the SS segment.
+
+#GP(0) if the current privilege level is not 0. #GP (selector) if the
+object named by the source selector is not a TSS or is already busy. #NP
+(selector) if the TSS is marked not present.
+
+Real Address Mode Exceptions
+
+Interrupt 6; LTR is not recognized in Real Address mode.
+
+
+MOV──Move Data
+
+
+Opcode Instruction Clocks Description
+88 /r MOV eb,rb 2,mem=3 Move byte register into EA byte
+89 /r MOV ew,rw 2,mem=3 Move word register into EA word
+8A /r MOV rb,eb 2,mem=5 Move EA byte into byte register
+8B /r MOV rw,ew 2,mem=5 Move EA word into word register
+8C /0 MOV ew,ES 2,mem=3 Move ES into EA word
+8C /1 MOV ew,CS 2,mem=3 Move CS into EA word
+8C /2 MOV ew,SS 2,mem=3 Move SS into EA word
+8C /3 MOV ew,DS 2,mem=3 Move DS into EA word
+8E /0 MOV ES,mw 5,pm=19 Move memory word into ES
+8E /0 MOV ES,rw 2,pm=17 Move word register into ES
+8E /2 MOV SS,mw 5,pm=19 Move memory word into SS
+8E /2 MOV SS,rw 2,pm=17 Move word register into SS
+8E /3 MOV DS,mw 5,pm=19 Move memory word into DS
+8E /3 MOV DS,rw 2,pm=17 Move word register into DS
+A0 dw MOV AL,xb 5 Move byte variable (offset dw) into AL
+A1 dw MOV AX,xw 5 Move word variable (offset dw=) into AX
+A2 dw MOV xb,AL 3 Move AL into byte variable (offset dw=)
+A3 dw MOV xw,AX 3 Move AX into word register (offset dw=)
+B0+ rb db MOV rb,db 2 Move immediate byte into byte register
+B8+ rw dw MOV rw,dw 2 Move immediate word into word register
+C6 /0 db MOV eb,db 2,mem=3 Move immediate byte into EA byte
+C7 /0 dw MOV ew,dw 2,mem=3 Move immediate word into EA word
+
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+The second operand is copied to the first operand.
+
+If the destination operand is a segment register (DS, ES, or SS), then the
+associated segment register cache is also loaded. The data for the cache is
+obtained from the descriptor table entry for the selector given.
+
+A null selector (values 0000-0003) can be loaded into DS and ES registers
+without causing a protection exception. Any use of a segment register with a
+null selector to address memory will cause #GP(0) exception. No memory
+reference will occur.
+
+Any move into SS will inhibit all interrupts until after the execution of
+the next instruction.
+
+Following is a listing of the protected-mode checks and actions taken in
+the loading of a segment register:
+
+If SS is loaded:
+ If selector is null then #GP(0)
+ Selector index must be within its descriptor table limits else
+ #GP (selector)
+ Selector's RPL must equal CPL else #GP (selector)
+ AR byte must indicate a writable data segment else #GP (selector)
+ DPL in the AR byte must equal CPL else #GP (selector)
+ Segment must be marked PRESENT else #SS (selector)
+ Load SS with selector
+ Load SS cache with descriptor
+If ES or DS is loaded with non-null selector
+ Selector index must be within its descriptor table limits else
+ #GP (selector)
+ AR byte must indicate data or readable code segment else #GP (selector)
+ If data or non-conforming code, then both the RPL and the
+ CPL must be less than or equal to DPL in AR byte else
+ #GP (selector)
+ Segment must be marked PRESENT else #NP (selector)
+Load segment register with selector
+Load segment register cache with descriptor
+If ES or DS is loaded with a null selector:
+ Load segment register with selector
+ Clear descriptor valid bit
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+MOVS/MOVSB/MOVSW──Move Data from String to String
+
+Opcode Instruction Clocks Description
+
+A4 MOVS mb,mb 5 Move byte [SI] to ES:[DI]
+A5 MOVS mw,mw 5 Move word [SI] to ES:[DI]
+A4 MOVSB 5 Move byte DS:[SI] to ES:[DI]
+A5 MOVSW 5 Move word DS:[SI] to ES:[DI]
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+MOVS copies the byte or word at [SI] to the byte or word at ES:[DI]. The
+destination operand must be addressable from the ES register; no segment
+override is possible. A segment override may be used for the source operand.
+
+After the data movement is made, both SI and DI are automatically advanced.
+If the direction flag is 0 (CLD was executed), the registers increment; if
+the direction flag is 1 (STD was executed), the registers decrement. The
+registers increment or decrement by 1 if a byte was moved; by 2 if a word
+was moved.
+
+MOVS can be preceded by the REP prefix for block movement of CX bytes or
+words. Refer to the REP instruction for details of this operation.
+
+Protected Address Mode Exceptions
+
+#GP(0) if the destination is in a non-writable segment. #GP(0) for an
+illegal memory operand effective address in the CS, DS, or ES segments;
+#SS(0) for an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+MUL──Unsigned Multiplication of AL or AX
+
+Opcode Instruction Clocks Description
+
+F6 /4 MUL eb 13,mem=16 Unsigned multiply (AX = AL * EA byte)
+F7 /4 MUL ew 21,mem=24 Unsigned multiply (DXAX = AX * EA word)
+
+Flags Modified
+
+Overflow, carry
+
+Flags Undefined
+
+Sign, zero, auxiliary carry, parity
+
+Operation
+
+If MUL has a byte operand, then the byte is multiplied by AL, and the
+result is left in AX. Carry and overflow are set to 0 if AH is 0; they are
+set to 1 otherwise.
+
+If MUL has a word operand, then the word is multiplied by AX, and the
+result is left in DX:AX. DX contains the high order 16 bits of the product.
+Carry and overflow are set to 0 if DX is 0; they are set to 1 otherwise.
+
+Protected Address Mode Exceptions
+
+#GP(0) for an illegal memory operand effective address in the CS, DS, or ES
+segments; #SS(0) for an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+NEG──Two's Complement Negation
+
+Opcode Instruction Clocks Description
+
+F6 /3 NEG eb 2,mem=7 Two's complement negate EA byte
+F7 /3 NEG ew 2,mem=7 Two's complement negate EA word
+
+Flags Modified
+
+Overflow, sign, zero, auxiliary carry, parity, carry
+
+Flags Undefined
+
+None
+
+Operation
+
+The two's complement of the register or memory operand replaces the old
+operand value. Likewise, the operand is subtracted from zero, and the result
+is placed in the operand.
+
+The carry flag is set to 1 except when the input operand is zero, in which
+case the carry flag is cleared to 0.
+
+Protected Address Mode Exceptions
+
+#GP(0) if the result is in a non-writable segment. #GP(0) for an illegal
+memory operand effective address in the CS, DS, or ES segments; #SS(0) for
+an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+NOP──No OPERATION
+
+Opcode Instruction Clocks Description
+
+90 NOP 3 No OPERATION
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+Performs no operation. NOP is a one-byte filler instruction that takes up
+space but affects none of the machine context except IP.
+
+Protected Address Mode Exceptions
+
+None
+
+Real Address Mode Exceptions
+
+None
+
+
+NOT──One's Complement Negation
+
+Opcode Instruction Clocks Description
+
+F6 /2 NOT eb 2,mem=7 Reverse each bit of EA byte
+F7 /2 NOT ew 2,mem=7 Reverse each bit of EA word
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+The operand is inverted; that is, every 1 becomes a 0 and vice versa.
+
+Protected Address Mode Exceptions
+
+#GP(0) if the result is in a non-writable segment. #GP(0) for an illegal
+memory operand effective address in the CS, DS, or ES segments; #SS(0) for
+an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+OR──Logical Inclusive OR
+
+Opcode Instruction Clocks Description
+
+08 /r OR eb,rb 2,mem=7 Logical-OR byte register into EA byte
+09 /r OR ew,rw 2,mem=7 Logical-OR word register into EA word
+0A /r OR rb,eb 2,mem=7 Logical-OR EA byte into byte register
+0B /r OR rw,ew 2,mem=7 Logical-OR EA word into word register
+0C db OR AL,db 3 Logical-OR immediate byte into AL
+0D dw OR AX,dw 3 Logical-OR immediate word into AX
+80 /1 db OR eb,db 3,mem=7 Logical-OR immediate byte into EA byte
+81 /1 dw OR ew,dw 3,mem=7 Logical-OR immediate word into EA word
+
+Flags Modified
+
+Overflow=0, sign, zero, parity, carry=0
+
+Flags Undefined
+
+Auxiliary carry
+
+Operation
+
+This instruction computes the inclusive OR of the two operands. Each bit of
+the result is 0 if both corresponding bits of the operands are 0; each bit
+is 1 otherwise. The result is placed in the first operand.
+
+Protected Address Mode Exceptions
+
+#GP(0) if the result is in a non-writable segment. #GP(0) for an illegal
+memory operand effective address in the CS, DS, or ES segments; #SS(0) for
+an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+OUT──Output to Port
+
+Opcode Instruction Clocks Description
+
+E6 db OUT db,AL 3 Output byte AL to immediate port number db
+E7 db OUT db,AX 3 Output word AX to immediate port number db
+EE OUT DX,AL 3 Output byte AL to port number DX
+EF OUT DX,AX 3 Output word AX to port number DX
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+OUT transfers a data byte or data word from the register (AL or AX) given
+as the second operand to the output port numbered by the first operand. You
+can output to any port from 0-65535 by placing the port number in the DX
+register then using an OUT instruction with DX as the first operand. If the
+instruction contains an 8-bit port ID, that value is zero-extended to 16
+bits.
+
+Intel reserves I/O port addresses 00F8H through 00FFH; these addresses
+should not be used.
+
+Protected Address Mode Exceptions
+
+#GP(0) if the current privilege level is bigger (has less privilege) than
+IOPL, which is the privilege level found in the flags register.
+
+Real Address Mode Exceptions
+
+None
+
+
+OUTS/OUTSB/OUTSW──Output String to Port
+
+Opcode Instruction Clocks Description
+
+6E OUTS DX,eb 5 Output byte [SI] to port number DX
+6F OUTS DX,ew 5 Output word [SI] to port number DX
+6E OUTSB 5 Output byte DS:[SI] to port number DX
+6F OUTSW 5 Output word DS:[SI] to port number DX
+
+Flags Modified
+
+None
+
+Flags Undefined
+None
+
+Operation
+
+OUTS transfers data from the memory byte or word at SI to the output port
+numbered by the DX register.
+
+OUTS does not allow the specification of the port number as an immediate
+value. The port must be addressed through the DX register.
+
+After the transfer is made, SI is automatically advanced. If the direction
+flag is 0 (CLD was executed), SI increments; if the direction flag is 1 (STD
+was executed), SI decrements. SI increments or decrements by 1 if a byte was
+moved; by 2 if a word was moved.
+
+OUTS can be preceded by the REP prefix for block output of CX bytes or
+words. Refer to the REP instruction for details of this operation.
+
+Intel reserves I/O port addresses 00F8H through 00FFH; these addresses
+should not be used.
+
+───────────────────────────────────────────────────────────────────────────
+NOTE
+ Not all output devices can handle the rate at which this instruction
+ transfers data.
+───────────────────────────────────────────────────────────────────────────
+
+Protected Mode Exceptions
+
+#GP(0) if CPL > IOPL. #GP(0) for an illegal memory operand effective
+address in the CS, DS, or ES segments; #SS(0) for an illegal address in the
+SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+POP──Pop a Word from the Stack
+
+Opcode Instruction Clocks Description
+
+ 1F POP DS 5,pm=20 Pop top of stack into DS
+ 07 POP ES 5,pm=20 Pop top of stack into ES
+ 17 POP SS 5,pm=20 Pop top of stack into SS
+ 8F /0 POP mw 5 Pop top of stack into memory word
+ 58+rw POP rw 5 Pop top of stack into word register
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+The word on the top of the 80286 stack, addressed by SS:SP, replaces the
+previous contents of the memory, register, or segment register operand. The
+stack pointer SP is incremented by 2 to point to the new top of stack.
+
+If the destination operand is another segment register (DS, ES, or SS), the
+value popped must be a selector. In protected mode, loading the selector
+initiates automatic loading of the descriptor information associated with
+that selector into the hidden part of the segment register; loading also
+initiates validation of both the selector and the descriptor information.
+
+A null value (0000-0003) may be loaded into the DS or ES register without
+causing a protection exception. Attempts to reference memory using a segment
+register with a null value will cause #GP(0) exception. No memory reference
+will occur. The saved value of the segment register will be null.
+
+A POP SS instruction will inhibit all interrupts, including NMI, until
+after the execution of the next instruction. This permits a POP SP
+instruction to be performed first.
+
+Following is a listing of the protected-mode checks and actions taken in
+the loading of a segment register:
+
+If SS is loaded:
+ If selector is null then #GP(0)
+ Selector index must be within its descriptor table limits else #GP
+ (selector)
+ Selector's RPL must equal CPL else #GP (selector)
+ AR byte must indicate a writable data segment else #GP (selector)
+ DPL in the AR byte must equal CPL else #GP (selector)
+ Segment must be marked PRESENT else #SS (selector)
+ Load SS register with selector
+ Load SS cache with descriptor
+If ES or DS is loaded with non-null selector:
+ AR byte must indicate data or readable code segment else #GP (selector)
+ If data or non-conforming code, then both the RPL and the
+ CPL must be less than or equal to DPL in AR byte else
+ #GP (selector)
+ Segment must be marked PRESENT else #NP (selector)
+ Load segment register with selector
+ Load segment register cache with descriptor
+If ES or DS is loaded with a null selector:
+ Load segment register with selector
+ Clear valid bit in cache
+
+Protected Mode Exceptions
+
+If a segment register is being loaded, #GP, #SS, and #NP, as described in
+the listing above.
+
+Otherwise, #SS(0) if the current top of stack is not within the stack
+segment.
+
+#GP(0) if the destination is in a non-writable segment. #GP(0) for an
+illegal memory operand effective address in the CS, DS, or ES segments;
+#SS(0) for an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+POPA──Pop All General Registers
+
+Opcode Instruction Clocks Description
+
+ 61 POPA 19 Pop in order: DI,SI,BP,SP,BX,DX,CX,AX
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+POPA pops the eight general registers given in the description above,
+except that the SP value is discarded instead of loaded into SP. POPA
+reverses a previous PUSHA, restoring the general registers to their values
+before PUSHA was executed. The first register popped is DI.
+
+Protected Mode Exceptions
+
+#SS(0) if the starting or ending stack address is not within the stack
+segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+POPF──Pop from Stack into the Flags Register
+
+Opcode Instruction Clocks Description
+
+ 9D POPF 5 Pop top of stack into flags register
+
+Flags Modified
+
+Entire flags register is popped from stack
+
+Flags Undefined
+
+None
+
+Operation
+
+The top of the 80286 stack, pointed to by SS:SP, is copied into the 80286
+flags register. The stack pointer SP is incremented by 2 to point to the new
+top of stack. The flags, from the top bit (bit 15) to the bottom (bit 0),
+are as follows: undefined, nested task, I/O privilege level (2 bits),
+overflow, direction, interrupts enabled, trap, sign, zero, undefined,
+auxiliary carry, undefined, parity, undefined, and carry.
+
+The I/O privilege level will be altered only when executing at privilege
+level 0. The interrupt enable flag will be altered only when executing at a
+level at least as privileged as the I/O privilege level. If you execute a
+POPF instruction with insufficient privilege, there will be no exception
+nor will the privileged bits be changed.
+
+Protected Mode Exceptions
+
+#SS(0) if the top of stack is not within the stack segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at 0FFFFH.
+
+In real mode the NT and IOPL bits will not be modified.
+
+
+PUSH──Push a Word onto the Stack
+
+Opcode Instruction Clocks Description
+
+ 06 PUSH ES 3 Push ES
+ 0E PUSH CS 3 Push CS
+ 16 PUSH SS 3 Push SS
+ 1E PUSH DS 3 Push DS
+ 50+ rw PUSH rw 3 Push word register
+ FF /6 PUSH mw 5 Push memory word
+ 68 dw PUSH dw 3 Push immediate word
+ 6A db PUSH db 3 Push immediate sign-extended byte
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+The stack pointer SP is decremented by 2, and the operand is placed on the
+new top of stack, which is pointed to by SS:SP.
+
+The 80286 PUSH SP instruction pushes the value of SP as it existed before
+the instruction. This differs from the 8086, which pushes the new
+(decremented by 2) value.
+
+Protected Mode Exceptions
+
+#SS(0) if the new value of SP is outside the stack segment limit.
+
+#GP(0) for an illegal memory operand effective address in the CS, DS, or ES
+segments; #SS(0) for an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+None; the 80286 will shut down if SP = 1 ──due to lack of stack space.
+
+
+PUSHA──Push All General Registers
+
+Opcode Instruction Clocks Description
+
+ 60 PUSHA 17 Push in order: AX,CX,DX,BX,original
+ SP,BP,SI,DI
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+PUSHA saves the registers noted above on the 80286 stack. The stack pointer
+SP is decremented by 16 to hold the 8 word values. Since the registers are
+pushed onto the stack in the order in which they were given, they will
+appear in the 16 new stack bytes in the reverse order. The last register
+pushed is DI.
+
+Protected Mode Exceptions
+
+#SS(0) if the starting or ending address is outside the stack segment
+limit.
+
+Real Address Mode Exceptions
+
+The 80286 will shut down if SP = 1, 3, or 5 before executing PUSHA. If SP =
+7, 9, 11, 13, or 15, exception 13 will occur.
+
+
+PUSHF──Push Flags Register onto the Stack
+
+Opcode Instruction Clocks Description
+
+ 9C PUSHF 3 Push flags register
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+The stack pointer SP is decremented by 2, and the 80286 flags register is
+copied to the new top of stack, which is pointed to by SS:SP. The flags,
+from the top bit (15) to the bottom bit (0), are as follows: undefined,
+nested task, I/O privilege level (2 bits), overflow, direction, interrupts
+enabled, trap, sign, zero, undefined, auxiliary carry, undefined, parity,
+undefined, and carry.
+
+Protected Mode Exceptions
+
+#SS(0) if the new value of SP is outside the stack segment limit.
+
+Real Address Mode Exceptions
+
+None; the 80286 will shut down if SP=1 due──to lack of stack space.
+
+
+RCL/RCR/ROL/ROR──Rotate Instructions
+
+
+Opcode Instruction Clocks-N
+Add 1 clock to the times shown for each rotate made Description
+D0 /2 RCL eb,1 2,mem=7 Rotate 9-bits (CF, EA byte) left once
+D2 /2 RCL eb,CL 5,mem=8 Rotate 9-bits (CF, EA byte) left CL times
+C0 /2 db RCL eb,db 5,mem=8 Rotate 9-bits (CF, EA byte) left db times
+D1 /2 RCL ew,1 2,mem=7 Rotate 17-bits (CF, EA word) left once
+D3 /2 RCL ew,CL 5,mem=8 Rotate 17-bits (CF, EA word) left CL times
+C1 /2 db RCL ew,db 5,mem=8 Rotate 17-bits (CF, EA word) left db times
+D0 /3 RCR eb,1 2,mem=7 Rotate 9-bits (CF, EA byte) right once
+D2 /3 RCR eb,CL 5,mem=8 Rotate 9-bits (CF, EA byte) right CL times
+C0 /3 db RCR eb,db 5,mem=8 Rotate 9-bits (CF, EA byte) right db times
+D1 /3 RCR ew,1 2,mem=7 Rotate 17-bits (CF, EA word) right once
+D3 /3 RCR ew,CL 5,mem=8 Rotate 17-bits (CF, EA word) right CL times
+C1 /3 db RCR ew,db 5,mem=8 Rotate 17-bits (CF, EA word) right db times
+D0 /0 ROL eb,1 2,mem=7 Rotate 8-bit EA byte left once
+D2 /0 ROL eb,CL 5,mem=8 Rotate 8-bit EA byte left CL times
+C0 /0 db ROL eb,db 5,mem=8 Rotate 8-bit EA byte left db times
+D1 /0 ROL ew,1 2,mem=7 Rotate 16-bit EA word left once
+D3 /0 ROL ew,CL 5,mem=8 Rotate 16-bit EA word left CL times
+C1 /0 db ROL ew,db 5,mem=8 Rotate 16-bit EA word left db times
+D0 /1 ROR eb,1 2,mem=7 Rotate 8-bit EA byte right once
+D2 /1 ROR eb,CL 5,mem=8 Rotate 8-bit EA byte right CL times
+C0 /1 db ROR eb,db 5,mem=8 Rotate 8-bit EA byte right db times
+D1 /1 ROR ew,1 2,mem=7 Rotate 16-bit EA word right once
+D3 /1 ROR ew,CL 5,mem=8 Rotate 16-bit EA word right CL times
+C1 /1 db ROR ew,db 5,mem=8 Rotate 16-bit EA word right db times
+
+
+Flags Modified
+
+Overflow (only for single rotates), carry
+
+Flags Undefined
+
+Overflow for multi-bit rotates
+
+Operation
+
+Each rotate instruction shifts the bits of the register or memory operand
+given. The left rotate instructions shift all of the bits upward, except for
+the top bit, which comes back around to the bottom. The right rotate
+instructions do the reverse: the bits shift downward, with the bottom bit
+coming around to the top.
+
+For the RCL and RCR instructions, the carry flag is part of the rotated
+quantity. RCL shifts the carry flag into the bottom bit and shifts the top
+bit into the carry flag; RCR shifts the carry flag into the top bit and
+shifts the bottom bit into the carry flag. For the ROL and ROR
+instructions, the original value of the carry flag is not a part of the
+result; nonetheless, the carry flag receives a copy of the bit that was
+shifted from one end to the other.
+
+The rotate is repeated the number of times indicated by the second operand,
+which is either an immediate number or the contents of the CL register. To
+reduce the maximum execution time, the 80286 does not allow rotation counts
+greater than 31. If a rotation count greater than 31 is attempted, only the
+bottom five bits of the rotation are used. The 8086 does not mask rotate
+counts.
+
+The overflow flag is set only for the single-rotate (second operand = 1)
+forms of the instructions. The OF bit is set to be accurate if a shift of
+length 1 is done. Since it is undefined for all other values, including a
+zero shift, it can always be set for the count-of-1 case regardless of the
+actual count. For left shifts/rotates, the CF bit after the shift is XORed
+with the high-order result bit. For right shifts/rotates, the high-order
+two bits of the result are XORed to get OF. Neither flag bit is modified
+when the count value is zero.
+
+Protected Mode Exceptions
+
+#GP(0) if the result is in a non-writable segment. #GP(0) for an illegal
+memory operand effective address in the CS, DS, or ES segments; #SS(0) for
+an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+REP/REPE/REPNE──Repeat Following String Operation
+
+
+Opcode Instruction Clocks
+N denotes the number of iterations actually executed. Description
+F3 6C REP INS eb,DX 5+4 CX Input CX bytes from port DX into ES:[DI]
+F3 6D REP INS ew,DX 5+4 CX Input CX words from port DX into ES:[DI]
+F3 6C REP INSB 5+4 CX Input CX bytes from port DX into ES:[DI]
+F3 6D REP INSW 5+4 CX Input CX words from port DX into ES:[DI]
+F3 A4 REP MOVS mb,mb 5+4 CX Move CX bytes from [SI] to ES:[DI]
+F3 A5 REP MOVS mw,mw 5+4 CX Move CX words from [SI] to ES:[DI]
+F3 A4 REP MOVSB 5+4 CX Move CX bytes from DS:[SI] to ES:[DI]
+F3 A5 REP MOVSW 5+4 CX Move CX words from DS:[SI] to ES:[DI]
+F3 6E REP OUTS DX,eb 5+4 CX Output CX bytes from [SI] to port DX
+F3 6F REP OUTS DX,ew 5+4 CX Output CX words from [SI] to port DX
+F3 6E REP OUTSB 5+4 CX Output CX bytes from DS:[SI] to port DX
+F3 6F REP OUTSW 5+4 CX Output CX words from DS:[SI] to port DX
+F3 AA REP STOS mb 4+3 CX Fill CX bytes at ES:[DI] with AL
+F3 AB REP STOS mw 4+3 CX Fill CX words at ES:[DI] with AX
+F3 AA REP STOSB 4+3 CX Fill CX bytes at ES:[DI] with AL
+F3 AB REP STOSW 4+3 CX Fill CX words at ES:[DI] with AX
+F3 A6 REPE CMPS mb,mb 5+9 N Find nonmatching bytes in
+ ES:[DI] and [SI]
+F3 A7 REPE CMPS mw,mw 5+9 N Find nonmatching words in
+ ES:[DI] and [SI]
+F3 A6 REPE CMPSB 5+9 N Find nonmatching bytes in ES:[DI]
+ and DS:[SI]
+F3 A7 REPE CMPSW 5+9 N Find nonmatching words in ES:[DI]
+ and DS:[SI]
+F3 AE REPE SCAS mb 5+8 N Find non-AL byte starting at ES:[DI]
+F3 AF REPE SCAS mw 5+8 N Find non-AX word starting at ES:[DI]
+F3 AE REPE SCASB 5+8 N Find non-AL byte starting at ES:[DI]
+F3 AF REPE SCASW 5+8 N Find non-AX word starting at ES:[DI]
+F2 A6 REPNE CMPS mb,mb 5+9 N Find matching bytes in
+ ES:[DI] and [SI]
+F2 A7 REPNE CMPS mw,mw 5+9 N Find matching words in
+ ES:[DI] and [SI]
+F2 A6 REPNE CMPSB 5+9 N Find matching bytes in ES:[DI]
+ and DS:[SI]
+F2 A7 REPNE CMPSW 5+9 N Find matching words in ES:[DI]
+ and DS:[SI]
+F2 AE REPNE SCAS mb 5+8 N Find AL, starting at ES:[DI]
+F2 AF REPNE SCAS mw 5+8 N Find AX, starting at ES:[DI]
+F2 AE REPNE SCASB 5y+8 N Find AL, starting at ES:[DI]
+F2 AF REPNE SCASW 5+8 N Find AX, starting at ES:[DI]
+
+
+Flags Modified
+
+By CMPS and SCAS, none by REP
+
+Flags Undefined
+
+None
+
+Operation
+
+REP, REPE, and REPNE are prefix operations. These prefixes cause the string
+instruction that follows to be repeated CX times or (for REPE and REPNE)
+until the indicated condition in the zero flag is no longer met. Thus, REPE
+stands for "Repeat while equal," REPNE for "Repeat while not equal."
+
+The REP prefixes make sense only in the contexts listed above. They cannot
+be applied to anything other than string operations.
+
+Synonymous forms of REPE and REPNE are REPZ and REPNZ, respectively.
+
+The REP prefixes apply only to one string instruction at a time. To repeat
+a block of instructions, use a LOOP construct.
+
+The precise action for each iteration is as follows:
+
+ 1. Check the CX register. If it is zero, exit the iteration and move to
+ the next instruction.
+
+ 2. Acknowledge any pending interrupts.
+
+ 3. Perform the string operation once.
+
+ 4. Decrement CX by 1; no flags are modified.
+
+ 5. If the string operation is SCAS or CMPS, check the zero flag. If the
+ repeat condition does not hold, then exit the iteration and move to
+ the next instruction. Exit if the prefix is REPE and ZF=0 (the last
+ comparison was not equal), or if the prefix is REPNE and ZF=1 (the
+ last comparison was equal).
+
+ 6. Go to step 1 for the next iteration.
+
+As defined by the individual string-ops, the direction of movement through
+the block is determined by the direction flag. If the direction flag is 1
+(STD was executed), SI and/or DI start at the end of the block and move
+backward; if the direction flag is 0 (CLD was executed), SI and/or DI start
+at the beginning of the block and move forward.
+
+For repeated SCAS and CMPS operations the repeat can be exited for one of
+two different reasons: the CX count can be exhausted or the zero flag can
+fail the repeat condition. Your code will probably want to distinguish
+between the two cases. It can do so via either the JCXZ instruction or the
+conditional jumps that test the zero flag (JZ, JNZ, JE, and JNE).
+
+Not all input/output ports can handle the rate at which the repeated I/O
+instructions execute.
+
+Protected Mode Exceptions
+
+None by REP; exceptions can be generated when the string-op is executed.
+
+Real Address Mode Exceptions
+
+None by REP; exceptions can be generated when the string-op is executed.
+
+
+RET──Return from Procedure
+
+Opcode Instruction Clocks
+Add 1 clock for each byte in the next instruction executed. Description
+
+ CB RET 15,pm=25 Return to far caller, same privilege
+ CB RET 55 Return, lesser privilege, switch stacks
+ C3 RET 11 Return to near caller, same privilege
+ CA dw RET dw 15,pm=25 RET (far), same privilege, pop dw bytes
+ CA dw RET dw 55 RET (far), lesser privilege, pop dw bytes
+ C2 dw RET dw 11 RET (near), same privilege, pop dw bytes
+ pushed before Call
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+RET transfers control to a return address located on the stack. The address
+is usually placed on the stack by a CALL instruction; in that case, the
+return is made to the instruction that follows the CALL.
+
+There is an optional numeric parameter to RET. It gives the number of stack
+bytes to be released after the return address is popped. These bytes are
+typically used as input parameters to the procedure called.
+
+For the intra-segment return, the address on the stack is a 2-byte quantity
+popped into IP. The CS register is unchanged.
+
+For the inter-segment return, the address on the stack is a 4-byte-long
+pointer. The offset is popped first, followed by the selector. In real
+address mode, CS and IP are directly loaded.
+
+In protected mode, an inter-segment return causes the processor to consult
+the descriptor addressed by the return selector. The AR byte of the
+descriptor must indicate a code segment of equal or less privilege (of
+greater or equal numeric value) than the current privilege level. Returns
+to a lesser privilege level cause the stack to be reloaded from the value
+saved beyond the parameter block.
+
+The DS and ES segment registers may be set to zero by the inter-segment RET
+instruction. If these registers refer to segments which cannot be used by
+the new privilege level, they are set to zero to prevent unauthorized
+access.
+
+The following list of checks and actions describes the protected-mode
+inter-segment return in detail.
+
+Inter-segment RET:
+ Second word on stack must be within stack limits else #SS(0)
+ Return selector RPL must be ≥ CPL else #GP (return selector)
+ If return selector RPL = CPL then
+ RETURN TO SAME LEVEL:
+ Return selector must be non-null else #GP(0)
+ Selector index must be within its descriptor table limits else
+ #GP (selector)
+ Descriptor AR byte must indicate code segment else #GP (selector)
+ If non-conforming then code segment DPL must equal CPL else
+ #GP (selector)
+ If conforming then code segment DPL must be ≤ CPL else #GP (selector)
+ Code segment must be PRESENT else #NP (selector)
+ Top word on stack must be within stack limits else #SS(0)
+ IP must be in code segment limit else #GP(0)
+ Load CS:IP from stack
+ Load CS-cache with descriptor
+ Increment SP by 4 plus the immediate offset if it exists
+Else
+ RETURN TO OUTER PRIVILEGE LEVEL:
+ Top (8+immediate) bytes on stack must be within stack limits else #SS(0)
+ Examine return CS selector (at SP+2) and associated descriptor:
+ Selector must be non-null else #GP(0)
+ Selector index must be within its descriptor table limits else
+ #GP (selector)
+ Descriptor AR byte must indicate code segment else #GP (selector)
+ If non-conforming then code segment DPL must equal return selector
+ RPL else #GP (selector)
+ If conforming then code segment DPL must be ≤ return selector RPL
+ else #GP (selector)
+ Segment must be PRESENT else #NP (selector)
+ Examine return SS selector (at SP+6+imm) and associated descriptor:
+ Selector must be non-null else #GP(0)
+ Selector index must be within its descriptor table limits else
+ #GP (selector)
+ Selector RPL must equal the RPL of the return CS selector else
+ #GP (selector)
+ Descriptor AR byte must indicate a writable data segment else
+ #GP (selector)
+ Descriptor DPL must equal the RPL of the return CS selector else
+ #GP (selector)
+ Segment must be PRESENT else #SS (selector)
+ IP must be in code segment limit else # GP(0)
+ Set CPL to the RPL of the return CS selector
+ Load CS:IP from stack
+ Set CS RPL to CPL
+ Increment SP by 4 plus the immediate offset if it exists
+ Load SS:SP from stack
+ Load the CS-cache with the return CS descriptor
+ Load the SS-cache with the return SS descriptor
+ For each of ES and DS:
+ If the current register setting is not valid for the outer level,
+ set the register to null (selector = AR = 0)
+ To be valid, the register setting must satisfy the following
+ properties:
+ Selector index must be within descriptor table limits
+ Descriptor AR byte must indicate data or readable code segment
+ If segment is data or non-conforming code, then:
+ DPL must be ≥ CPL, or
+ DPL must be ≥ RPL
+
+Protected Mode Exceptions
+
+#GP, #NP, or #SS, as described in the above listing.
+
+Real Address Mode Exceptions
+
+Interrupt 13 if the stack pop wraps around from 0FFFFH to 0.
+
+
+SAHF──Store AH into Flags
+
+Opcode Instruction Clocks Description
+
+ 9E SAHF 2 Store AH into flags
+ SF ZF xx AF xx PF xx CF
+
+Flags Modified
+
+Sign, zero, auxiliary carry, parity, carry
+
+Flags Undefined
+
+None
+
+Operation
+
+The flags listed above are loaded with values from the AH register, from
+bits 7, 6, 4, 2, and 0, respectively.
+
+Protected Mode Exceptions
+
+None
+
+Real Address Mode Exceptions
+
+None
+
+
+SAL/SAR/SHL/SHR──Shift Instructions
+
+Opcode Instruction Clocks-N
+Add 1 clock to the times shown for each shift performed Description
+
+D0 /4 SAL eb,1 2,mem=7 Multiply EA byte by 2, once
+D2 /4 SAL eb,CL 5,mem=8 Multiply EA byte by 2, CL times
+C0 /4 db SAL eb,db 5,mem=8 Multiply EA byte by 2, db times
+D1 /4 SAL ew,1 2,mem=7 Multiply EA word by 2, once
+D3 /4 SAL ew,CL 5,mem=8 Multiply EA word by 2, CL times
+C1 /4 db SAL ew,db 5,mem=8 Multiply EA word by 2, db times
+D0 /7 SAR eb,1 2,mem=7 Signed divide EA byte by 2, once
+D2 /7 SAR eb,CL 5,mem=8 Signed divide EA byte by 2, CL times
+C0 /7 db SAR eb,db 5,mem=8 Signed divide EA byte by 2, db times
+D1 /7 SAR ew,1 2,mem=7 Signed divide EA word by 2, once
+D3 /7 SAR ew,CL 5,mem=8 Signed divide EA word by 2, CL times
+C1 /7 db SAR ew,db 5,mem=8 Signed divide EA word by 2, db times
+D0 /5 SHR eb,1 2,mem=7 Unsigned divide EA byte by 2, once
+D2 /5 SHR eb,CL 5,mem=8 Unsigned divide EA byte by 2, CL times
+C0 /5 db SHR eb,db 5,mem=8 Unsigned divide EA byte by 2, db times
+D1 /5 SHR ew,1 2,mem=7 Unsigned divide EA word by 2, once
+D3 /5 SHR ew,CL 5,mem=8 Unsigned divide EA word by 2, CL times
+
+
+Flags Modified
+
+Overflow (only for single-shift form), carry, zero, parity, sign
+
+Flags Undefined
+
+Auxiliary carry; also overflow for multibit shifts (only).
+
+Operation
+
+SAL (or its synonym SHL) shifts the bits of the operand upward. The
+high-order bit is shifted into the carry flag, and the low-order bit is set
+to 0.
+
+SAR and SHR shift the bits of the operand downward. The low-order bit is
+shifted into the carry flag. The effect is to divide the operand by 2. SAR
+performs a signed divide: the high-order bit remains the same. SHR performs
+an unsigned divide: the high-order bit is set to 0.
+
+The shift is repeated the number of times indicated by the second operand,
+which is either an immediate number or the contents of the CL register. To
+reduce the maximum execution time, the 80286 does not allow shift counts
+greater than 31. If a shift count greater than 31 is attempted, only the
+bottom five bits of the shift count are used. The 8086 uses all 8 bits of
+the shift count.
+
+The overflow flag is set only if the single-shift forms of the instructions
+are used. For left shifts, it is set to 0 if the high bit of the answer is
+the same as the result carry flag (i.e., the top two bits of the original
+operand were the same); it is set to 1 if they are different. For SAR it is
+set to 0 for all single shifts. For SHR, it is set to the high-order bit of
+the original operand. Neither flag bit is modified when the count value is
+zero.
+
+Protected Mode Exceptions
+
+#GP(0) if the operand is in a non-writable segment. #GP(0) for an illegal
+memory operand effective address in the CS, DS, or ES segments; #SS(0) for
+an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+SBB──Integer Subtraction With Borrow
+
+Opcode Instruction Clocks Description
+
+18 /r SBB eb,rb 2,mem=7 Subtract with borrow byte
+ register from EA byte
+19 /r SBB ew,rw 2,mem=7 Subtract with borrow word
+ register from EA word
+1A /r SBB rb,eb 2,mem=7 Subtract with borrow EA byte
+ from byte register
+1B /r SBB rw,ew 2,mem=7 Subtract with borrow EA word
+ from word register
+1C db SBB AL,db 3 Subtract with borrow imm.
+ byte from AL
+1D dw SBB AX,dw 3 Subtract with borrow imm.
+ word from AX
+80 /3 db SBB eb,db 3,mem=7 Subtract with borrow imm. byte
+ from EA byte
+81 /3 dw SBB ew,dw 3,mem=7 Subtract with borrow imm. word
+ from EA word
+83 /3 db SBB ew,db 3,mem=7 Subtract with borrow imm. byte
+ from EA word
+
+Flags Modified
+
+Overflow, sign, zero, auxiliary carry, parity, carry
+
+Flags Undefined
+
+None
+
+Operation
+
+The second operand is added to the carry flag and the result is subtracted
+from the first operand. The first operand is replaced with the result of the
+subtraction, and the flags are set accordingly.
+
+When a byte-immediate value is subtracted from a word operand, the
+immediate value is first sign-extended.
+
+Protected Mode Exceptions
+
+#GP(0) if the result is in a non-writable segment. #GP(0) for an illegal
+memory operand effective address in the CS, DS, or ES segments; #SS(0) for
+an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+SCAS/SCASB/SCASW──Compare String Data
+
+Opcode Instruction Clocks Description
+
+ AE SCAS mb 7 Compare bytes AL - ES:[DI], advance DI
+ AF SCAS mw 7 Compare words AX - ES:[DI], advance DI
+ AE SCASB 7 Compare bytes AL - ES:[DI], advance DI
+ AF SCASW 7 Compare words AX - ES:[DI], advance DI
+
+Flags Modified
+
+Overflow, sign, zero, auxiliary carry, parity, carry
+
+Flags Undefined
+
+None
+
+Operation
+
+SCAS subtracts the memory byte or word at ES:DI from the AL or AX register.
+The result is discarded; only the flags are set. The operand must be
+addressable from the ES register; no segment override is possible.
+
+After the comparison is made, DI is automatically advanced. If the
+direction flag is 0 (CLD was executed), DI increments; if the direction flag
+is 1 (STD was executed), DI decrements. DI increments or decrements by 1 if
+bytes were compared; by 2 if words were compared.
+
+SCAS can be preceded by the REPE or REPNE prefix for a block search of CX
+bytes or words. Refer to the REP instruction for details of this operation.
+
+Protected Mode Exceptions
+
+#GP(0) for an illegal memory operand effective address in the CS, DS, or ES
+segments; #SS(0) for an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+SGDT/SIDT──Store Global/Interrupt Descriptor Table Register
+
+Opcode Instruction Clocks Description
+
+0F 01 /0 SGDT m 11 Store Global Descriptor Table register
+ to m
+0F 01 /1 SIDT m 12 Store Interrupt Descriptor Table
+ register to m
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+The contents of the descriptor table register are copied to six bytes of
+memory indicated by the operand. The LIMIT field of the register goes to the
+first word at the effective address; the next three bytes get the BASE field
+of the register; and the last byte is undefined.
+
+SGDT and SIDT appear only in operating systems software; they are not used
+in applications programs.
+
+Protected Mode Exceptions
+
+#UD if the destination operand is a register. #GP(0) if the destination is
+in a non-writable segment. #GP(0) for an illegal memory operand effective
+address in the CS, DS, or ES segments; #SS(0) for an illegal address in the
+SS segment.
+
+Real Address Mode Exceptions
+
+These instructions are valid in Real Address mode to facilitate power-up or
+to reset initialization prior to entering Protected mode.
+
+#UD if the destination operand is a register. Interrupt 13 for a word
+operand at offset 0FFFFH.
+
+
+SLDT──Store Local Descriptor Table Register
+
+Opcode Instruction Clocks Description
+
+0F 00 /0 SLDT ew 2,mem=3 Store Local Descriptor Table register to
+ EA word
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+The Local Descriptor Table register is stored in the 2-byte register or
+memory location indicated by the effective address operand. This register is
+a selector that points into the Global Descriptor Table.
+
+SLDT appears only in operating systems software. It is not used in
+applications programs.
+
+Protected Mode Exceptions
+
+#GP(0) if the destination is in a non-writable segment. #GP(0) for an
+illegal memory operand effective address in the CS, DS, or ES segments;
+#SS(0) for an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 6; SLDT is not recognized in Real Address mode.
+
+
+SMSW──Store Machine Status Word
+
+Opcode Instruction Clocks Description
+
+0F 01 /4 SMSW ew 2,mem=3 Store Machine Status Word to EA word
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+The Machine Status Word is stored in the 2-byte register or memory location
+indicated by the effective address operand.
+
+Protected Mode Exceptions
+
+#GP(0) if the destination is in a non-writable segment. #GP(0) for an
+illegal memory operand effective address in the CS, DS, or ES segments;
+#SS(0) for an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+STC──Set Carry Flag
+
+Opcode Instruction Clocks Description
+
+ F9 STC 2 Set carry flag
+
+Flags Modified
+
+Carry=1
+
+Flags Undefined
+
+None
+
+Operation
+
+The carry flag is set to 1.
+
+Protected Mode Exceptions
+
+None
+
+Real Address Mode Exceptions
+
+None
+
+
+STD──Set Direction Flag
+
+Opcode Instruction Clocks Description
+
+FD STD 2 Set direction flag so SI and DI
+ will decrement
+
+Flags Modified
+
+Direction=1
+
+Flags Undefined
+
+None
+
+Operation
+
+The direction flag is set to 1. This causes all subsequent string
+operations to decrement the index registers (SI and/or DI) on which they
+operate.
+
+Protected Mode Exceptions
+
+None
+
+Real Address Mode Exceptions
+
+None
+
+
+STI──Set Interrupt Enable Flag
+
+Opcode Instruction Clocks Description
+
+FB STI 2 Set interrupt enable flag,
+ interrupts enabled
+
+Flags Modified
+
+Interrupt=1 (enabled)
+
+Flags Undefined
+
+None
+
+Operation
+
+The interrupts-enabled flag is set to 1. The 80286 will now respond to
+external interrupts after executing the STI instruction.
+
+Protected Mode Exceptions
+
+#GP(0) if the current privilege level is bigger (has less privilege) than
+the I/O privilege level.
+
+Real Address Mode Exceptions
+
+None
+
+
+STOS/STOSB/STOSW──Store String Data
+
+Opcode Instruction Clocks Description
+
+AA STOS mb 3 Store AL to byte ES:[DI], advance DI
+AB STOS mw 3 Store AX to word ES:[DI], advance DI
+AA STOSB 3 Store AL to byte ES:[DI], advance DI
+AB STOSW 3 Store AX to word ES:[DI], advance DI
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+STOS transfers the contents the AL or AX register to the memory byte or
+word at ES:DI. The operand must be addressable from the ES register; no
+segment override is possible.
+
+After the transfer is made, DI is automatically advanced. If the direction
+flag is 0 (CLD was executed), DI increments; if the direction flag is 1 (STD
+was executed), DI decrements. DI increments or decrements by 1 if a byte was
+moved; by 2 if a word was moved.
+
+STOS can be preceded by the REP prefix for a block fill of CX bytes or
+words. Refer to the REP instruction for details of this operation.
+
+Protected Mode Exceptions
+
+#GP(0) if the destination is in a non-writable segment. #GP(0) for an
+illegal memory operand effective address in the CS, DS, or ES segments;
+#SS(0) for an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+STR──Store Task Register
+
+Opcode Instruction Clocks Description
+
+0F 00 /1 STR ew 2,mem=3 Store Task Register to EA word
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+The contents of the Task Register are copied to the 2-byte register or
+memory location indicated by the effective address operand.
+
+Protected Mode Exceptions
+
+#GP(0) if the destination is in a non-writable segment. #GP(0) for an
+illegal memory operand effective address in the CS, DS, or ES segments;
+#SS(0) for an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 6; STR is not recognized in Real Address mode.
+
+
+SUB──Integer Subtraction
+
+Opcode Instruction Clocks Description
+
+28 /r SUB eb,rb 2,mem=7 Subtract byte register from EA byte
+29 /r SUB ew,rw 2,mem=7 Subtract word register from EA word
+2A /r SUB rb,eb 2,mem=7 Subtract EA byte from byte register
+2B /r SUB rw,ew 2,mem=7 Subtract EA word from word register
+2C db SUB AL,db 3 Subtract immediate byte from AL
+2D dw SUB AX,dw 3 Subtract immediate word from AX
+80 /5 db SUB eb,db 3,mem=7 Subtract immediate byte from EA byte
+81 /5 dw SUB ew,dw 3,mem=7 Subtract immediate word from EA word
+83 /5 db SUB ew,db 3,mem=7 Subtract immediate byte from
+ EA word
+
+Flags Modified
+
+Overflow, sign, zero, auxiliary carry, parity, carry
+
+Flags Undefined
+
+None
+
+Operation
+
+The second operand is subtracted from the first operand, and the first
+operand is replaced with the result.
+
+When a byte-immediate value is subtracted from a word operand, the
+immediate value is firstsign-extended.
+
+Protected Mode Exceptions
+
+#GP(0) if the result is in a non-writable segment. #GP(0) for an illegal
+memory operand effective address in the CS, DS, or ES segments; #SS(0) for
+an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+TEST──Logical Compare
+
+Opcode Instruction Clocks Description
+
+84 /r TEST eb,rb 2,mem=6 AND byte register into EA byte
+ for flags only
+84 /r TEST rb,eb 2,mem=6 AND EA byte into byte register
+ for flags only
+85 /r TEST ew,rw 2,mem=6 AND word register into EA word
+ for flags only
+85 /r TEST rw,ew 2,mem=6 AND EA word into word register
+ for flags only
+A8 db TEST AL,db 3 AND immediate byte into AL
+ for flags only
+A9 dw TEST AX,dw 3 AND immediate word into AX
+ for flags only
+F6 /0 db TEST eb,db 3,mem=6 AND immediate byte into EA byte
+ for flags only
+F7 /0 dw TEST ew,dw 3,mem=6 AND immediate word into EA word
+ for flags only
+
+Flags Modified
+
+Overflow=0, sign, zero, parity, carry=0
+
+Flags Undefined
+
+Auxiliary carry
+
+Operation
+
+TEST computes the bit-wise logical AND of the two operands given. Each bit
+of the result is 1 if both of the corresponding bits of the operands are 1;
+each bit is 0 otherwise. The result of the operation is discarded; only the
+flags are modified.
+
+Protected Mode Exceptions
+
+#GP(0) for an illegal memory operand effective address in the CS, DS, or ES
+segments; #SS(0) for an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+VERR,VERW──Verify a Segment for Reading or Writing
+
+Opcode Instruction Clocks Description
+
+0F 00 /4 VERR ew 14,mem=16 Set ZF=1 if seg. can be read,
+ selector ew
+0F 00 /5 VERW ew 14,mem=16 Set ZF=1 if seg. can be written,
+ selector ew
+
+Flags Modified
+
+Zero
+
+Flags Undefined
+
+None
+
+Operation
+
+VERR and VERW expect the 2-byte register or memory operand to contain the
+value of a selector. The instructions determine whether the segment denoted
+by the selector is reachable from the current privilege level; the
+instructions also determine whether it is readable or writable. If the
+segment is determined to be accessible, the zero flag is set to 1; if the
+segment is not accessible, it is set to 0. To set ZF, the following
+conditions must be met:
+
+ 1. The selector must denote a descriptor within the bounds of the table
+ (GDT or LDT); that is, the selector must be "defined."
+
+ 2. The selector must denote the descriptor of a code or data segment.
+
+ 3. If the instruction is VERR, the segment must be readable. If the
+ instruction is VERW, the segment must be a writable data segment.
+
+ 4. If the code segment is readable and conforming, the descriptor
+ privilege level (DPL) can be any value for VERR. Otherwise, the DPL
+ must be greater than or equal to (have less or the same privilege as)
+ both the current privilege level and the selector's RPL.
+
+The validation performed is the same as if the segment were loaded into DS
+or ES and the indicated access (read or write) were performed. The zero flag
+receives the result of the validation. The selector's value cannot result in
+a protection exception. This enables the software to anticipate possible
+segment access problems.
+
+Protected Mode Exceptions
+
+The only faults that can occur are those generated by illegally addressing
+the memory operand which contains the selector. The selector is not loaded
+into any segment register, and no faults attributable to the selector
+operand are generated.
+
+#GP(0) for an illegal memory operand effective address in the CS, DS, or ES
+segments; #SS(0) for an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 6; VERR and VERW are not recognized in Real Address Mode.
+
+
+WAIT──Wait Until BUSY Pin Is Inactive (HIGH)
+
+Opcode Instruction Clocks Description
+
+9B WAIT 3 Wait until BUSY pin is inactive (HIGH)
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+WAIT suspends execution of 80286 instructions until the BUSY pin is inactive
+(high). The BUSY pin is driven by the 80287 numeric processor extension.
+WAIT is issued to ensure that the numeric instruction being executed is
+complete, and to check for a possible numeric fault (see below).
+
+Protected Mode Exceptions
+
+#NM if task switch flag in MSW is set. #MF if 80287 has detected an
+unmasked numeric error.
+
+Real Address Mode Exceptions
+
+Same as Protected mode.
+
+
+XCHG──Exchange Memory/Register with Register
+
+Opcode Instruction Clocks Description
+
+86 /r XCHG eb,rb 3,mem=5 Exchange byte register with EA byte
+86 /r XCHG rb,eb 3,mem=5 Exchange EA byte with byte register
+87 /r XCHG ew,rw 3,mem=5 Exchange word register with EA word
+87 /r XCHG rw,ew 3,mem=5 Exchange EA word with word register
+90+ rw XCHG AX,rw 3 Exchange word register with AX
+90+ rw XCHG rw,AX 3 Exchange with word register
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+The two operands are exchanged. The order of the operands is immaterial.
+BUS LOCK is asserted for the duration of the exchange, regardless of the
+presence or absence of the LOCK prefix or IOPL.
+
+Protected Mode Exceptions
+
+#GP(0) if either operand is in a non-writable segment. #GP(0) for an
+illegal memory operand effective address in the CS, DS, or ES segments;
+#SS(0) for an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+XLAT──Table Look-up Translation
+
+Opcode Instruction Clocks Description
+
+D7 XLAT mb 5 Set AL to memory byte DS:[BX + unsigned AL]
+D7 XLATB 5 Set AL to memory byte DS:[BX + unsigned AL]
+
+Flags Modified
+
+None
+
+Flags Undefined
+
+None
+
+Operation
+
+When XLAT is executed, AL should be the unsigned index into a table
+addressed by DS:BX. XLAT changes the AL register from the table index into
+the table entry. BX is unchanged.
+
+Protected Mode Exceptions
+
+#GP(0) for an illegal memory operand effective address in the CS, DS, or ES
+segments; #SS(0) for an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+XOR──Logical Exclusive OR
+
+Opcode Instruction Clocks Description
+
+30 /r XOR eb,rb 2,mem=7 Exclusive-OR byte register into EA byte
+31 /r XOR ew,rw 2,mem=7 Exclusive-OR word register into EA word
+32 /r XOR rb,eb 2,mem=7 Exclusive-OR EA byte into byte register
+33 /r XOR rw,ew 2,mem=7 Exclusive-OR EA word into word register
+34 db XOR AL,db 3 Exclusive-OR immediate byte into AL
+35 dw XOR AX,dw 3 Exclusive-OR immediate word into AX
+80 /6 db XOR eb,db 3,mem=7 Exclusive-OR immediate byte into EA byte
+81 /6 dw XOR ew,dw 3,mem=7 Exclusive-OR immediate word into EA word
+
+Flags Modified
+
+Overflow=0, sign, zero, parity, carry=0
+
+Flags Undefined
+
+Auxiliary carry
+
+Operation
+
+XOR computes the exclusive OR of the two operands. Each bit of the result
+is 1 if the corresponding bits of the operands are different; each bit is 0
+if the corresponding bits are the same. The answer replaces the first
+operand.
+
+Protected Mode Exceptions
+
+#GP(0) if the result is in a non-writable segment. #GP(0) for an illegal
+memory operand effective address in the CS, DS, or ES segments; #SS(0) for
+an illegal address in the SS segment.
+
+Real Address Mode Exceptions
+
+Interrupt 13 for a word operand at offset 0FFFFH.
+
+
+Appendix C 8086/8088 Compatibility Considerations
+
+───────────────────────────────────────────────────────────────────────────
+
+Software Compatibility Considerations
+
+In general, the real address mode 80286 will correctly execute ROM-based
+8086/8088 software. The following is a list of the minor differences between
+8086 and 80286 (Real mode).
+
+ 1. Add Six Interrupt Vectors. The 80286 adds six interrupts which arise
+ only if the 8086 program has a hidden bug. These interrupts occur only
+ for instructions which were undefined on the 8086/8088 or if a segment
+ wraparound is attempted. It is recommended that you add an interrupt
+ handler to the 8086 software that is to be run on the 80286, which
+ will treat these interrupts as invalid operations. This additional
+ software does not significantly effect the existing 8086 software
+ because the interrupts do not normally occur and should not already
+ have been used since they are in the interrupt group reserved by
+ Intel. Table C-1 describes the new 80286 interrupts.
+
+ 2. Do not Rely on 8086/8088 Instruction Clock Counts. The 80286 takes
+ fewer clocks for most instructions than the 8086/8088. The areas to
+ look into are delays between I/O operations, and assumed delays in
+ 8086/8088 operating in parallel with an 8087.
+
+ 3. Divide Exceptions Point at the DIV Instruction. Any interrupt on the
+ 80286 will always leave the saved CS:IP value pointing at the
+ beginning of the instruction that failed (including prefixes). On the
+ 8086, the CS:IP value saved for a divide exception points at the next
+ instruction.
+
+ 4. Use Interrupt 16 for Numeric Exceptions. Any 80287 system must use
+ interrupt vector 16 for the numeric error interrupt. If an 8086/8087
+ or 8088/8087 system uses another vector for the 8087 interrupt, both
+ vectors should point at the numeric error interrupt handler.
+
+ 5. Numeric Exception Handlers Should allow Prefixes. The saved CS:IP
+ value in the NPX environment save area will point at any leading
+ prefixes before an ESC instruction. On 8086/8088 systems, this value
+ points only at the ESC instruction.
+
+ 6. Do Not Attempt Undefined 8086/8088 Operations. Instructions like
+ POP CS or MOV CS,op will either cause exception 6 (undefined opcode)
+ or perform a protection setup operation like LIDT on the 80286.
+ Undefined bit encodings for bits 5-3 of the second byte of POP MEM or
+ PUSH MEM will cause exception 13 on the 80286.
+
+ 7. Place a Far JMP Instruction at FFFF0H. After reset, CS:IP = F000:FFF0
+ on the 80286 (versus FFFF:0000 on the 8086/8088). This change was made
+ to allow sufficient code space to enter protected mode without
+ reloading CS. Placing a far JMP instruction at FFFF0H will avoid this
+ difference. Note that the BOOTSTRAP option of LOC86 will automatically
+ generate this jump instruction.
+
+ 8. Do not Rely on the Value Written by PUSH SP. The 80286 will push a
+ different value on the stack for PUSH SP than the 8086/8088. If the
+ value pushed is important, replace PUSH SP instructions with the
+ following three instructions:
+ PUSH BP
+ MOV BP,SP
+ XCHG BP,[BP]
+ This code functions as the 8086/8088 PUSH SP instruction on the 80286.
+
+ 9. Do not Shift or Rotate by More than 31 Bits. The 80286 masks all
+ shift/rotate counts to the low 5 bits. This MOD 32 operation limits
+ the count to a maximum of 31 bits. With this change, the longest
+ shift/rotate instruction is 39 clocks. Without this change, the
+ longest shift/rotate instruction would be 264 clocks, which delays
+ interrupt response until the instruction completes execution.
+
+ 10. Do not Duplicate Prefixes. The 80286 sets an instruction length limit
+ of 10 bytes. The only way to violate this limit is by duplicating a
+ prefix two or more times before an instruction. Exception 6 occurs if
+ the instruction length limit is violated. The 8086/8088 has no
+ instruction length limit.
+
+ 11. Do not Rely on Odd 8086/8088 LOCK Characteristics. The LOCK prefix and
+ its corresponding output signal should only be used to prevent other
+ bus masters from interrupting a data movement operation. The 80286
+ will always assert LOCK during an XCHG instruction with memory (even
+ if the LOCK prefix was not used). LOCK should only be used with the
+ XCHG, MOV, MOVS, INS, and OUTS instructions. The 80286 LOCK signal
+ will not go active during an instruction prefetch.
+
+ 12. Do not Single Step External Interrupt Handlers. The priority of the
+ 80286 single step interrupt is different from that of the 8086/8088.
+ This change was made to prevent an external interrupt from being
+ single-stepped if it occurs while single stepping through a program.
+ The 80286 single step interrupt has higher priority than any external
+ interrupt. The 80286 will still single step through an interrupt
+ handler invoked by INT instructions or an instruction exception.
+
+ 13. Do not Rely on IDIV Exceptions for Quotients of 80H or 8000H. The
+ 80286 can generate the largest negative number as a quotient for IDIV
+ instructions. The 8086 will instead cause exception 0.
+
+ 14. Do not Rely on NMI Interrupting NMI Handlers. After an NMI is
+ recognized, the NMI input and processor extension limit error
+ interrupt is masked until the first IRET instruction is executed.
+
+ 15. The NPX error signal does not pass through an interrupt controller
+ (an 8087 INT signal does). Any interrupt controller-oriented
+ instructions for the 8087 may have to be deleted.
+
+ 16. If any real-mode program relies on address space wrap-around (e.g.,
+ FFF0:0400=0000:0300), then external hardware should be used to force
+ the upper 4 addresses to zero during real mode.
+
+ 17. Do not use I/O ports 00F8-00FFH. These are reserved for controlling
+ 80287 and future processor extensions.
+
+
+Table C-1. New 80286 Interrupts
+
+Interrupt Function
+Number
+
+ 5 A BOUND instruction was executed with a register value outside
+ the two limit values.
+ 6 An undefined opcode was encountered.
+ 7 The EM bit in the MSW has been set and an ESC instruction was
+ executed. This interrupt will also occur on WAIT instructions
+ if TS is set.
+ 8 The interrupt table limit was changed by the LIDT instruction
+ to a value between 20H and 43H. The default limit after reset is
+ 3FFH, enough for all 256 interrupts.
+ 9 A processor extension data transfer exceeded offset 0FFFFH in a
+ segment. This interrupt handler must execute FNINIT before
+ any ESC or WAIT instruction is executed.
+ 13 Segment wraparound was attempted by a word operation at offset
+ 0FFFFH.
+ 16 When 80286 attempted to execute a coprocessor instruction
+ ERROR pin indicated an unmasked exception from previous
+ coprocessor instruction.
+
+
+Hardware Compatibility Considerations
+
+ 1. Address after Reset
+
+ 8086 has CS:IP = FFFF:0000 and physical address FFFF0.
+ 80286 has CS:IP = F000:FFF0 and physical address FFFFF0.
+
+───────────────────────────────────────────────────────────────────────────
+NOTE
+ After 80286 reset, until the first 80286 far JMP or far CALL, the
+ code segment base is FF0000. This means A20-A23 will be high for
+ CS-relative bus cycles (code fetch or use of CS override prefix)
+ after reset until the first far JMP or far CALL instruction is
+ performed.
+───────────────────────────────────────────────────────────────────────────
+
+ 2. Physical Address Formation
+
+ In real mode or protected mode, the 80286 always forms a physical
+ address by adding a 16-bit offset with a 24-bit segment base value
+ (8086 has 20-bit base value). Therefore, if the 80286 in real mode
+ has a segment base within 64K of the top of the 1 Mbyte address space,
+ and the program adds an offset of ffffh to the segment base, the
+ physical address will be slightly above 1Mbyte. Thus, to fully
+ duplicate 1Mbyte wraparound that the 8086 has, it is always necessary
+ to force A20 low externally when the 80286 is in real mode, but system
+ hardware uses all 24 address lines.
+
+ 3. LOCK signal
+
+ On the 8086, LOCK asserted means this bus cycle is within a group of
+ two or more locked bus cycles. On the 80286, the LOCK signal means
+ lock this bus cycle to the NEXT bus cycle. Therefore, on the 80286,
+ the LOCK signal is not asserted on the last locked bus cycle of the
+ group of locked bus cycles.
+
+ 4. Coprocessor Interface
+
+ 8086, synchronous to 8086, can become a bus master.
+ 80287, asynchronous to 80286 and 80287, cannot become a bus master.
+ 8087 pulls opcode and pointer information directly from data bus.
+ 80286 passes opcode and pointer information to 80287.
+ 8087 uses interrupt path to signal errors to 8086.
+ 80287 uses dedicated ERROR signal.
+ 8086 requires explicit WAIT opcode preceding all ESC instructions to
+ synchronize with 8087. 80286 has automatic instruction synchronization
+ with 80287.
+
+ 5. Bus Cycles
+
+ 8086 has four-clock minimum bus cycle, with a time-multiplexed
+ address/data bus. 80286 has two-clock minimum bus cycle, with separate
+ buses for address and data.
+
+
+Appendix D 80286/80386 Software Compatibility Considerations
+
+───────────────────────────────────────────────────────────────────────────
+
+This appendix describes the considerations required in designing an
+Operating System for the protected mode 80286 so that it will operate
+on an 80386. An 80286 Operating System running on the 80386 would not use
+any of the advanced features of the 80386 (i.e., paging or segments larger
+than 64K), but would run 80286 code faster. Use of the new 80386 features
+requires changes in the 80286Operating System.
+
+The 80386 is no different than any other software compatible processor in
+terms of requiring the same system environment to run the same software; the
+80386 must have the same amount of physical memory and I/O devices in the
+system as the 80286 system to run the same software. Note that an 80386
+system requires a different memory system to achieve the higher
+performance.
+
+The 80286 design considerations can be generally characterized as avoiding
+use of functions or memory that the 80386 will use. The exception to this
+rule is initialization code executed after power up. Such code must be
+changed to configure the 80386 system to match that of the 80286 system.
+
+The following are 80286/80386 software compatibility design considerations:
+
+ 1. Isolate the protected mode initialization code.
+
+ System initialization code will be required on the 80386 to program
+ operating parameters before executing any significant amount of 80286
+ software. The 80286 initialization software should be isolated from
+ the rest of the Operating System.
+
+ The initialization code in Appendix A is an example of isolated
+ initialization code. Such code can be extended to include programming
+ of operating parameters before executing the initial protected
+ mode task.
+
+ 2. Avoid wraparound of 80286 24-bit physical address space.
+
+ Since the 80386 has a larger physical address space, any segment
+ whose base address is greater than FF0000 and whose limit is beyond
+ FFFFFF will address the seventeenth megabyte of memory in the 80386
+ 32-bit physical address space instead of the first megabyte on an
+ 80286.
+
+ No expand-down segments shouldhave a base address in the range
+ FF00001-FFFFFF. No expand-up segments should wrap around the 80286
+ address space (the sum of their base and limit is in the range
+ 000000-00FFFE).
+
+ 3. Zero the last word of every 80286 descriptor.
+
+ The 80386 uses the last word of each descriptor to expand the base
+ address and limit fields of segments. Placing zeros in the descriptor
+ will cause the 80386 to treat the segments the same way as an 80286
+ (except for address space wraparound as mentioned above).
+
+ 4. Use only 80H or 00H for invalid descriptors.
+
+ The 80386 uses more descriptor types than the 80286. Numeric values
+ of 8-15 in bits 3-0 of the access byte for control descriptors will
+ cause a protection exception on the 80286, but may be defined for
+ other segment types on the 80386. Access byte values of 80H and 00H
+ will remain undefined descriptors on both the 80286 and the 80386.
+
+ 5. Put error interrupt handlers in reserved interrupts 14, 15, 17-31.
+
+ Some of the unused, Intel-reserved interrupts of the 80286
+ will be used by the 80386 (i.e., page fault or bus error). These
+ interrupts should not occur while executing an 80286 operating system
+ on an 80386. However, it is safest to place an interrupt handler in
+ these interrupts to print an error message and stop the system if
+ they do occur.
+
+ 6. Do not change bits 15-4 of MSW.
+
+ The 80386 uses some of the undefined bits in the machine status word.
+ 80286 software should ignore bits 15-4 of the MSW. To change the MSW
+ on an 80286, read the old value first with LMSW, change bits 3-0 only,
+ then write the new value with SMSW.
+
+ 7. Use a restricted LOCK protocol for multiprocessor systems.
+
+ The 80386 supports the 8086/80286 LOCK functions for simple
+ instructions, but not the string move instructions. Any need for
+ locked string moves can be satisfied by gaining control of a status
+ semaphore before using the string move instruction. Any attempt to
+ execute a locked string move will cause a protection exception on the
+ 80386.
+
+ The general 80286 LOCK protocol does not efficiently extend to large
+ multiprocessor systems. If all the processors in the system frequently
+ use the 8086/80286 LOCK, they will prevent other processors from
+ accessing memory and thereby impact system performance.
+
+Access to semaphores in the future, including current 80286 Operating
+Systems, should use a protocol with the following restrictions:
+
+ ■ Be sure the semaphore starts at a physical memory address that is a
+ multiple of 4.
+
+ ■ Do not use string moves to access the variable.
+
+ ■ All accesses by any instruction or I/O device (even simple reads or
+ writes) must use the LOCK prefix or system LOCK signal.
+
+
+Index
+───────────────────────────────────────────────────────────────────────────
+
+A
+───────────────────────────────────────────────────────────────────────────
+AAA
+AAD
+AAM
+AAS
+ADC
+ADD
+Addressing Modes
+ Based Indexed Mode
+ Based Indexed Mode with Displacement
+ Based Mode (on BX or BP Registers)
+ Direct Address Mode
+ Displacement
+ Immediate Operand
+ Indexed Mode (by DI or SI)
+ Opcode
+ Register Indirect Mode
+ Summary
+AF Flag, (see Flags)
+AH Register
+AL Register
+AND Instruction
+Arithmetic Instructions
+ASCII (see Data Types)
+AX Register
+
+
+B
+───────────────────────────────────────────────────────────────────────────
+Based Index Mode (see Addressing Modes)
+Based Index Mode with Displacement (see Addressing Modes)
+Based Mode (see Addressing Modes)
+BCD Arithmetic (see Data Management Instructions)
+BH Register
+BL Register
+BOUND Instruction (see Extended Instruction Set)
+Bound Range Exceeded (Interrupt 5), (see Interrupt Handling)
+BP Register
+Breakpoint Interrupt 3, (see Interrupt Handling)
+BUSY
+BX Register
+ (cont.)
+Byte (See Data Types)
+
+
+C
+───────────────────────────────────────────────────────────────────────────
+CALL Instructions
+Call Gates
+CBW Instructions
+CF (Carry Flag) (see Flags)
+CH Register
+CL Register
+CLC Instruction
+CLD Instruction
+CLI Instruction
+CLTS Instruction
+CMP Instruction
+Code Segment Access
+Comparison Instructions
+Conforming Code Segments
+Constant Instructions
+Control Transfers
+CPL (Current Privilege Level)
+CS Register
+CWD Instruction
+CX Register
+
+
+D
+───────────────────────────────────────────────────────────────────────────
+DAA
+DAS
+Data Management Instructions
+ Address Manipulation
+ Arithmetic Instructions
+ Addition Instructions
+ Division Instructions
+ Multiplication Instructions
+ Subtraction Instructions
+ BCD Arithmetic
+ Character Transfer and String Instructions
+ Repeat Prefixes
+ String Move
+ String Translate
+ Control Transfer Instructions
+ Conditional Transfer
+ Software Generated Interrupts
+ Interrupt Instructions
+ Unconditional Transfer
+ Flag Control
+ Logical Instructions
+ Shift and Rotate Instructions
+ Type Conversion Instructions
+ Processor Extension Intructions
+ Test and Compare Instructions
+ Trusted Instructions
+ Input/Output Instructions
+ Stack Manipulation
+Data Transfer Instructions
+Data Types
+ ASCII
+ BCD
+ Byte
+ Floating Point
+ Integer
+ Packed BCD
+ Pointer
+ Strings
+ Word
+DEC Instruction
+Dedicated Interrupt Vector
+Descriptor Table
+Descriptor Table Register
+DF Flag, (see Flags)
+DH Register
+DI Instruction
+Direct Address Mode (see Addressing Modes)
+Divide Error (Interrupt 0) (see Interrupt Handling)
+DIV Instruction
+DL Register
+DPL (Descriptor Privilege Level)
+DS Register
+DX Register
+
+
+E
+───────────────────────────────────────────────────────────────────────────
+EM (Bit in MSW)
+ENTER Instruction
+ES Register
+ESC (Instructions for Coprocessor)
+Extended Instruction Set (Chapter 4)
+ ENTER Build Stackframe
+ LEAVE Remove Stackframe
+ Repeated IN and OUT String Instructions
+
+
+F
+───────────────────────────────────────────────────────────────────────────
+Flag Register
+Flags see also Use of Flags with Basic
+ Instructions
+ AF (Auxilliary Carry Flag)
+ CF (Carry Flag)
+ (cont.)
+ DF (Direction Flag)
+ IF (Interrupt Flag)
+ IOPL (Privilege Level)
+ NT (Nested Task Flag)
+ OF (Overflow Flag)
+ PF (Parity Flag)
+ SF (Sign Flag)
+ TF (Trap Flag)
+ TS (Task Switch)
+ ZF (Zero Flag)
+Floating Point (see Data Types)
+
+
+G
+───────────────────────────────────────────────────────────────────────────
+Gates
+GDT
+GDTR (Global Descriptor Register)
+General Protection Fault (Interrupt 3), (see Interrupt Handling)
+General Registers
+
+
+H
+───────────────────────────────────────────────────────────────────────────
+HLT Instruction
+Hierarchy of 86, 186, 286 Instruction Sets
+ Basic Instruction Set, Chapter 3
+ Extended Instruction Set
+ Instruction Set Overview
+ System Control Register Set, Chapter 4, Chapter 5, Chapter 6, Chapter 7
+ (cont.) Chapter 8, Chapter 9, Chapter 10
+
+
+I
+───────────────────────────────────────────────────────────────────────────
+I/O
+IDIV Instruction
+IDT (Interrupt Descriptor Table)
+IDTR (Interrupt Descriptor Table Register)
+IF (Interrupt Flag), (see Flags)
+IMUL Instruction
+IN Instruction
+INC Instruction
+INDEX Field
+Indexed Mode
+Index, Pointer and Base Register
+Input/Output
+ Instructions
+ Memory Mapped I/O
+ Restrictions in Protected Mode
+ Separate I/O Space
+INS/INSB/INSW Instruction
+INT Instruction, (see Interrupt Handling)
+Integer, (see Data Types)
+Interrupt Handling
+ (cont.)
+Interrupt Priorities
+ Interrupt 0 Divide Error
+ Interrupt 1 Single-Step
+ Interrupt 2 Nonmaskable
+ Interrupt 3 Breakpoint
+ Interrupt 4 INTO Detected Overflow
+ Interrupt 5 BOUND Range Exceeded
+ Interrupt 6 Invalid Opcode
+ Interrupt 7 Processor Extension Not Available
+ Interrupt 8, Interrupt Table Limit Too Small
+ Interrupt Vectors
+ Reserved Vectors
+Interrupt Vector Table
+Interrupts and Exceptions,(see Interrupt Handling and Interrupt Priorities)
+INTO Detected Overflow (Interrupt 4), (see Interrupt Handling and Interrupt
+ Priorities)
+INTO Instruction
+INTR
+Invalid opcode (Interrupt 6), (see Interrupt Handling and Interrupt
+ Priorities)
+IOPL (I/O Privilege Level), (see Flags)
+IP Register
+IRET Instruction
+
+
+J
+───────────────────────────────────────────────────────────────────────────
+JCXZ Instruction
+JMP Instruction
+
+
+L
+───────────────────────────────────────────────────────────────────────────
+LAHF Instruction
+LAR Instruction
+LDS Instruction
+LDT (Local Descriptor Table)
+ (cont.)
+LEA Instruction
+LEAVE Instruction
+LES Instruction
+LGDT Instruction
+LIDT Instruction
+LLDT Instruction
+LMSW Instruction
+LOCK Prefix
+LODS/LODSB/LODSW
+LOOP Instruction
+LOOPE Instruction
+LOOPNE
+LOOPNZ
+LSL Instruction
+
+
+M
+───────────────────────────────────────────────────────────────────────────
+Memory,
+ Physical Size
+ Segmentation
+ Implied Usage
+ Interpretation in Protected Mode
+ Interpretation in Real Mode
+ Modularity
+ Virtual Size
+Memory Addressing Modes
+Memory Management
+ Task Managment, Chapter 8
+ Context Switching (Task Switching)
+ Overview
+Memory Management Registers, Chapter 6
+Memory Mapped I/O, (see Input/Output)
+Memory Mode
+Memory Segmentation and Segment Registers
+MOV Instructions
+MOVS Instructions
+MOVSB Instructions
+MOVSW Instruction
+MSW Register
+MUL Instruction
+
+
+N
+───────────────────────────────────────────────────────────────────────────
+NEG Instruction
+NMI (Non maskable Interrupt)
+Nonmaskable (Interrupt 2), (see Interrupt Priorities)
+NOP Instruction
+NOT Instruction
+Not Present (Interrupt 11) (see Interrupt Priorities)
+NPX Processor Extension
+NT (Nested Task Flag), (see Flags)
+Numeric Data Processor Instructions
+
+
+O
+───────────────────────────────────────────────────────────────────────────
+OF (Overflow Flag), (see Flags)
+Offset Computation
+Operands
+OR Instruction
+OUT/OUTW
+OUTS/OUTSB/OUTSW Instruction
+
+
+P
+───────────────────────────────────────────────────────────────────────────
+PF (Parity Flag), (see Flags)
+Pointer, (see Data Types)
+POP Instruction
+POPA Instruction
+POPF Instruction
+Processor Extension Error (Interrupt 6), (see Interrupt Handling and
+ Interrupt Priorities)
+Processor Extension Not Available, (Interrupt 7), (see Interrupt and
+ Interrupt Priorities)
+Processor Extension Segment Overrun Interrupt (Interrupt 9), (see Interrupt
+ and Interrupt Priorities)
+Protected Mode
+ Protected Virtual Address Mode
+Protection Implementation
+Protection Mechanisms
+PUSH
+PUSHA
+PUSHF
+
+
+R
+───────────────────────────────────────────────────────────────────────────
+Real Address Mode
+Register,
+ Base Architecture Diagram
+ Base Register BX
+ Flags Register
+ General Registers
+ Index Registers DI, SI
+ Overview
+ Pointer Registers BP and SP
+ Segment Registers
+ Status and Control
+Register Direct Mode
+Register and Immediate Modes
+Register Indirect Mode (see Addressing Modes)
+Reserved Interrupt Vectors, (see Interrupt Handling and Interrupt
+ Priorities)
+RESET
+RCL Instruction
+RCR Instruction
+REP Prefix
+REPE Prefix
+REPNE Prefix
+REPNZ Prefix
+REPZ Prefix
+RET Instructon
+ROL Instruction
+ROR Instruction
+RPL
+
+
+S
+───────────────────────────────────────────────────────────────────────────
+SAL Instruction
+SAR Instruction
+SBB Instruction
+SCAS Instruction
+SEG (Segment Override Prefix)
+Segment Address Translation Registers
+Segment Descriptor
+Segment Overrun Exception (Interrupt 13), (see Interrupt Handling and
+ Interrupt Priorities)
+Segment Selection
+SF (Sign Flag), (see Flags)
+SGDT Instruction
+SHL Instruction
+SHR Instruction
+SI Register
+SIDT Instruction
+Single Step (Interrupt 1), (see Interrupt Priorities)
+SMSW Instruction
+SP Register
+SS Register
+ (cont.)
+Status and Control Registers
+Stack Flag, (see Flags)
+Stack Fault (Interrupt 12), (see Interrupt Priorities)
+Stack Manipulation Instructions
+Stack Operations
+ Grow Down
+ Overview
+ Segment Register Usage
+ Segment Usage Override
+ Stack Frame Base Pointer BP
+ Top of Stack
+ TOS
+ with BP and SP Registers
+Status Flags
+STC Instructions
+STD Instructions
+STI Instructions
+String Instructions
+SUB Instruction
+System Address Registers
+System Initialization
+System Control Instructions
+
+
+T
+───────────────────────────────────────────────────────────────────────────
+TEST Instruction
+TF (Trap Flags), (see Flags)
+TOS (Top of Stack), (see Stack Operation)
+TR (Task Register)
+Transcendental Instruction
+TSS (Task State Segment)
+
+
+U
+───────────────────────────────────────────────────────────────────────────
+Use of Flags with Basic Instructions
+
+
+V
+───────────────────────────────────────────────────────────────────────────
+Virtual Address
+
+
+W
+───────────────────────────────────────────────────────────────────────────
+WAIT Instruction
+
+
+X
+───────────────────────────────────────────────────────────────────────────
+XCHG Instruction
+XLAT Instruction
+XOR Instruction
blob - /dev/null
blob + 9c54a27dfc894532d85310de676c1729770badc6 (mode 644)
Binary files /dev/null and doc/80c286.pdf differ