commit 095d0ed35c3587d68ee65e3d1fd5024c2d3109fc from: Benjamin Stürz date: Sat Oct 05 14:55:27 2024 UTC add doc commit - a1cd4b7fc7a060a817c404ca38994a604035281d commit + 095d0ed35c3587d68ee65e3d1fd5024c2d3109fc blob - /dev/null blob + 55f590d145a547fe0f84ffddaa4724b8c559a9ee (mode 644) --- /dev/null +++ doc/286intel-utf8.txt @@ -0,0 +1,15600 @@ +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 ║◄── + │ ╠═══════════════╣ + ║ • ║ + ≈ • ≈ + ║ • ║ + + +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 +; +; 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 +; +; 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 + 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